I want to extend the discussion from the original RFC, ‘Supporting IPv6 in Provisioning, Registration & KEA [0],’ focusing in this post only on the design and implementation of an IPv6 provider for Smart Proxy.
This will address a critical gap in the current providers’ lack of support for IPv6 [1]. This addition ensures that Smart Proxy can fully handle the modern networking needs of dual-stack and IPv6-only environments.
Our current aim is for KEA [2] to be the DHCP tool, not managed by us but as an external service. This will benefit users who don’t want to manage the DHCP and will require less code to maintain on Foreman’s side.
However, there are some implementation questions and challenges we need to figure out. For example:
Supported IPv6 modes: stateless, stateful, or both?
IPv6 vs IPv4: Configuration on OS level or APP level?
Provisioning: As @ekohl mentioned [2], the current implementation for provisioning with IPv6 won’t work.
Do we need IP for host creation? With unmanaged DHCP, we may not need IP to create a host.
In the Smart Proxy we can write modules with multiple providers. I’d strongly recommend writing 2 providers at once to verify the API isn’t just implementing one backend. I think Infoblox supports IPv6 as well in their REST API.
This will depend on what you want to achieve. Today’s Smart Proxy DHCP module isn’t capable of managing subnets and requires the server to be set up. If you want to implement this (and I can see benefits) then stateless can make sense.
On the other hand, if you essentially take the current module and make it IPv6 compatible then I don’t see a benefit. Today we explicitly manage hosts but with stateless there explicitly aren’t managed hosts from the server side.
Speaking of standards: I know there’s the DNS camel that has an overview of all the relevant RFC for DNS, but I’m not aware of an equivalent for IPv6.
I’m not sure I completely understand what you mean by this.
This is something we should investigate before we start implementing something. I would like to support a system where we don’t care about the exact IP, but there are some things to consider. For example, we now create the DNS entries before the host boots up. For that you need to know the IP(s). Of course, you can get a reservation from IPAM and as long as the DHCP server talks to IPAM that’ll be OK.
Still, I think this is the most crucial thing to figure out before we starting writing code.
That’s our plan: support IPv4 and IPv6 for Kea from the start. But I’m unsure if the current code in smart-proxy allows us to have a DHCP provider that can do both.
The problem is that we don’t know. We have no idea what users have in their infrastructure; we got zero feedback about this topic. From what I understood, the stateless mode is more suitable for personal networks or places where you don’t care about managing the IPs. Still, the business would probably be more interested in the stateful mode.
[quote]
If we will have Satellite and the whole infrastructure on dual-stack, do we want to have some configuration that allows users to set their preferred network type? For example, do we prefer IPv6 over IPv4 or vice versa? We have something similar for REX in the settings. Or we’ll leave it to OS to decide which IP network to use.
Very quick introduction in the Smart Proxy, modules and providers.
The Smart Proxy has a core that’s essentially the webserver (webrick) configuration and a plugin loader framework. It loads modules that all add some API. Even the top level API is implemented as a module (root).
A module is declared as a subclass of Proxy::Plugin and that has a small DSL to do configuration. I won’t go into detail, but in the end they’re all rack applications.
Then plugins can declare they use a provider, like the DHCP module does:
I’ll skip over all the details (this is phase 2 in the plan), but then through dependency injection a provider instance is injected into the API:
Now you may notice that all the actual API handlers call server.something. I think the DHCP examples are a lot more complex but in the end it’s just an interface that’s implemented by some class (like Proxy::DHCP::Infoblox::Provider).
A user will then configure the implementation in their dhcp.yml config file:
In practice the installer does this for them when they use --foreman-proxy-dhcp-provider.
For end users I’ve made a start to gather documenting this properly in a single place, but right now it’s all over the place (chapter 3.7, chapter 4.2, chapter 5 and chapter 7 in 1 guide). My goal is to expand chapter 5 to what’s been done for DNS in chapter 6 and centralize all of them.
I’d recommend reading the RFC4862 introduction because IMHO it’s very clear, though you must know the concept of link-local addresses. These are the fe80:: addresses you see on an interface. A lot of communication happens on this and a concept that’s rarely used in IPv4 (you may have seen the 169.254.0.0/16 range). Even without a router hosts can talk to each other and you’ll often see that the router also only advertises their link local address.
This is all based on the Neighbor Discovery Protocol (RFC4861). If you look at the Router Advertisement Message Format you can see it’s really limited what can actually be sent. Very interesting to note here is that it can tell you that DHCPv6 is available for more options.
Much later it was extended to inform about DNS servers via RFC8106. Prior to that you needed DHCPv6 or other means (static configuration or DHCPv4, both undesirable).
Relevant for provisioning: note that you can’t send fields that you’re used to in DHCPv4. No TFTP server, no HTTPBoot. These do exist in DHCPv6 (RFC3315), though they’re not explicitly mentioned. Both DHCPv4 and DHCPv6 have an extensible option scheme.
Long story short: for provisioning I think stateful management is mandatory. The question is: do we need to manage it (via some API) or will it be sufficient if we can come up with instructions that allows all hosts to be configured in the same way?
I’m in favor of using the OS as much as possible. Prefer DNS when you can and let the OS figure out what’s preferred. Obviously when IPs are provided then there’s only one way. Though we can implement happy eyeballs, I’m not too keen on doing so. Foreman is deployed in controlled environments and IMHO we should prefer users fix their network rather than working around it. Happy eyeballs is intended for environments you can’t easily fix (like on the internet).
I asked for permission to share details of our internal network.
We have a dual stack network divided into multiple IPv4 subnets for different purposes like an Admin, Office or Guest LAN and all of them have a corresponding IPv6 prefix. These subnets and prefixes are managed in NetBox. IPv6 is configured as Stateless RA with assisted DHCP. So nearly all networks provide DHCPv4 and DHCPv6 announcing DNS (handled by PowerDNS providing also DoT/DoH), NTP, Active Directory Domain related stuff and were appropriate there is a PXE based on https://netboot.xyz/ providing kpxe and efi based on the client asking, but this service is currently IPV4 only. In addition for provisioning our training setup one network has a PXE environment managed by Foreman (currently IPv4 only using still ISC DHCP).
All this is internal, most things regarding routing to the outside world is done by our datacenter provider(s) as we are just using space in managed datacenters.
If more details are interesting for you, please ask and I will try to get an answer by my colleagues!