Local domain resolution stopped working in 6.0

Suddenly today all my .lan resolutions stopped working after an automatic upgrade to 6.0.

 dig captain.lan

; <<>> DiG 9.18.7 <<>> captain.lan
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 41739
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;captain.lan.                   IN      A

;; Query time: 0 msec
;; SERVER: 192.168.1.1#53(192.168.1.1) (UDP)
;; WHEN: Wed Oct 19 18:19:22 CEST 2022
;; MSG SIZE  rcvd: 40

❯ dig google.com

; <<>> DiG 9.18.7 <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55630
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;google.com.                    IN      A

;; ANSWER SECTION:
google.com.             128     IN      A       216.58.215.110

;; Query time: 39 msec
;; SERVER: 192.168.1.1#53(192.168.1.1) (UDP)
;; WHEN: Wed Oct 19 18:19:26 CEST 2022
;; MSG SIZE  rcvd: 55
root@turris:~# cat /etc/config/dhcp

config dnsmasq
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option local '/lan/'
        option domain 'lan'
        option localuse '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option port '5353'
        option dhcpscript '/etc/resolver/dhcp_host_domain_ng.py'
        option nonwildcard '0'
        option filterwin2k '1'
        option noresolv '1'
        option serversfile '/tmp/adb_list.overall'
        option confdir '/tmp/dnsmasq.d'
        option authoritative '1'
        option localservice '1'
        option nonegcache '1'
        option cachesize '5000'
        option dnssec '1'
        option domainneeded '1'

config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option dhcpv6 'server'
        option ra 'server'
        option ra_management '1'
        option ra_default '1'
        option ignore '0'
        option leasetime '172800'
        list dhcp_option '6,192.168.1.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'

config dhcp 'guest_turris'
        option interface 'guest_turris'
        option ignore '0'
        option start '100'
        option limit '150'
        option leasetime '172800'
        option dhcpv6 'server'
        option ra 'server'
        list dhcp_option '6,10.111.222.1'

dnsmasq serving DNS on port 5353? Sounds like you were attempting some non-default solution for local names, or why do that? (5353 is allocated for a different protocol mDNS, by the way)

I don’t remember, I had this setup running for like 5 years now without any changes. How would more default configuration look like?

root@turris:~# cat /etc/kresd/custom.conf
local lan_rule = policy.add(policy.suffix(policy.STUB('127.0.0.1@5353'), policy.todnames({'lan','168.192.in-addr.arpa'})))
policy.del(lan_rule.id)
table.insert(policy.rules, 1, lan_rule)
root@turris:~# cat /etc/config/resolver

config resolver 'common'
        list interface '0.0.0.0'
        list interface '::0'
        option port '53'
        option keyfile '/etc/root.keys'
        option verbose '0'
        option msg_buffer_size '4096'
        option msg_cache_size '20M'
        option net_ipv6 '1'
        option net_ipv4 '1'
        option prefered_resolver 'kresd'
        option ignore_root_key '0'
        option prefetch 'yes'
        option static_domains '1'
        option dynamic_domains '1'
        option forward_upstream '1'
        option forward_custom '99_cloudflare'

config resolver 'kresd'
        option rundir '/tmp/kresd'
        option log_stderr '1'
        option log_stdout '1'
        option forks '1'
        option keep_cache '1'
        option include_config '/etc/kresd/custom.conf'
        list rpz_file '/etc/kresd/adb_list.overall'

config resolver 'unbound'
        option outgoing_range '60'
        option outgoing_num_tcp '1'
        option incoming_num_tcp '1'
        option msg_cache_slabs '1'
        option num_queries_per_thread '30'
        option rrset_cache_size '100K'
        option rrset_cache_slabs '1'
        option infra_cache_slabs '1'
        option infra_cache_numhosts '200'
        list access_control '0.0.0.0/0 allow'
        list access_control '::0/0 allow'
        option pidfile '/var/run/unbound.pid'
        option root_hints '/etc/unbound/named.cache'
        option target_fetch_policy '2 1 0 0 0'
        option harden_short_bufsize 'yes'
        option harden_large_queries 'yes'
        option qname_minimisation 'yes'
        option harden_below_nxdomain 'yes'
        option key_cache_size '100k'
        option key_cache_slabs '1'
        option neg_cache_size '10k'
        option prefetch_key 'yes'

config resolver 'unbound_remote_control'
        option control_enable 'yes'
        option control_use_cert 'no'
        list control_interface '127.0.0.1'

More default approach would not use custom.conf (the simplest way would be to make it empty). As you have it now, you’re trying to the same thing in both ways – the default one (checkbox in reForis) and the custom stuff as well.

Can you look into the log and see if there are any errors related to dhcp_host_domain_ng.py ? I have some problems with this script on my Omnia and it fails to add local hosts to the DNS cache…

That’s because dnsmasq tries to source the script but fails because it is Python and not a shell script. Anyone still on 5.4? I’ll paste the path to check to see the difference from 6.0.

1 Like

I rolledback to 5.4.4, can check it for you if you tell me what

To fix this, you need to edit /usr/lib/dnsmasq/dhcp-script.sh

Find the line with

[ -f "$USER_DHCPSCRIPT" ] && . "$USER_DHCPSCRIPT" "$@"

Replace it with

if [ -f "$USER_DHCPSCRIPT" ]; then
        filename=$(basename "$USER_DHCPSCRIPT")
        ext="${filename##*.}"
        if [ "$ext" == "py" ]; then
        $USER_DHCPSCRIPT "$@"
        else
        . "$USER_DHCPSCRIPT" "$@"
        fi
fi

@Pepe Which package should I file an issue against? I might even have a stab a PR if time permits but I don’t know where to look.

I believe this comes from outside Turris modifications: https://github.com/openwrt/openwrt/blob/master/package/network/services/dnsmasq/files/dhcp-script.sh

In 5.4 it is different (I checked one of the backups I have), and the git history does not show that change, so it is definitely something downstream. The difference is that this file now comes from dnsmasq-full as opposed to dnsmasq.

Thanks, this worked.

Considering other people had this error and the @einar has a solution, this doesn’t seem like a too non-default configuration?

Right, there’s certainly a different issue than your modifications. It still served the names on my side (even after several restarts since first 6.0) so I thought it works, but it probably doesn’t update or something.

There are two things: there’s a hotplug script in /etc/hotplug.d/dhcp/40-dynamic-domains which handles part of the job, and then there’s patches/openwrt/to-upstream/0015-dnsmasq-fix-dhcp-leases-script-execution.patch · v5.4.5 · Turris / Turris OS / Turris Build · GitLab which wasn’t applied to 6.0 it seems (but it doesn’t look upstreamed to me, or perhaps in later OpenWRT versions).

EDIT: without a checkout, which I can’t do atm, I can’t seem to find where it went during development.

I suspect it even works fine, just the option dhcpscript line needs to get dropped from config. (I’m not sure what’s the usual approach to forcing change in configs.)

Thanks. Can you check if you have any reference to the script in `/etc/config/dhcp? Scratch that, I can’t seem to find it there.

No, I don’t. I don’t think such things could even be done in that file.

That took a lot of digging. And I somehow got it wrong again. :wink:

/etc/init.d/resolver:

DHCP_SCRIPT=/etc/resolver/dhcp_host_domain_ng.py
[...]
set_dhcp_script() {
        uci_set dhcp "@dnsmasq[0]" dhcpscript "$DHCP_SCRIPT"
        uci_commit dhcp
}

Hopefully I got it right this time…

I posted my full config above, it contains option dhcpscript '/etc/resolver/dhcp_host_domain_ng.py' for dnsmasq