pigmonkey / spark

Arch Linux Provisioning with Ansible
The Unlicense
387 stars 114 forks source link

/etc/hosts / Unbound not respected by NetworkManager with DNS provided by DHCP #80

Closed StephenBrown2 closed 4 years ago

StephenBrown2 commented 5 years ago

It seems that the NetworkManager config provided here doesn't utilize the Unbound server also installed, as NetworkManager simply overwrites /etc/resolv.conf if any DNS servers are provided by the DHCP server.

I looked into several possible solutions, but couldn't find one that seemed to stick. The farthest I got was installing and starting dnssec-trigger and setting dns=unbound in NetworkManager.conf, but it still resolved some of the sites given in /etc/hosts to the real IP address, rather than 0.0.0.0.

A bit stuck, hope you can help figure this out.

pigmonkey commented 5 years ago

I'm not sure what is causing your problem.

In the Unbound role we add name_servers=127.0.0.1 to /etc/resolvconf.conf, which should mean that the system always use our Unbound instance. NetworkManager isn't touching /etc/resolv.conf directly, but instead uses resolvconf, which should always respect the change we made to its configuration file.

I did a quick test by reconfiguring my router to provide 8.8.8.8 DNS for DHCP clients. When I reconnect to my network, I can see that it is being provided.

$ nmcli dev show wlp4s0 | grep -i dns
IP4.DNS[1]:                             8.8.8.8

But when I look at my /etc/resolv.conf, the system is ignoring the DNS provided by the network and using my local Unbound instance. The only thing in the file that changes when I connect to the network is the addition of the domain entry.

# Generated by resolvconf
domain havenaut.net
nameserver 127.0.0.1

I'm not sure why you're experiencing anything different. What does your /etc/resolv.conf look like when all network connections are disabled, and what does it look like when you have connected via NetworkManager to your network providing DHCP?

Regardless of the cause of that problem, none of this should impact /etc/hosts or hostsctl. Unbound doesn't respect /etc/hosts. It provides DNS. /etc/hosts is an alternative (that predates) DNS.

When attempting to resolve a domain, the NSS will first look for an entry in /etc/hosts, only falling back to DNS (using whatever is in /etc/resolv.conf) if nothing is found. As an example:

$ tail -n 1 /etc/hosts
0.0.0.0 zuverink.net
$ ping -c 1 zuverink.net
PING zuverink.net (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=1 ttl=64 time=0.052 ms

--- zuverink.net ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.052/0.052/0.052/0.000 ms
$ host zuverink.net
zuverink.net has address 74.220.219.74
zuverink.net mail is handled by 30 lastmx.spamexperts.net.
zuverink.net mail is handled by 10 mx.spamexperts.com.
zuverink.net mail is handled by 20 fallbackmx.spamexperts.eu.

When I ping that domain, it resolves to localhost because the NSS sees the entry in my /etc/hosts. DNS is irrelevant. When I use host I'm explicitly asking for DNS, so my Unbound server resolves the domain name. The /etc/hosts file is irrelevant.

So even if NetworkManager is somehow overwriting your /etc/resolv.conf to bypass Unbound, when you attempt to ping one of the block hosts it should resolve to localhost. When using a DNS-specific tool like host or dig, blocked hosts should resolve to their actual IP, even when everything is working properly.

JamieMagee commented 5 years ago

I also encountered this issue. The fix was adding the following line to /etc/NetworkManager/NetworkManager.conf

[main]
rc-manager=resolvconf

Check out this page in the Arch wiki for some more info.