Local Name Resolution in Arch

2020-09-26

It's quite handy to be able to access clients connected at the same Access Point as you using their hostname.

There are a few technologies to do that : mostly, Apple's Bonjour translates as mDNS in the Linux world, with the avahi package ; then there is Microsoft's NetBIOS protocol, that is provided by samba under Linux but not running as a default. And Microsoft also created the LLMNR resolution protocol, that ships with Windows starting at Vista (and with 7, 8 and 10).

To have local name resolution, an option is systemd-resolved, since it does both mDNS and LLMNR. It's also quite sophisticated, and not easy to debug. On the other side, avahi does mDNS and lets you advertise specific services on the network. If you're interested in this you might want to go for it ; check Archwiki's page on network configuration.

avahi

First disable systemd-resolved.service, as both are mutually exclusive. Then install the avahi package. Start avahi-daemon.service. Check that your firewall allows mDNS requests (the relevant port is 5353). Edit the hosts line in /etc/nsswitch.conf until it resembles :

hosts: mymachines mdns_minimal [NOTFOUND=return] files myhostname dns

Then check that you have local name resolution with

ping NEIGHBOUR.local

where NEIGHBOUR is another machine on the local network. That's about it.

systemd-resolved

First disable avahi-daemon.service, as both are mutually exclusive. Linux systems resolve DNS domains using the nameserver indicated in /etc/resolv.conf. If it's a symlink to some NetworkManager folder, it's NetworkManager that deals with it. If it's linked to some Systemd folder, then it's systemd-resolved. If it is NetworkManager and you want to switch to systemd-resolved and keep NetworkManager to manage connections, just do :

# ln -sf /run/systemd/resolve/stub-resolve.conf /etc/resolv.conf

It may also be a real file, meaning your computer uses static IP addresses for DNS servers. In this case you can do the same (back it up if you will).

Edit /etc/systemd/resolved.conf so that inside of the [Resolve] section, you have MulticastDNS=yes and LLMNR=yes. After that, you will have to

# systemctl enable systemd-resolved 

Now edit the hosts line in /etc/nsswitch.conf until it resembles :

hosts: mymachines resolve [!UNAVAIL=return] files myhostname dns

And reboot.

Now run resolvectl to see how it goes. If your network interface doesn't specifically allow MulticastDNS, you will have to tell the network manager to do it. If it's systemd-networkd, you will need to add the very same option in the relevant .network files in /etc/systemd/network/. If it's NetworkManager, no luck, you will have to update each and every connection by adding mdns=2 to the [connection] section of the connection definition in /etc/NetworkManager/system-connections.

If you changed anything, you might want to reboot again. Then try

$ resolvectl query SOMEHOSTNAME.local

SOMEHOSTNAME being the name of a device you know is connected. It should answer through mDNS. You may also try resolvectl query SOMEHOSTNAME, skipping the .local extension ; it should answer with LLMNR. Do note that Android devices don't seem to show up on the local network. But they do see declared neighbours ; I suspect they ship with LLMNR since they're only able to ping names without the .local extension.

WINS

The winbind service inside samba uses Microsoft's WINS local resolve. Mostly, you'll need to install samba, create a basic samba configuration, start smb.service, nmb.service and windbind.service, and append wins to the hosts line in /etc/nsswitch.conf.

The basic samba configuration is not so simple ; I'll post another article on that.