Ipv6 dns woes - using local resolver which queries ISP resolvers

After installing a new openwrt 24.10.5 device, I am hoping to set up dnsmasq as a local resolver. Most of it is working in the sense that clients on the lan obtain ipv4 addresses, ipv6 addresses and they are receiving the configuration for the openwrt box to use as name server.

On the openwrt box I want to use the local resolver too, so I set usepeerdns to 0 in both the wan and the wan6 interface and I also set

  • ::1 / 127.0.0.1 as nameserver.
  • a resolvfile in the location /tmp/resolv.conf.ppp which apparently is written when the dsl connection is established

However, the existing resolvfile in /tmp/resolv.conf.ppp does not contain any ipv6 upstream addresses. With usepeerdns unset in the wan6 interface, the ipv6 dns servers by my ISP are still being set in /etc/resolv.conf but with usepeerdns=0, said servers are nowhere to be found.

How do I configure the dns system for ipv6 the same way as ipv4 in the sense that the dns servers by the ISP are being communicated to dnsmasq while openwrt itself uses its local resolver?

edit: config files added. This is /etc/config/dhcp

I have redacted a domain name (example.com and example.de are actually different domains), mac addresses, many host-sections, domain sections

config dnsmasq
	option domainneeded '1'
	option localise_queries '1'
	option rebind_protection '1'
	option rebind_localhost '1'
	option dnssec '1'
	option expandhosts '1'
	option authoritative '1'
	option readethers '1'
	option leasefile '/tmp/dhcp.leases'
	option cachesize '10000'
	option logqueries '1'
	option nonegcache '1'
	option domain 'example.com'
	list rebind_domain 'example.de'
	list rebind_domain 'example.com'
	option resolvfile '/tmp/resolv.conf.ppp'
	option ednspacket_max '1232'
	option localservice '0'

config dhcp 'kika'
	option interface 'kika'
	option start '50'
	option limit '200'
	option leasetime '1h'
	option dhcpv4 'server'
	option force '1'

config dhcp 'lan'
	option interface 'lan'
	option start '50'
	option limit '200'
	option leasetime '1h'
	option dhcpv4 'server'
	option dhcpv6 'server'
	option ra 'server'
	list ra_flags 'managed-config'
	list ra_flags 'other-config'
	option force '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'
	option piofolder '/tmp/odhcpd-piofolder'

config host
	option mac 'de:ad:be:ef:aa:aa'
	option name 'hostname'
	option dns '1'
	option ip '192.168.44.50'
	option leasetime '1h'

this is /etc/config/network


config interface 'loopback'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'
	option device 'lo'

config globals 'globals'
	option ula_prefix 'fd00:db80::/48'
	option packet_steering '1'
	option steering_flows '256'

config route 'k8s_clusterip'
	option interface 'lan'
	option target '10.43.0.0/16'
	option gateway '192.168.44.50'

config route 'route_wan'
	option interface 'pppoe-wan'
	option target '0.0.0.0/0'

config interface 'lan'
	option proto 'static'
	option ipaddr '192.168.44.1'
	option netmask '255.255.255.0'
	option ipv6 '1'
	option delegate '0'
	option ip6assign '64'
	option ip6hint '00'
	option device 'br-lan.5'
	list ip6class 'wan6'
	list ip6class 'local'

config interface 'wan'
	option proto 'pppoe'
	option password 'XXXXXX'
	option username 'DSLXXXXXXXX-o2.de'
	option ipv6 '1'
	option device 'wan'
	option peerdns '0'
	list dns '127.0.0.1'

config interface 'wan6'
	option proto 'dhcpv6'
	option device '@wan'
	option sourcefilter '0'
	option reqaddress 'try'
	option reqprefix '56'
	option norelease '1'
	option peerdns '0'
	list dns '::1'

config dsl 'dsl'
	option annex 'b'
	option tone 'bv'
	option xfer_mode 'ptm'
	option line_mode 'vdsl'
	option ds_snr_offset '60'

config device
	option name 'br-lan'
	option type 'bridge'
	list ports 'lan1'
	list ports 'lan2'
	list ports 'lan3'
	list ports 'lan4'

config bridge-vlan
	option device 'br-lan'
	option vlan '5'
	list ports 'lan1:u*'
	list ports 'lan2:u*'
	list ports 'lan3:u*'
	list ports 'lan4:u*'

config bridge-vlan
	option device 'br-lan'
	option vlan '6'
	list ports 'lan1:t'
	list ports 'lan2:t'
	list ports 'lan3:t'
	list ports 'lan4:t'

config interface 'kika'
	option proto 'static'
	option device 'br-lan.6'
	option ipaddr '192.168.15.1'
	option netmask '255.255.255.0'

this is where the symptom is visible:

root@lady:~# ls -l /tmp/resolv.conf*
lrwxrwxrwx    1 root     root            35 Jan  7 01:04 /tmp/resolv.conf -> /tmp/resolv.conf.d/resolv.conf.auto
-rw-r--r--    1 root     root            48 Jan  7 01:29 /tmp/resolv.conf.ppp

/tmp/resolv.conf.d:
-rw-r--r--    1 root     root            69 Jan  7 01:29 resolv.conf.auto
root@lady:~# cat /tmp/resolv.conf
# Interface wan
nameserver 127.0.0.1
# Interface wan6
nameserver ::1
root@lady:~# cat /tmp/resolv.conf.ppp
nameserver 62.109.121.2
nameserver 62.109.121.1

/tmp/resolv.conf.ppp contains ipv4 dns servers exclusively. If I remove the list dns ‘::1’ bit from the wan6 network config, then /tmp/resolv.conf contains the ipv6 dns servers by the isp in addition to the ipv4 addresses set (127.0.0.1 in this case.)

Please no(t only-) prose, just paste the contents of /etc/config/network and /etc/config/dhcp (and redact sensitive information, like your PPPoE credentials and MAC addresses). A lot of things can get lost without looking at the actual config files.

2 Likes

Today I had another look. When usepeerdns for the wan6 interface is ‘1’ and list dns is set to ‘::1’, then this happens:

/tmp/resolv.conf.ppp contains the two ipv4 dns server

/tmp/resolv.conf.d/resolv.conf.auto contains:

cat /tmp/resolv.conf.d/resolv.conf.auto 
# Interface wan
nameserver 127.0.0.1     <<< this is set by the list dns option in the wan section
# Interface wan6
nameserver ::1           <<< this is set by the list dns option in the wan6 section
nameserver 2a01:c30::530 <<< these are set by the ISP dynamicall.
nameserver 2a01:c30::531

the ipv6 dns hosts by the ISP are exclusively visible in this file. They are not visible in /tmp/resolv.conf.ppp.

The file /tmp/resolv.conf.d/resolv.conf.auto is written by netifd.

the file /tmp/resolv.conf.ppp is written by ppp.

When usepeerdns is set to 0, then something happens that I am not entirely sure of. There seems to be this code path triggered: https://github.com/openwrt/netifd/blob/master/interface-ip.c#L1570

In this case, the provided dns servers are not being written to the resolv.conf.auto file but only the static configuration.

This unfortunately deprives dnsmasq from utilizing the ipv6 nameservers as upstream.

To me, this looks like a not implemented feature, rather than a misconfiguration.

Maybe netifd should be writing these dns servers always (although to a different file, say /tmp/resolv.conf.wan in addition to whatever is being written to resolv.conf.auto)?

@nbd might I ask for your opinion on the matter (I see you authored the last commits in netifd)? Should netifd write the dns servers to interface-specific resolv.conf files, as an option or always?

This would allow to use these dns servers as upstream servers for dnsmasq. I cannot make promises now but if you agree this to be the correct approach, I am happy to try my hand at creating a patch.

How OpenWRT handles DNSMasq is a rather complex process

If you use DNSMasq for DNS then all DNS servers set on the interfaces (or in DHCP) will end up in the same basket which contains the upstream DNS servers for DNSMasq to use.
These can be found in /tmp/resolv.conf.d/resolv.conf.auto which could look like this:

# Interface lan
search home
# Interface wan
nameserver 1.0.0.1
nameserver 9.9.9.9
# Interface wan6
nameserver 2606:4700::1111
nameserver 2620:fe::10

This file is referenced by DNSMAsq as its upstream resolver file but you have altered that:

option resolvfile '/tmp/resolv.conf.ppp'

I do not think that is the way to go

The router itself is a basic linux machine and what it uses for DNS can be found in /etc/resolv.conf which is a symlink for /tmp/resolv.conf

This tells the router to send DNS queries locally (as that is where DNSMasq is listening)

search home
nameserver 127.0.0.1
nameserver ::1

Then you are not using the dns servers advertised by your provider, you can of course add any DNS server manually to your interfaces also those of your provider.

If you want to use the DNS server from your provider automatically then enable usepeerdns, you can of course still add other DNS servers to your liking

Not sure what you are trying to accomplish but I hope my explanation sheds some light on it

There is a fundamental misunderstanding here. By default, the first DNS server is the local instance of dnsmasq. Dnsmasq needs to access an external server for names that it does not know, which is anything on the Internet that hasn't been previously looked up and cached.

So installing ::1 or 127.0.0.1 as an upstream DNS server makes no sense, and names will not be resolved.

peerdns 0 in a wan interface of proto dhcp or dhcpv6 causes the DHCP client to ignore (not add to resolv.conf.d) the DNS servers that were advertised by the ISP in the DHCP response. Then one or more list dns pointing outside the network must be present to make DNS usable. The IP protocol of the list dns DNS server address must match the dhcp proto being used for that interface.

Note that any DNS server may provide a v4 and / or v6 address for the queried name, regardless of the protocol used to reach it.

2 Likes

What I want to achieve is:

  • all clients on the lan should use dnsmasq. this is achieved by sending appropriate dhcp options and slaac options.
  • dnsmasq should use the providers dns as upstream. this is achieved by setting the option for resolvfile.
  • the router itself should use dnsmasq as resolver (to resolve hosts from my local lan that are defined in the dnsmasq config). this can be achieved by setting usepeerdns to 0 and defining localhost as list dns.

the problem is, when setting usepeerdns to 0 (which is required to use the local dnsmasq instance as a resolver on the router itself), then information about the providers resolvers is lost (I would like to configure dnsmasq to use it as upstream resolver). pppd writes the ipv4 resolvers into a file that can be utilized by dnsmasq, but the ipv6 resolvers are not persisted anywhere hence cannot currently be used. This means that the network needs ipv4 to function on the wan side as a prerequisite for ipv6 connectivity. This is not desirable.

Hard-coding my ISPs dns into dnsmasq is not desirable because it might change without notice.

It does. Along with your first two points which also describe default behavior, processes running inside the router use dnsmasq to resolve names (e.g. for NTP or package downloads). dnsmasq is already listening on the loopback interface. You can confirm that with netstat -lpn | grep 53

tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      1057/dnsmasq
...

usepeerdns and list dns are for when you want to not use the ISP's DNS upstream. If you do want to use the ISP's advertised DNS, leave those options out, and the DHCP client will set up the resolve file for dnsmasq to use them.

2 Likes

Running mosquitto_client on the router to establish a connection to a host in my lan reveals that clearly it does not use the local dnsmasq instance unless nameservers in /etc/resolv.conf are set to 127.0.0.1 or ::1. This is in line with any Linux system: the nameservers from /etc/resolv.conf are used. unless usepeerdns is 0, netifd writes the providers’ dns into that location.

just because dnsmasq is listening, does not imply it is being queried.

If you revert this back to the default, the router will use dnsmasq as the local resolver. A non default value bypasses this behavior.

2 Likes

wow, thank you. I never would have guessed this. And I would argue that it should be documented that this one parameter changes more than one thing. https://openwrt.org/docs/guide-user/base-system/dhcp?s[]=0&s[]=0 is what I used. Is this the right place?

On second thought, this could even be considered a problem beyond simple documentation because having one parameter for two very different things (configuring dns resolution for the host / configuring the upstream resolver of dnsmasq) is overloading that parameter.

Needless to say, removing the parameter for resolvfile, removing both list dns settings and usepeerdns did indeed work for the described use case. Thank you again for pointing to this.

I am not sure if this is true, the use of DNSMasq by the router is configurable with the option localuse

You are specifying a different resolver file for use as upstream resolvers but that is not automatically filled so basically it is empty unless you fill it in your self.

But in my testing /tmp/resolv.conf still continues to be:

search home9
nameserver 127.0.0.1
nameserver ::1

meaning the router continues to use DNSMasq

The code segment shared by @dave14305 shows it. if this file is specified, localuse is set to 0. I feel this coupling is incorrect or at the very least should be documented.

And this coupling is actually the root cause of the problem of this thread.

Actually, explicitly setting localuse overrides the automatic behavior before it.