Glibc DNS Resolver (non systemd) fails to resolve CNAME record to local CGNAT IP
Describe the problem
When using NetBird 0.53.0 on a Gentoo or MX Linux that doesn't use systemd but the glibc resolver, we cannot resolve a CNAME pointing to a NetBird DNS name to its CGNAT IP. The issue could be around using a DNS name from the managed NetBird zone (.netbird.selfhosted) as the target of the CNAME.
In the below example you would expect wiki.vpn.domain.tld to resolve to 100.93.192.221 but it doesn't whereas querying wiki01.netbird.selfhosted directly does return the IP.
root@mx:~# host wiki.vpn.domain.tld
wiki.vpn.domain.tld is an alias for wiki01.netbird.selfhosted.
root@mx:~# host wiki01.netbird.selfhosted
wiki01.infra.iob has address 100.93.192.221What is normally expected is something like this (e.g: via systemd), the resolver resolves the CNAME and then the A record for wiki01.netbird.selfhosted
root@mx:~# host wiki.vpn.domain.tld
wiki.vpn.domain.tld is an alias for wiki01.netbird.selfhosted.
wiki01.netbird.selfhosted has address 100.93.192.221To Reproduce
Steps to reproduce the behavior:
- Install MX Linux in a VM
- Install NetBird
- Set up public DNS entries (assuming
netbird.selfhostedis NetBird's automatic DNS)wiki.vpn.domain.tld IN CNAME wiki01.netbird.selfhosted
- Where
wiki01.netbird.selfhostedis a node on the NetBird mesh network with the IP100.93.192.221(for illustrative purpose, any IP will do) - Try to resolve:
host wiki.vpn.domain.tld - The IP is not returned.
root@mx:~# host wiki.vpn.domain.tld
wiki.vpn.domain.tld is an alias for wiki01.netbird.selfhosted.I suspect NetBird's resolver sees that wiki.vpn.domain.tld is not 'local', so it tries to resolve it by recursing from the root level, gets the CNAME but then doesn't realise the target is actually a 'local' hostname wiki01.netbird.selfhosted and doesn't resolve via its own authoritative DNS whereas it could :)
Expected behavior I would expect NetBird with Glibc resolver to work the same than on a systemd system. The right answer to the DNS query is:
root@mx:~# host wiki.vpn.domain.tld
wiki.vpn.domain.tld is an alias for wiki01.netbird.selfhosted.
wiki01.netbird.selfhosted has address 100.93.192.221Are you using NetBird Cloud? No. Selfhosted.
NetBird version
netbird version
0.53.0Is any other VPN software installed? No.
Debug output Unfortunately I tore apart my test scenario so I cannot provide a debug output. I abandoned the idea of the CNAME to the NetBird internal domain and point the public name directly to the CGNAT IP. While not ideal, it's a workaround to get us going. However this issue remains an unexpected behaviour.
Screenshots N/A
Additional context I increased debug logging.
oot@mx:~# host wiki.vpn.domain.tld
2025-08-08T14:48:36+10:00 TRAC client/internal/dns/handler_chain.go:166: DNS request domain=wiki.vpn.domain.tld., handlers (3):
- pattern: domain=93.100.in-addr.arpa. original: domain=93.100.in-addr.arpa. wildcard=false match_subdomain=true priority=100
- pattern: domain=netbird.selfhosted. original: domain=netbird.selfhosted. wildcard=false match_subdomain=true priority=100
- pattern: domain=. original: domain=. wildcard=false match_subdomain=true priority=-100
2025-08-08T14:48:36+10:00 TRAC client/internal/dns/handler_chain.go:174: handler matched: domain=wiki.vpn.domain.tld. -> pattern=. wildcard=false match_subdomain=true priority=-100
2025-08-08T14:48:36+10:00 TRAC [request_id: 5af76651] client/internal/dns/upstream.go:114: received upstream question: domain=wiki.vpn.domain.tld. type=1 class=1
2025-08-08T14:48:37+10:00 TRAC [request_id: 5af76651] client/internal/dns/upstream.go:151: took 301.380076ms to query the upstream 192.168.1.254:53 for question domain=wiki.vpn.domain.tld.
Host wiki.vpn.domain.tld not found: 3(NXDOMAIN)
root@mx:~# host wiki.vpn.domain.tld
2025-08-08T14:52:17+10:00 TRAC client/internal/dns/handler_chain.go:166: DNS request domain=wiki.vpn.domain.tld., handlers (3):
- pattern: domain=93.100.in-addr.arpa. original: domain=93.100.in-addr.arpa. wildcard=false match_subdomain=true priority=100
- pattern: domain=netbird.selfhosted. original: domain=netbird.selfhosted. wildcard=false match_subdomain=true priority=100
- pattern: domain=. original: domain=. wildcard=false match_subdomain=true priority=-100
2025-08-08T14:52:17+10:00 TRAC client/internal/dns/handler_chain.go:174: handler matched: domain=wiki.vpn.domain.tld. -> pattern=. wildcard=false match_subdomain=true priority=-100
2025-08-08T14:52:17+10:00 TRAC [request_id: 9d2b7861] client/internal/dns/upstream.go:114: received upstream question: domain=wiki.vpn.domain.tld. type=1 class=1
2025-08-08T14:52:17+10:00 TRAC [request_id: 9d2b7861] client/internal/dns/upstream.go:151: took 1.176969ms to query the upstream 192.168.1.254:53 for question domain=wiki.vpn.domain.tld.
wiki.vpn.domain.tld is an alias for wiki01.netbird.selfhosted.
2025-08-08T14:52:17+10:00 TRAC client/internal/dns/handler_chain.go:166: DNS request domain=wiki01.netbird.selfhosted., handlers (3):
- pattern: domain=93.100.in-addr.arpa. original: domain=93.100.in-addr.arpa. wildcard=false match_subdomain=true priority=100
- pattern: domain=netbird.selfhosted. original: domain=netbird.selfhosted. wildcard=false match_subdomain=true priority=100
- pattern: domain=. original: domain=. wildcard=false match_subdomain=true priority=-100
2025-08-08T14:52:17+10:00 TRAC client/internal/dns/handler_chain.go:174: handler matched: domain=wiki01.netbird.selfhosted. -> pattern=netbird.selfhosted. wildcard=false match_subdomain=true priority=100
2025-08-08T14:52:17+10:00 TRAC client/internal/dns/local/local.go:58: received local question: domain=wiki01.netbird.selfhosted. type=28 class=1
2025-08-08T14:52:17+10:00 TRAC client/internal/dns/handler_chain.go:166: DNS request domain=wiki01.netbird.selfhosted., handlers (3):
- pattern: domain=93.100.in-addr.arpa. original: domain=93.100.in-addr.arpa. wildcard=false match_subdomain=true priority=100
- pattern: domain=netbird.selfhosted. original: domain=netbird.selfhosted. wildcard=false match_subdomain=true priority=100
- pattern: domain=. original: domain=. wildcard=false match_subdomain=true priority=-100
2025-08-08T14:52:17+10:00 TRAC client/internal/dns/handler_chain.go:174: handler matched: domain=wiki01.netbird.selfhosted. -> pattern=netbird.selfhosted. wildcard=false match_subdomain=true priority=100
2025-08-08T14:52:17+10:00 TRAC client/internal/dns/local/local.go:58: received local question: domain=wiki01.netbird.selfhosted. type=15 class=1Observations So based on QTYPES values from Wikipedia, it requests an MX record first (type=15) followed by a AAAA (type=28)... but not the A record (type=1) for the CGNAT IPv4 address we are after.
Unfortunately I can't tell why it's requesting for a AAAA record (ipv6) instead of an A record (ipv4) or even both. Actually, the MX record query could be the mistake, why does it request the MX (type=15) instead of A (type=1)
Ref:
- https://github.com/netbirdio/netbird/blob/main/client/internal/dns/local/local.go#L58
- https://github.com/netbirdio/netbird/blob/main/client/internal/dns/handler_chain.go#L174
- I originally posted my issue on Slack: https://netbirdio.slack.com/archives/C02KHAE8VLZ/p1754626563100329
Have you tried these troubleshooting steps?
- Reviewed client troubleshooting (if applicable)
- Checked for newer NetBird versions (at the time 0.53 was the latest)
- Searched for similar issues on GitHub (including closed ones)
- Restarted the NetBird client
- [N/A] Disabled other VPN software
- Checked firewall settings
Source: netbirdio/netbird