[SOLVED] No DNS on Guest Network when preventing DNS leaks

Thanks, both. That's all clear. I've now got the following, and it seems to work; no more DNS leaks from the lan-zone clients!

/etc/config/dhcp
config dnsmasq
	option domainneeded '1'
	option localise_queries '1'
	option rebind_protection '1'
	option rebind_localhost '1'
	option local '/lan/'
	option domain 'lan'
	option expandhosts '1'
	option authoritative '1'
	option readethers '1'
	option leasefile '/tmp/dhcp.leases'
	option nonwildcard '1'
	option localservice '1'
	option serversfile '/tmp/adb_list.overall'
	option noresolv '1'
	list server '10.64.0.1'

config dhcp 'lan'
	option interface 'lan'
	option leasetime '12h'
	option dhcpv6 'server'
	option ra 'server'
	option ra_management '1'
	option start '100'
	option limit '150'
	list dhcp_option '6,10.64.0.1'

config dhcp 'wan'
	option interface 'wan'
	option ignore '1'

config odhcpd 'odhcpd'
	option maindhcp '0'
	option leasefile '/tmp/hosts/odhcpd'
	option leasetrigger '/usr/sbin/odhcpd-update'
	option loglevel '4'

config dhcp 'Guest'
	option start '100'
	option limit '150'
	option interface 'Guest'
	option leasetime '1h'
	list dhcp_option '6,84.200.69.80,84.200.70.40'

My next hurdle is going to be stubby. If I set:

list server '127.0.0.1#5453'

then my lan-zone clients will use that, even if I have list dhcp_option '6,10.64.0.1' set.

can I, instead, set list dhcp_option '6,127.0.0.1:5453' on the guest-zone?

noresolv is not defined in the config, so it becomes 0.

resolvfile is not defined in the config, so it becomes /tmp/resolv.conf.auto.

Removing these options from the config changes nothing, because their default values are defined in the dnsmasq init-script.

No, you can't use ports numbers in the DHCP-option-6.

OK, thanks. So, either I stick with the setup I have now (which works), or I employ stubby and have to accept the DNS leaks from the lan-zone clients?

LAN hosts use directly 10.64.0.1 that is advertised from the DHCP server.
Why would there be a leak to a different resolver?
Or do you mean that they use the IPv6 NS?

That's how Dnsmasq works:

I understand that, but LAN hosts have a NS from VPN to query directly. Dnsmasq should not be involved in this, unless queried from the IPv6.

1 Like

Yep, option dhcp_option applies to Dnsmasq only and overrides DHCP-option-6 for DHCPv4.
So, @tectonic should also use option dns which applies to odhcpd and overrides DHCP-option-6 for DHCPv6.
In this case it may be worth replacing Dnsmasq with odhcpd for both DHCPv4 and DHCPv6.

Note that pushing 3-rd party DNS-servers via DHCP-option-6 will effectively disable Adblock.
If you need Adblock, then you should use another method.

2 Likes

Sorry for the slow reply.

Thanks very much, @vgaetera and @trendy for your assistance. I think I'm beginning to make sense of this. From what you've said, do I understand correctly that my DNS leaks are as a result of resolvfile which defaults to /tmp/resolv.conf.auto when not specified explicitly, and that this gets created by the WAN DHCP client.

So, setting 'Ignore Resolve File' and specifying list dhcp_option '6,84.200.69.80,84.200.70.40' for guest-zone clients fixes the leak.

However, if I'm to use Stubby for DNS over TLS, then I have to accept leaks to (e.g.) Cloudflare for lan-zone clients. The only way to get around this is to have multiple dnsmasq instances whereby the guest-zone could use Stubby, but the lan-zone could use 10.64.0.1 (and ignore resolv.conf.auto).

I'll get the first version working (i.e. without Stubby) and then have a go at the separate dnsmasq instance...

If you want to use Adblock or DoT via Stubby, you should not push 3-rd party DNS-servers via DHCP-option-6.

Exactly.

1 Like

I think, think it's working. I see no DNS leaks on lan-zone clients, but guest-zone clients are using DoT and DNSSEC. Adblock is working in both zones.

/etc/config/network
config interface 'loopback'
	option ifname 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config globals 'globals'
	option ula_prefix 'fd2c:dd09:d634::/48'

config interface 'lan'
	option type 'bridge'
	option ifname 'eth1.1'
	option proto 'static'
	option ipaddr '192.168.100.1'
	option ip6assign '60'
	option netmask '255.255.255.0'

config interface 'wan'
	option ifname 'eth0.2'
	option proto 'pppoe'
	option username '...'
	option password '...'
	option ipv6 'auto'
	option peerdns '0'
	option dns '127.0.0.1 84.200.69.80 84.200.70.40'

config interface 'wan6'
	option ifname 'eth0.2'
	option proto 'dhcpv6'
	option reqaddress 'try'
	option reqprefix 'auto'
	option peerdns '0'
	option dns '0::1 2001:1608:10:25::1c04:b12f 2001:1608:10:25::9249:d69b'

config switch
	option name 'switch0'
	option reset '1'
	option enable_vlan '1'

config switch_vlan
	option device 'switch0'
	option vlan '1'
	option ports '1 2 3 4 6t'

config switch_vlan
	option device 'switch0'
	option vlan '2'
	option ports '5 0t'

config interface 'streaming'
	option proto 'static'
	option ipaddr '192.168.3.1'
	option netmask '255.255.255.0'
	option type 'bridge'

config interface 'guest'
	option proto 'static'
	option netmask '255.255.255.0'
	option ipaddr '10.0.0.1'
	option type 'bridge'

config interface 'mullvad'
	option proto 'wireguard'
	option private_key '...'
	option force_link '1'
	list addresses '10.99.57.166/32'

config wireguard_mullvad
	list allowed_ips '0.0.0.0/0'
	option persistent_keepalive '25'
	option public_key '...'
	option description 'mv'
	option endpoint_host '...'

config interface 'MODEM'
	option proto 'static'
	option ifname 'eth0.2'
	option ipaddr '192.168.2.2'
	option netmask '255.255.255.0'
/etc/config/firewall
config defaults
	option syn_flood '1'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'REJECT'

config zone
	option name 'lan'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	option network 'streaming lan'

config zone
	option name 'wan'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	option network 'mullvad wan wan6 MODEM'

config rule
	option name 'Allow-DHCP-Renew'
	option src 'wan'
	option proto 'udp'
	option dest_port '68'
	option target 'ACCEPT'
	option family 'ipv4'

config rule
	option name 'Allow-Ping'
	option src 'wan'
	option proto 'icmp'
	option icmp_type 'echo-request'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-IGMP'
	option src 'wan'
	option proto 'igmp'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-DHCPv6'
	option src 'wan'
	option proto 'udp'
	option src_ip 'fc00::/6'
	option dest_ip 'fc00::/6'
	option dest_port '546'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-MLD'
	option src 'wan'
	option proto 'icmp'
	option src_ip 'fe80::/10'
	list icmp_type '130/0'
	list icmp_type '131/0'
	list icmp_type '132/0'
	list icmp_type '143/0'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Input'
	option src 'wan'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	list icmp_type 'router-solicitation'
	list icmp_type 'neighbour-solicitation'
	list icmp_type 'router-advertisement'
	list icmp_type 'neighbour-advertisement'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Forward'
	option src 'wan'
	option dest '*'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-IPSec-ESP'
	option src 'wan'
	option dest 'lan'
	option proto 'esp'
	option target 'ACCEPT'

config rule
	option name 'Allow-ISAKMP'
	option src 'wan'
	option dest 'lan'
	option dest_port '500'
	option proto 'udp'
	option target 'ACCEPT'

config include
	option path '/etc/firewall.user'

config zone
	option forward 'REJECT'
	option output 'ACCEPT'
	option name 'guest'
	option input 'REJECT'
	option network 'guest'

config rule
	option target 'ACCEPT'
	option proto 'udp'
	option dest_port '67-68'
	option name 'guest_dhcp'
	option src 'guest'

config rule
	option target 'ACCEPT'
	option proto 'tcp udp'
	option dest_port '53'
	option name 'guest_dns'
	option src 'guest'

config forwarding
	option dest 'wan'
	option src 'guest'

config forwarding
	option dest 'wan'
	option src 'lan'

config rule
	option src 'guest'
	option name 'Disable Modem Access'
	option dest 'wan'
	option dest_ip '192.168.2.1'
	option target 'DROP'

config redirect 'adblock_dns_53'
	option name 'Adblock DNS'
	option src 'lan'
	option proto 'tcp udp'
	option src_dport '53'
	option dest_port '53'
	option target 'DNAT'

config redirect 'adblock_dns_guest_53'
	option proto 'tcp udp'
	option target 'DNAT'
	option name 'Adblock DNS Guest'
	option src 'guest'
	option src_dport '53'
	option dest_port '53'
/etc/config/dhcp
`config dnsmasq 'main'
	option domainneeded '1'
	option localise_queries '1'
	option rebind_protection '1'
	option rebind_localhost '1'
	option local '/lan/'
	option domain 'lan'
	option expandhosts '1'
	option authoritative '1'
	option readethers '1'
	option leasefile '/tmp/dhcp.leases'
	option nonwildcard '1'
	option localservice '1'
	option serversfile '/tmp/adb_list.overall'
	option noresolv '1'
	list server '193.138.218.74'
	list server '10.64.0.1'
	list notinterface 'guest'
	
config dnsmasq 'guest'
	option domainneeded '1'
	option localise_queries '1'
	option rebind_protection '1'
	option rebind_localhost '1'
	option local '/guest/'
	option domain 'guest'
	option expandhosts '1'
	option authoritative '1'
	option readethers '1'
	option leasefile '/tmp/dhcp.leases.guest'
	option nonwildcard '1'
	option localservice '1'
	option serversfile '/tmp/adb_list.overall'
	option noresolv '1'
	list server '127.0.0.1#5453'
	list interface 'guest'
	list notinterface 'lo'
	option dnssec '1'
	option dnsseccheckunsigned '1'

config dhcp 'lan'
	option instance 'main'
	option interface 'lan'
	option leasetime '12h'
	option dhcpv6 'server'
	option ra 'server'
	option ra_management '1'
	option start '100'
	option limit '150'

config dhcp 'wan'
	option interface 'wan'
	option ignore '1'

config odhcpd 'odhcpd'
	option maindhcp '0'
	option leasefile '/tmp/hosts/odhcpd'
	option leasetrigger '/usr/sbin/odhcpd-update'
	option loglevel '4'

config dhcp 'streaming'
	option instance 'main'
	option interface 'streaming'
	option leasetime '12h'
	option start '100'
	option limit '150'

config dhcp 'guests'
	option instance 'guest'
	option interface 'guest'
	option start '100'
	option limit '150'
	option leasetime '1h'

Critical review appreciated: if there's anything that jumps out as 'not right', or there is scope to improve/refine, I'd gladly welcome your feedback. Otherwise, I'll mark this as 'solved'.

Possible future extension: add a 'kidsafe' network with safe-search and filtering (e.g. with OpenDNS Family Shield and the safe-search package. Note to self: list addnhosts '/etc/safe-search/enabled')

2 Likes

something's not right.

Wired clients are seeing dns failures. For example, my HDHomerun Connect logs show "webclient error (dns failed)". Similarly, my Philips Hue Bridge (also wired) cannot connect to meethue. Curiously, whilst the Hue Bridge has an IP address of 192.168.1.119, https://www.meethue.com/api/nupnp reports an IP address of 10.10.10.249.

Somehow, the multiple dnsmasq instances has messed things up. I suspect list interface and list nointerface settings are incorrect, but I can't determine what it might be.

Any suggestions or troubleshooting steps?

Without destination it works as a REDIRECT target forcing the traffic to the loopback interface:
http://ipset.netfilter.org/iptables-extensions.man.html#lbDM

But you need different destinations:

uci set firewall.adblock_dns_53.dest_ip="$(uci get network.lan.ipaddr)"
uci set firewall.adblock_dns_guest_53.dest_ip="$(uci get network.guest.ipaddr)"
uci commit firewall
service firewall restart

Test name resolution from client PC:

nslookup example.org

Verify iptables rules.
Check that PIDs on interfaces match runtime configurations for those interfaces.

iptables-save -t nat
netstat -l -n -p | grep -e dnsmasq
pgrep -f -a dnsmasq

My testing shows that dynamic interface-binding for DNS works.
But I did not validate interface-based DHCP options.

I'm not sure it supports multiple instances or interface-based configurations.
I suggest to disable DHCPv6, at least until you fix DHCPv4+DNS4.

1 Like

Thanks, that's been applied and seems to have sorted my HDHomerun Connect; logs there are clean now.

The Philips Hue is also connecting to the Philips cloud service, but in order to resolve it, I had to remove option noresolv '1' from config dnsmasq 'main'. This means that devices are using the list of resolvers in resolv.conf.auto. I'm back to 'square one' with the DNS leaks. Here's what I'm seeing:

If I set option noresolv '0', then the Philips Hue loses connection to the Philips cloud service, and nslookup openwrt.org shows:

;; Truncated, retrying in TCP mode.
Server:   192.168.100.1
Address: 192.168.100.1#53

Non-authoritative answer:
Name:  openwrt.og
Address: 139.59.209.225

If I set set option noresolv '', then the Philips Hue connects fine to the Philips cloud service, and nslookup openwrt.org` shows:

Server:   192.168.100.1
Address: 192.168.100.1#53

Non-authoritative answer:
Name:  openwrt.og
Address: 139.59.209.225

So, it seems that the Hue Bridge uses UDP exclusively, and, for whatever reason, using my VPN provider's public resolver (193.138.218.74) doesn't accept UDP connections.

Is there a way by which I can enforce the order such that 193.138.218.74 is always preferred, but, if that fails, a second resolver is queried?

Nope; UDP is fine:

nc -v -u -z -w 3 193.138.218.74 53
found 0 associations
found 1 connections:
     1:	flags=82<CONNECTED,PREFERRED>
	outif (null)
	src 10.0.0.176 port 60952
	dst 193.138.218.74 port 53
	rank info not available

Connection to 193.138.218.74 port 53 [udp/domain] succeeded!

If dhcp.@dnsmasq[x].noresolv=1 then dnsmasq sends queries only to dhcp.@dnsmasq[x].server.
If you can't get response from dnsmasq, it means dnsmasq doesn't receive a response from those servers.
Troubleshooting from OpenWrt:

nslookup example.org server_ip_address

Thanks, @vgaetera. Appreciate all the help you're giving me.

When run on my router, this:

*** Can't find openwrt.org: No answer

When run on a client device, it returns:

;; Truncated, retrying in TCP mode
Server:		193.138.218.74
Address:	193.138.218.74#53

Non-authoritative answer:
Name:	openwrt.org
Address: 139.59.209.225

So, it looks like it's definitely peculiar to (Mullvad's) DNS resolver. It's only affecting my Philips Hue bridge, though. All other devices work fine.

Curiously, If I set dhcp.@dnsmasq[x].noresolv=1 and put DNS.watch addresses in dhcp.@dnsmasq[x].server, then the Hue Bridge connects fine. I wonder if ;; Truncated, retrying in TCP mode is significant? The Hue Bridge doesn't have TCP fallback (as far as I know), so whilst other client devices can fallback when UDP fails(?), the Hue device cannot.

How might I determine why 193.138.218.74 is reachable from client devices, but not the router?

1 Like

We have an explanation! No lookups over UDP on Mullvad's DNS server:

Most likely it is because OpenWRT does not handle lookups over TCP.

ie:

root@meepmeep:/mullvad# nslookup mullvad.net 193.138.218.74
;; Truncated, retrying in TCP mode.
Server: 193.138.218.74
Address: 193.138.218.74#53

Non-authoritative answer:
Name: mullvad.net
Address: 46.166.138.241

Our public DNS server will reply to try over TCP, and most clients handle that well, it seems some > routers (like OpenWRT does not)

Marking as 'solved'

1 Like

Yep, it truncates UDP-response with tc flag:

# dig @193.138.218.74 openwrt.org +ignore

; <<>> DiG 9.11.2-P1 <<>> @193.138.218.74 openwrt.org +ignore
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56106
;; flags: qr tc rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 9b00f22b4f6988f6 (echoed)
;; QUESTION SECTION:
;openwrt.org.			IN	A

;; Query time: 19 msec
;; SERVER: 193.138.218.74#53(193.138.218.74)
;; WHEN: Wed Apr 10 12:12:00 MSK 2019
;; MSG SIZE  rcvd: 52
1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.