Bug #13393
closedDNS Resolver responds with unexpected source address when the DNS over TLS server function is enabled
100%
Description
When unbound responds to DNS queries, it will by default respond with a source address that is closest to the request source. The query then fails since the requestor did not expect the answer to come from a different address. For example:
dig +short @192.168.223.1 host.domain.tld 192.168.224.20 dig +short @192.168.224.1 host.domain.tld ;; reply from unexpected source: 192.168.223.1#53, expected 192.168.224.1#53
Updated by Jim Pingle over 2 years ago
- Status changed from New to Not a Bug
- Plus Target Version deleted (
22.11)
That's a limitation of Unbound when binding to specific interfaces/addresses or when acting as a DNS over TLS server.
We do this when binding to all and DoT is off:
interface-automatic: <yes or no> Listen on all addresses on all (current and future) interfaces, detect the source interface on UDP queries and copy them to replies. This is a lot like ip-transparent, but this option services all interfaces whilst with ip-transparent you can se- lect which (future) interfaces Unbound provides service on. This feature is experimental, and needs support in your OS for particular socket options. Default value is no.
It's not compatible with other configurations.
Updated by Marcos M over 2 years ago
The issue is when it's bound to all. When it's bound to specific interfaces, it's not an issue.
https://gitlab.netgate.com/pfSense/pfSense/-/merge_requests/840
Updated by Jim Pingle over 2 years ago
It's already set in the config where it can be:
https://github.com/pfsense/pfsense/blob/master/src/etc/inc/unbound.inc#L265
Updated by Marcos M over 2 years ago
Indeed it was the DoT option - what's the reason for interface-automatic
being dependent on DoT being disabled? When using DoT and adding the option manually, queries work as expected (whereas otherwise they do not).
Updated by Jim Pingle over 2 years ago
Marcos M wrote in #note-4:
Indeed it was the DoT option - what's the reason for
interface-automatic
being dependent on DoT being disabled? When using DoT and adding the option manually, queries work as expected (whereas otherwise they do not).
It's possible that Unbound fixed it, but ~4 years ago when the DoT service options were added to the GUI (#8030), enabling interface-automatic
broke TCP.
With more thorough testing it may be OK to remove that condition, but we'd have to ensure that it doesn't cause other failures. For example if UDP queries work but larger TCP queries fail, that's probably a side effect of this combination of options.
Clients should really be querying the local address for DNS and not addresses on other interfaces anyhow. And if they do insist on doing so, using the usual DNS redirect port forwards can also work around that.
Updated by Jim Pingle over 2 years ago
- Subject changed from DNS Resolver responds with unexpected source address to DNS Resolver responds with unexpected source address when the DNS over TLS server function is enabled
- Status changed from Not a Bug to In Progress
- Target version set to 2.7.0
- Plus Target Version set to 22.11
I thought I reopened this but apparently not. Based on my last comment, this needs some more testing and confirmation that the behavior has been fixed in Unbound. If it has, then we can remove the condition that prevents using DoT and interface-automatic
at the same time.
Updated by Marcos M over 2 years ago
The changelog here indicates it's been fixed:
https://nlnetlabs.nl/projects/unbound/download/
Fix
#618
: enabling interface-automatic disables DNS-over-TLS. Adds the option to list interface-automatic-ports.
Currently on 22.05 with DoT enabled, this happens:
dig +tcp google.net @10.0.50.1 ;; communications error to 10.0.50.1#53: end of file ;; communications error to 10.0.50.1#53: end of file
This no longer happens on 22.11. It seems to have been solved by:
Fix that TCP interface does not use TLS when TLS is also configured
There is a new issue on 22.11. interface-automatic
is now needed even when specific interfaces are selected in Network Interfaces
in order to query interface addresses outside of the client's subnet.
Updated by Marcos M over 2 years ago
- Status changed from In Progress to Pull Request Review
Updated by Marcos M about 2 years ago
- Status changed from Pull Request Review to Feedback
- % Done changed from 0 to 100
Applied in changeset 910a468672a6dcfe9f3567ffcb25e0fd94e74073.
Updated by Jim Pingle about 2 years ago
- Plus Target Version changed from 22.11 to 23.01
Updated by Chris Linstruth about 2 years ago
When I select LAN+Localhost in Network Interfaces I get this:
unbound unbound 74675 7 udp4 *:53 *:* unbound unbound 74675 8 tcp4 *:53 *:*
# Interface IP(s) to bind to interface-automatic: yes interface: 172.25.236.2 interface: 2001:470:e01a:7e01::2 interface: 127.0.0.1 interface: ::1
I figure that might be a by-product of multiple binds, just like listening to IPv4 and IPv6 with OpenVPN.
Further testing shows it listens on *:53 even if only one interface is selected.
Updated by Marcos M about 2 years ago
- Status changed from Feedback to Ready To Test
- If
Network Interfaces
is set to all, unbound will respond from the wrong address unlessinterface-automatic: yes
is set. - If
Network Interfaces
is set to specific interfaces, unbound will respond from the correct address regardless ofinterface-automatic
(tested set/unset and yes/no). - If
interface-automatic: yes
is set, unbound will listen on all (e.g.*:53
) regardless of theinterface
(akaNetwork Interfaces
) option.
The following patch addresses this behavior and always respects the Network Interfaces
option:
diff --git a/src/etc/inc/unbound.inc b/src/etc/inc/unbound.inc index 2da497cd12..bbaa7aa332 100644 --- a/src/etc/inc/unbound.inc +++ b/src/etc/inc/unbound.inc @@ -257,15 +257,14 @@ EOF; // Determine interfaces where unbound will bind $port = (is_port($unboundcfg['port'])) ? $unboundcfg['port'] : "53"; $tlsport = is_port($unboundcfg['tlsport']) ? $unboundcfg['tlsport'] : "853"; - $bindintcfg = "interface-automatic: yes" . PHP_EOL; - if (isset($unboundcfg['enablessl'])) { - $bindintcfg .= sprintf('interface-automatic-ports: "%1$s %2$s"%3$s', $port, $tlsport, PHP_EOL); - } + $bindintcfg = ""; $bindints = array(); $active_interfaces = explode(",", $unboundcfg['active_interface']); if (empty($unboundcfg['active_interface']) || in_array("all", $active_interfaces, true)) { - $bindints[] = "0.0.0.0"; - $bindints[] = "::0"; + $bindintcfg = "interface-automatic: yes" . PHP_EOL; + if (isset($unboundcfg['enablessl'])) { + $bindintcfg .= sprintf('interface-automatic-ports: "%1$s %2$s"%3$s', $port, $tlsport, PHP_EOL); + } } else { foreach ($active_interfaces as $ubif) { /* Do not bind to disabled/nocarrier interfaces, @@ -533,7 +532,7 @@ aggressive-nsec: {$aggressivensec} {$statistics} # TLS Configuration {$tlsconfig} -# Interface IP(s) to bind to +# Interface IP addresses to bind to {$bindintcfg} {$outgoingints} # DNS Rebinding
Updated by Marcos M about 2 years ago
- Status changed from Ready To Test to Pull Request Review
Updated by Marcos M about 2 years ago
- Status changed from Pull Request Review to Feedback
Applied in changeset c77e381e5c408172cb20a565a3fdfd998fc983d1.