With years, I accumulated devices on my local network, which in general run on Linux.
I meticulously added them to my /etc/hosts/
file, so as not to remember their IP.
Something puzzled me, though:
my Synology NAS was readily available as nas.local
on the network, without doing anything.
I have close to zero skills in system administration, so here are my findings.
The .local
domain
We can learn more about .local
domain from Wikipedia.
The domain name .local is a special-use domain name reserved by the Internet Engineering Task Force (IETF) so that it may not be installed as a top-level domain in the Domain Name System (DNS) of the Internet. As such it is similar to the other special domain names, such as .localhost. However, .local has since been designated for use in link-local networking, in applications of multicast DNS (mDNS) and zero-configuration networking (zeroconf) so that DNS service may be established without local installations of conventional DNS infrastructure on local area networks.
The next step is obviously checking the Multicast DNS definition:
Multicast DNS (mDNS) is a computer networking protocol that resolves hostnames to IP addresses within small networks that do not include a local name server. It is a zero-configuration service, using essentially the same programming interfaces, packet formats and operating semantics as unicast Domain Name System (DNS). It was designed to work as either a stand-alone protocol or compatible with standard DNS servers. It uses IP multicast User Datagram Protocol (UDP) packets and is implemented by the Apple Bonjour and open-source Avahi software packages, included in most Linux distributions. Although the Windows 10 implementation was limited to discovering networked printers, subsequent releases resolved hostnames as well. mDNS can work in conjunction with DNS Service Discovery (DNS-SD), a companion zero-configuration networking technique specified separately in RFC 6763.
In short, when you send a request to a .local
domain, you sent it to a special multicast IP–224.0.0.251
.
Devices can join the multicast group associated to this IP.
From this point on, the router forwards the request to all devices in the group.
The one with the corresponding host will respond, others will ignore it.
Here’s the result of pinging the above IP on my local network:
PING 224.0.0.251 (224.0.0.251): 56 data bytes 64 bytes from 192.168.1.73: icmp_seq=0 ttl=64 time=0.251 ms 64 bytes from 224.0.0.251: icmp_seq=0 ttl=255 time=13.876 ms 64 bytes from 192.168.1.36: icmp_seq=0 ttl=64 time=127.181 ms 64 bytes from 192.168.1.71: icmp_seq=0 ttl=64 time=128.267 ms 64 bytes from 192.168.1.80: icmp_seq=0 ttl=64 time=128.588 ms
Notice that I get responses from other IPs.
With this approach, local networks can avoid the burden of setting up an internal DNS and the configuration that goes with it on each device.
Setting up a .local
domain
For my own local network, I prefer the .local
domain to a full-fledged DNS and configuring every device.
As I mentioned above, my Synology NAS does it automatically.
Let’s set it up for my Raspberry Pi. It works for any Linux-based distribution. I’ll use Avahi, which implements mDNS.
sudo apt-get update
sudo apt-get install avahi-daemon
We also need to update the /etc/nsswitch.conf
to plugin in into the host resolution system.
...
hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4
...
The above configuration tries to resolve host in order:
- Look in
/etc/hosts
- Use Avahi
If the host hasn’t been resolved at this point, return. Note that options after this stage are for documentation only: you can remove them with no side-effect, but it allows admins what options are available.
Since I started using Ansible to manage my Pi, here’s the corresponding playbook:
- name: Configure Raspberry Pi
hosts: 192.168.1.144
vars:
ansible_user: johndoe
tasks:
- name: Update apt cache
become: true
apt:
update_cache: yes
- name: Broadcast device as pi.local
block:
- name: Set hostname to pi
become: true
hostname:
name: pi
- name: Update /etc/hosts with new hostname
become: true
lineinfile:
path: /etc/hosts
regexp: '^127\.0\.1\.1\s+'
line: '127.0.1.1 pi'
- name: Install avahi-daemon
become: true
apt:
name: avahi-daemon
state: present
- name: Ensure avahi-daemon is enabled and running
service:
name: avahi-daemon
state: started
enabled: true
- name: Set mdns in /etc/nsswitch.conf
become: true
lineinfile:
path: /etc/nsswitch.conf
regexp: '^hosts:'
line: 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4'
backup: true
Conclusion
If you operate a small local network that only a few trusted people have access to, you can benefit from multicast and the .local
domain instead of full-fledged internal DNS server.
We only had to install the Avahi daemon locally and tweak the /etc/nsswitch.conf
file.
For Infrastructure-as-Code purposes, I used an Ansible playbook.