Most of the time, I set up a new Raspberry Pi by downloading a copy of Raspbian,1 and writing it to a SD card. Inevitably that leads to machines all called “raspberrypi” which is far from helpful when it comes to distinguishing them from each other.

So, I give each machine a name. This is easy to do, just edit /etc/hostname and /etc/hosts:

pi@breadpi ~ $ cat  /etc/hostname			
pi@breadpi ~ $ cat /etc/hosts	localhost				
::1		localhost ip6-localhost ip6-loopback	
fe00::0		ip6-localnet				
ff00::0		ip6-mcastprefix				
ff02::1		ip6-allnodes				
ff02::2		ip6-allrouters				breadpi					

Editing /etc/hostname changes the machine’s name, but if you don’t have a matching entry in /etc/hosts things like sudo complain:

$ sudo emacs /etc/hosts
sudo: unable to resolve host breadpi

You’ll probably need to reboot to make sure the hostname propagates properly. There’s also a risk that the old hostname has become explicitly embedded in other places.

Zeroconf and avahi

Having given something a name, it’s helpful if others can use it! In olden days we’d give the computer a fixed IP number, and then use the DNS2 to associate the computer’s name with that number. Today though it’s much more convenient to have the IP addresses assigned by DHCP.3 Obviously this makes it hard to put the machine into a zone file!4

Today we can use zeroconf5 techniques to solve the problem. Apple have used this for ages, under the Bonjour6 moniker, but happily it’s also available on Linux. In particular the avahi-daemon package lets us broadcast our name to the world.

Installing and configuring the package is easy, in fact it’s a one-liner:

$ sudo apt-get install avahi-daemon

Then, from a suitably zeroconf enabled machine, you can find the name in the .local domain:

$ ssh pi@breadpi.local
$ curl http://breadpi.local/~pi/

Normally I connect from a Mac which understands .local: if you’re using a Linux box then I think you’ll need to install avahi on it too.

Either way, after a few trivial configuration changes it’s now easy to access Raspberry Pis remotely without digging in DHCPd logs to get their IP addresses.

An unexpected bonus

If you use ssh to connect to a number of different hosts whose IP addresses keep changing, then connecting by name is a particularly good policy.

As a security measure, ssh keeps track of the identity of servers to which it connects, and warns you if they change. However, if you store those identities by IP address, and the IP addresses are different today, ssh will rightly complain that, say, server isn’t the machine we spoke to yesterday.

This problem just disappears if you have a unique name for each box. No more spurious messages like this:


The mechanics

Caveat: I’m a bit hazy about how this works, so you should read the following with more skepticism than normal.

Although zeroconf will do more, we’re only using mDNS7 here. This runs alongside the normal DNS, and so DNS only tools won’t work. For instance:

$ host breadpi.local
Host breadpi.local not found: 3(NXDOMAIN)
$ ssh pi@breadpi.local
Linux breadpi 3.6.11+ #371 PREEMPT Thu Feb 7 16:31:35 GMT 2013 armv6l

The only minor issue is that resolving the name in .local takes noticably longer than other names: several seconds. Presumably the name resolution waits for normal DNS to fail before looking in .local.

On the Mac you can look at the DNS setup with scutil, and it seems vaguely consistent with this idea:

$ scutil --dns						
DNS configuration					
resolver #1						
  nameserver[0] :				
  nameserver[1] :				
  if_index : 8 (en2)					
  reach    : Reachable					
resolver #2						
  domain   : local					
  options  : mdns					
  timeout  : 5						
  order    : 300000					
resolver #3