25.1.6 - DNS/DHCP best practice

Started by gstyle, May 08, 2025, 03:51:39 PM

Previous topic - Next topic
May 09, 2025, 10:53:01 AM #30 Last Edit: May 09, 2025, 10:57:38 AM by meyergru
With a lot of effort due to my big number of static reservations, I have now made the shift from ISC DHCP / Unbound to DNSmasq "only". Radvd is still in effect, since I use no DHCPv6. Thanks to ChatGPT for helping me to write the programs to extract the CSVs from the configuration XML for both the static reservations plus the DNS mappings and aliases.

Cudos to Cedrik: you can even import CSVs on top of another and the "last one wins" (i.e. there are no duplicates), so you can now have a static reservation with aliases, if you import them in correct order.

Just three observations for you, @Monviech:

1. It is unfortunate that the "DHCP options" are that complex to set up. Effectively, you need at least 6 lines for every (V)LAN / subnet, which soon adds up and gets confusing:

- router/gateway
- netmask
- DNS server (which, according to the config file, has a default of 0.0.0.0, thus could be left out in most cases)
- NTP server
- DNS domain
- DNS search list

Being able to use "Any" interface and thus having a kind of inheritance could reduce the numer of entries, yet make it even more confusing (who wants to inherit a netmask setting?).

This was much easier in ISC DHCP, because often-used options like these (and some more) were summarized nicely on one page per interface. Maybe tabs for each interface would be a nice addition.

2. There are some options completely missing, without the possibility to even configure them as custom options, like:

- time-server (4)
- wpad (252)
- Unifi controller (43 with a specific format for the IP)

These options should be added to the list of available DHCP options. Also, a "custom" option like in ISC DHCP would be appreciated for cases like these.

3. I used the "log-server (7)" option with a DNS name instead of an IP address, only to find that DNSmasq would fail at that. This works with ISC DHCP by the "IP address or host" type in the custom options.
Intel N100, 4 x I226-V, 16 GByte, 256 GByte NVME, ZTE F6005

1100 down / 800 up, Bufferbloat A+

Quote from: meyergru on May 09, 2025, 10:53:01 AM2. There are some options completely missing, without the possibility to even configure them as custom options, like:

- time-server (4)
- wpad (252)
- Unifi controller (43 with a specific format for the IP)

These options should be added to the list of available DHCP options. Also, a "custom" option like in ISC DHCP would be appreciated for cases like these.

So the current state is that neither Kea nor DNSmasq support vendor options at all? That comes as a bit of a shock, because I assumed that support for these might be one reason to prefer DNSmasq.

Yes, they are absolutely necessary in production. Luckily we have almost a year to go before ISC DHCP will be retired.

Meanwhile I found this presentation by ISC:
https://www.isc.org/docs/2023kea_custom_options.pdf

It's fairly recent (2023) and it does not look to be that much of a deal to implement vendor options (43) in Kea in OPNsense. But I might be missing something. I mean, yes, that's a lot of verbiage for a seemingly simple task, but nothing that cannot be easily rendered from Jinja templates.

Kind regards,
Patrick
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

May 09, 2025, 11:00:33 AM #32 Last Edit: May 09, 2025, 11:02:30 AM by Monviech (Cedrik)
1. There is an interface filter which is persistent across all tabs of dnsmasq. It also auto adds the interface to new options or ranges if selected.

2.For missing options just open an issue or a PR like this here. Its very simple to add:

https://github.com/opnsense/core/pull/8613

3. Some options might have a different syntax in dnsmasq, we did not test every option. Try to search the net for hints if others have issues with option 7 like you do.
Hardware:
DEC740

May 09, 2025, 11:43:50 AM #33 Last Edit: May 09, 2025, 11:47:56 AM by meyergru
1. I saw that and still find it confusing, sorry.

2. While I could do that to amend it to the comprehensive list at https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml plus specific custom options, there is something missing here, see next...

3. My point is that the DHCP options are effectively typed, yet in the DNSmasq version, there are no types, just a string input field. For ISC DHCP, the predefined fields in the web UI can have validations and for the custom option, you can even choose the type. For example, for the Unifi option, you need a "string" value written something like: "01:04:c0:a8:06:14". So, ideally we should either be able to select a type or the predefined options should "know" what type to use. Plus, there is no way of representing binary strings at all, AFAICT.

Also, there is no way besides code changes to even have yet missing or custom options (224-254). As Patrick noted: no feature parity.
Intel N100, 4 x I226-V, 16 GByte, 256 GByte NVME, ZTE F6005

1100 down / 800 up, Bufferbloat A+

Please open issues on github that explain what is missing for you so we can evaluate if its possible to add it.
Hardware:
DEC740

Quote from: Monviech (Cedrik) on May 09, 2025, 10:36:25 AME.g. if your network is 192.168.1.0/24 and you want to supply addresses from 192.168.1.100 on, that is your starting address for the static pool.

Thank you!

Done. I think these issues are linked closely, because an ideal solution would have:

1. A tab for any subnet with the most-used options (strongly typed and with the potential to use inputs for both IPv4 and IPv6, like the DNS search list).

2. The complete range of DHCP options from https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml and its DHCPv6 counterparts with strong types, which e.g. includes the possibility to enter binary strings.

3. A means to include vendor specific options, too. in order to come closer to feature-parity with ISC DHCP.
Intel N100, 4 x I226-V, 16 GByte, 256 GByte NVME, ZTE F6005

1100 down / 800 up, Bufferbloat A+

With the dhcp options, there might also be limitations by what dnsmasq actually offers:

-w, --help
Display all command-line options. --help dhcp will display known DHCPv4 configuration options, and --help dhcp6 will display DHCPv6 options.

Right now we read known options with a script, which populates options and options6.

https://github.com/opnsense/core/blob/master/src/opnsense/scripts/dns/dnsmasq_dhcp_options.py

Effectively it does this:

dnsmasq --help dhcp
dnsmasq --help dhcp6

And it will return a list of all supported options.
Hardware:
DEC740

A few words from me on the topic of DHCP. My introduction to OPNsense was ISC DHCP, which I've had very positive experiences with.

Today, however, I tried DNSmasq and was able to set up the appropriate domains, DHCP ranges, and DHCP options for my subnets following the OPNsense tutorial. A positive point is that the wired and wireless network devices (in different subnets) take too long for the DHCP process, whereas with ISC everything runs super quickly and smoothly.

I noticed, especially with my smartphone, that WiFi calling doesn't work with DNSmasq DHCP, but it does work with KEA and ISC DHCP. In general, I noticed that configuring DNSmasq is much more complex than with ISC und KEA and I have to agree with meyergru on that point.

Therefore, I seriously wonder whether ISC DHCP will continue to be usable despite its EOL status, albeit in the form of optional plugins? I also have the question of why HA will be mandatory for KEA DHCP in the future, or have I misunderstood something? Franco said that KEA DHCP is intended for medium to large companies, but why not simply leave HA optional so that regular users can also use KEA DHCP if they want?

In summary, the following question for @Franco:

1. Will ISC DHCP continue to be usable (via optional plugins) despite its EOL status?
2. Will KEA DHCP be usable for regular users even without HA?
3. DNSmasq is already active by default after a fresh installation of OPNsense. Will it be improved (and simplified) in the future?

May 09, 2025, 05:19:56 PM #39 Last Edit: May 09, 2025, 05:42:46 PM by meyergru
I did not look at DNSmasq manual pages until now. The relevant part about and typing is this:

QuoteAn option without data is valid, and includes just the option without data. (There is only one option with a zero length data field currently defined for DHCPv4, 80:rapid commit, so this feature is not very useful in practice). Options for which dnsmasq normally provides default values can be ommitted by defining the option with no data. These are netmask, broadcast, router, DNS server, domainname and hostname. Thus, for DHCPv4 -- dhcp-option = option:router will result in no router option being sent, rather than the default of the host on which dnsmasq is running. For DHCPv6, the same is true of the options DNS server and refresh time.

Data types allowed are comma separated dotted-quad IPv4 addresses, []-wrapped IPv6 addresses, a decimal number, colon-separated hex digits and a text string. If the optional tags are given then this option is only sent when all the tags are matched.

Special processing is done on a text argument for option 119, to conform with RFC 3397. Text or dotted-quad IP addresses as arguments to option 120 are handled as per RFC 3361. Dotted-quad IP addresses which are followed by a slash and then a netmask size are encoded as described in RFC 3442.

IPv6 options are specified using the option6: keyword, followed by the option number or option name. The IPv6 option name space is disjoint from the IPv4 option name space. IPv6 addresses in options must be bracketed with square brackets, eg. --dhcp-option=option6:ntp-server,[1234::56]. For IPv6, [::] means "the global address of the machine running dnsmasq", whilst [fd00::] is replaced with the ULA, if it exists, and [fe80::] with the link-local address.

Be careful: data-type suitability for the option number sent is not checked. It is quite possible to persuade dnsmasq to generate illegal DHCP packets with injudicious use of this flag. When the value is a decimal number, dnsmasq must determine how large the data item is. It does this by examining the option number and/or the value, but can be overridden by appending a single letter flag as follows: b = one byte, s = two bytes, i = four bytes. This is mainly useful with encapsulated vendor class options (see below) where dnsmasq cannot determine data size from the option number. Option data which consists solely of periods and digits will be interpreted by dnsmasq as an IP address, and inserted into an option as such. To force a literal string, use quotes. For instance when using option 66 to send a literal IP address as TFTP server name, it is necessary to do --dhcp-option=66,"1.2.3.4".

Encapsulated Vendor-class options may also be specified (IPv4 only) using --dhcp-option: for instance --dhcp-option=vendor:PXEClient,1,0.0.0.0 sends the encapsulated vendor class-specific option "mftp-address=0.0.0.0" to any client whose vendor-class matches "PXEClient". The vendor-class matching is substring based (see --dhcp-vendorclass for details). If a vendor-class option (number 60) is sent by dnsmasq, then that is used for selecting encapsulated options in preference to any sent by the client. It is possible to omit the vendorclass completely; --dhcp-option=vendor:,1,0.0.0.0 in which case the encapsulated option is always sent.

Options may be encapsulated (IPv4 only) within other options: for instance --dhcp-option=encap:175, 190, iscsi-client0 will send option 175, within which is the option 190. If multiple options are given which are encapsulated with the same option number then they will be correctly combined into one encapsulated option. encap: and vendor: may not both be set in the same --dhcp-option.

The final variant on encapsulated options is "Vendor-Identifying Vendor Options" as specified by RFC3925. These are denoted like this: --dhcp-option=vi-encap:2, 10, text The number in the vi-encap: section is the IANA enterprise number used to identify this option. This form of encapsulation is supported in IPv6.

The address 0.0.0.0 is not treated specially in encapsulated options.

So first, you can set any option by number or by name - while it is true that there is an (incomplete) list of named options, you actually set these via numbers only, like with the dns-search-list (119):

...
dhcp-option-force=tag:igc0_vlan1,119,lan;iot;dmz;guest
...

So, obviously, as a bare minimum, any vendor-specific option could as well be specified numerically, because DNSmasq itself admittedly does know jack about the types of the parameters. I bet you can use (in fact I included that in /usr/local/etc/dnsmasq.conf.d/unifi.conf and verified it to work as expected):

dhcp-option-force=tag:igc0_vlan1,43,01:04:c0:a8:06:14

As for the missing "known" options, you could prepend the program output with missing ones in textual form, like in the dnsmasq output:

  4 time-server
 43 unifi-server
252 wpad-url

Matter-of-fact, the names are only used in the GUI and not carried over to the actual config.

In order to help the user with a correct type and validation, you would need a third column describing what can/should be used, like:

  1 netmask          netmask
  2 time-offet       number
  3 router           ip-addr
  4 time-server      ip-addr
  6 dns-server       ip-addr-list
...
 43 unifi-server     binary-string
...
252 wpad-url         url
...

In order to support custom options, you could then just offer a table input with three columns "option-number", "option-name" and a "option-type" dropdown, which would be added to this to augment the web UI. You could also allow duplicates, e.g. option 43 is "vendor specific", so there might be other variants like " 43 vendor-xy ip-addr-list" on top of my unifi example. The option-name would be the selector for the validation, then.
Intel N100, 4 x I226-V, 16 GByte, 256 GByte NVME, ZTE F6005

1100 down / 800 up, Bufferbloat A+

Appending missing options to the output should be doable as we already do that with the captive server option.

Small tickets on github with clear scope can be worked on more efficiently.
Hardware:
DEC740

May 09, 2025, 07:25:03 PM #41 Last Edit: May 09, 2025, 08:42:24 PM by dMopp
I have problems getting ipv6 working with dnsmasq. RA is active and pool settings are set, but i don't get dnsv6 nor even a ipv6 address on my iPhone. I plan to use dhcpv6 + slaac :/

Edit: got that working by disable the general RA setting...

But now a new issue: how do i get reverse lookups working with dnsmasq?

May 09, 2025, 09:31:49 PM #42 Last Edit: May 10, 2025, 12:14:56 AM by Unspec
Quote from: Monviech (Cedrik) on May 09, 2025, 09:06:55 AMYou should try to find out where your dns queries get stuck.

I think Unbound does not cache queries it forwards to other DNS servers, and Dnsmasq should not need to cache its own DNS entries because they are static.

I'm just a bit surprised because I run dnsmasq fully features like in the docs since 2 months now and did not experience anything strange. Though I also do not query local services quite as much as you might do. So saying its broken is kinda not true.

Maybe our setups are quite different.

I believe it's unbound because when running a nslookup on my windows machine to a host that is in unbound's overrides, it times out twice before finally succeeding, suggesting unbound is choking on...something because it's a local lookup to unbound.

Edit: Once the query forwarding is turned off, it's able to resolve things better but obviously only for things in unbound's overrides. That said, I will be unable to test this further as I've fully abandoned dnsmasq and do not intend on returning to it in the near future, it's far too experimental for my tastes and makes my internal network communications extremely flakey.

Quote from: dMopp on May 09, 2025, 07:25:03 PMI have problems getting ipv6 working with dnsmasq. RA is active and pool settings are set, but i don't get dnsv6 nor even a ipv6 address on my iPhone. I plan to use dhcpv6 + slaac :/

Edit: got that working by disable the general RA setting...

But now a new issue: how do i get reverse lookups working with dnsmasq?

Double check to make sure you're not also running radvd (Services -> Router Advertisements) when trying to run dnsmasq's RA implementation.

Quote from: Monviech (Cedrik) on May 09, 2025, 05:42:28 PMAppending missing options to the output should be doable as we already do that with the captive server option.

Small tickets on github with clear scope can be worked on more efficiently.

I know. I created a pull request to fix two problems: https://github.com/opnsense/core/pull/8626

If someone wants to try it, you can change /usr/local/opnsense/scripts/dns/dnsmasq_dhcp_options.py and then call "service configd restart" to populate the new DHCP options.
Intel N100, 4 x I226-V, 16 GByte, 256 GByte NVME, ZTE F6005

1100 down / 800 up, Bufferbloat A+

Quote from: PhoenixRider on May 09, 2025, 04:36:58 PMIn summary, the following question for @Franco:

1. Will ISC DHCP continue to be usable (via optional plugins) despite its EOL status?
2. Will KEA DHCP be usable for regular users even without HA?
3. DNSmasq is already active by default after a fresh installation of OPNsense. Will it be improved (and simplified) in the future?

While I believe the answers to 1 and 2 are yes and yes, I will wait for Franco to confirm.

Regarding the third, I have a supplementary question. Will the documentation contain concise instructions for turning DNSmasq off in a new installation, eradicating its presence, so new installations are more easily switched to Kea? I did not see that there during a quick look.
Deciso DEC697
+crowdsec +wireguard