14

I am trying to get *.local domains to use the DNS server with vagrant-dns. In order for that to work I set up dnsmasq to run in front of it.

NetworkManager is installed but is set to dns=none

resolve.conf:

nameserver 127.0.0.1 #this points to dnsmasq

Testing resolve:

$ nslookup domain.local
Server:     127.0.0.1
Address:    127.0.0.1#53

Name:   domain.local
Address: 10.222.222.22

Dig resolves the same:

$ dig domain.local

; <<>> DiG 9.10.3-P4-Debian <<>> domain.local
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18052
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;domain.local.      IN  A

;; ANSWER SECTION:
domain.local.   86400   IN  A   10.222.222.22

;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sun Jan 29 19:18:52 CST 2017
;; MSG SIZE  rcvd: 49

That is the correct address. I can ping the ip:

ping 10.222.222.22
PING 10.222.222.22 (10.222.222.22) 56(84) bytes of data.
64 bytes from 10.222.222.22: icmp_seq=1 ttl=64 time=0.185 ms

But I can't ping the address:

$ ping domain.local
ping: domain.local: Name or service not known

I also tried from a browser to load the page hosted there, but I get a DNS error. The strange thing is that all other site seem to work fine, although I can't tell if it's using the localhost DNS server or not.

Using debian 8 Jessie/testing

3

4 Answers 4

16

I found the answer! So most of you will know that the /etc/hosts file will resolve domains, somewhat like a DNS server. But how does the system know to look in that file? And how does it know what order to look check that file or a DNS server?

There is a file: /etc/nsswitch.conf

I had the line:

hosts:          files myhostname mdns4_minimal [NOTFOUND=return] dns

This means first check files, like /etc/hosts. Then check the system hostname. Then there is mdns4, which I believe is the protocol for finding other machines on the local network.

After mdns4 is what was holding me up. [NOTFOUND=return]. mdns looks for names ending in .local. If it can't find one, it doesn't just pass to the next and final search method dns, it will actually stop and tell your system that the domain does not exist. Since the domain I set up in dnsmasq was a .local domain, it would never get there.

So there are two ways to fix this. The first is to remove [NOTFOUND=return]. This is the way I chose, and it works great. There is a small delay because I think mdns sees the .local and attempts to look it up anyway before passing it to dns.

This is what my file looks like now:

hosts:          files myhostname mdns4_minimal dns

Another option, since I don't really use mdns, is I could either remove it completely, or there was a way to tell it to use a different tld like .alocal instead - but I think that would effectively disable it also.

1
  • 1
    To answer why there is a difference in behaviour between ping on one side and nslookup and dig on the other side – ping uses libc resolver (which honours /etc/nsswitch.conf file) whereas these other tools talk directly to DNS servers listed in /etc/resolve.conf file. Oct 17, 2020 at 22:20
1

In my case, I have multiple nameserver lines in /etc/resolv.conf and the one I want to use is on the first line.

I read the manual, it says:

If there are multiple servers, the resolver library queries them in the order listed.

But I found it always selects the last nameserver first.

So, I reversed the lines in /etc/resolv.conf

Question resolved.

0

Underscores are not allowed in domain names according to RFC. In my case this was a problem. dig and nslookup uses their own way resolving names and are ok with this. Ping uses system library and fails. Actually, ping fails to resolve if a part of a name begins or ends with underscore.

0

In a very small sliver of use cases, (like mine: Fedora Core 31, long upgrade history), the problem was that nss-mdns hardcodes the path for the avahi-daemon socket to /var/run/avahi-daemon/socket but my /usr/lib/systemd/system/avahi-daemon.socket had a different socket path specified with

ListenStream=/run/avahi-daemon/socket

And, unless you have /var/run symlinked to /run (or /var/run/avahi-daemon symlinked to /run/avahi-daemon) then it will fail to connect. I found this serendipitously while writing up a reply in the following redhat bugzilla bug and running

strace  -e open,openat,connect,read /usr/bin/getent hosts MY_PRINTER_NODE.local

while debugging and trying to prepare enough useful information for the devs/maintainers, where I noticed that it was failing to connect:

connect(3, {sa_family=AF_UNIX, sun_path="/var/run/avahi-daemon/socket"}, 110) = -1 ENOENT (No such file or directory)

For the curious, my nsswitch.conf uses the line:

hosts:      files mdns4 [NOTFOUND=return] dns myhostname

And I have an /etc/mdns.allow file with

.local
.local.

I had tried all the other approaches mentioned here and in other forums and questions, but nothing worked. After I did:

ln -s /run/avahi-daemon /var/run/avahi-daemon

the .local name resolution works, ping works, getent works... all without having to restart any services.

I guess changing the ListenStream path in /usr/lib/systemd/system/avahi-daemon.socket would also work, but that was the default set there at installation. I haven't decided if that's what I will have to do as a long term solution, but hopefully this will work for some other poor soul out there.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .