Michael Maclean

The Linksys NSLU2, part one

I’ve spent some time recently playing with a couple of Linksys NSLU2s. These are small devices which have 2 USB ports and an Ethernet port, and are intended to be used to share USB drives across a network via CIFS (Windows file sharing). The best feature of them though is that like the early WRT54G routers, it runs Linux by default, and uses Samba to share the files. This means that with a bit of hacking, it’s fairly easy to extend it to make it more functional. There are a few projects doing this, the most famous being the Unslung firmware.

Another project that has been working on support for the NSLU2 is Debian. As of version 4.0 (Etch), the default Debian installer has had support for them out of the box. More information on this can be found at http://cyrius.com/debian/nslu2/. I’ve installed Etch on both my NSLU2s, though I found it quicker and easier to use the manual install method, which just means unpacking a tarball of the base system. This is described at http://cyrius.com/debian/nslu2/unpack.html. The instructions there are far better than I could describe, so I won’t bother trying to replicate them.

So, what can you do with these things once they’re running Debian? Lots of things. Just now I’m going to describe one of the most basic things I use it for, which is for serving DHCP and DNS on my LAN.

You can, if you like, run the full ISC BIND and dhcpd servers on your Slug, but there isn’t really that much point. They’re big, sometimes tricky to configure, and overkill for a small LAN. A decent, light alternative is dnsmasq. It’s a small daemon that uses the existing /etc/hosts and other related files to handle serving the network. I run it for a couple of reasons - firstly, my ISP’s DNS servers are somewhat less than reliable, so I use dnsmasq to proxy to OpenDNS. Secondly, it allows me to use internal DNS names for my machines. So, for example, rather than having to remember that my router is 192.168.1.1, if I want to go and change something in its configuration, I can just type “portal” into my browser. Similarly, my NSLU2s can be accessed by just typing “ssh kaylee” or “ssh inara”. I’ve picked a domain name that doesn’t exist in the wider Internet to ensure I don’t collide with anything real.

Setting it up

dnsmasq doesn’t come installed by default, but it’s only an apt-get away.

apt-get install dnsmasq

After that, there is a configuration file at /etc/dnsmasq.conf which you may want to have a look at. The defaults are mostly sensible. In my setup, I have changed the following options:

# Set the domain name for hosts on this network
domain=internal.lan
# Set the start and end of the DHCP pool, and set the
# default lease time to 24 hours
dhcp-range=192.168.1.100,192.168.1.150,24h

# Set DHCP option 3 (which supplies the default route) 
# to the IP address of your router - otherwise dnsmasq 
# will assume that the gateway is the machine it is running on
dhcp-option 3,192.168.1.1

# Answer DNS queries based on the interface the request was sent
# to - the effect of this means that you will never get 127.0.0.1
# returned when looking up the name of the dnsmasq server. 
localise-queries

You can also hard-code the MAC addresses of your machines into the dnsmasq.conf file, using the dhcp-host statement, so that each machine will always get the same IP address. This is a neat trick, but personally I don’t think that dnsmasq.conf is the right place to do that when there is already an /etc/ethers file that stores this information. So, for now, uncomment the “read-ethers” line in dnsmasq.conf. I’ll get back to setting up that file in a moment.

Next, you want to set up your resolv.conf file. This will contain the IP addresses of the nameservers you want to use, and which dnsmasq will proxy for. In my case, I’m using OpenDNS, so I’ve grabbed the DNS servers from https://www.opendns.com/start. My resolv.conf now looks like:

domain internal.lan
nameserver 208.67.222.222
nameserver 208.67.220.220

To set up internal hosts on your LAN, you just need to enter them in /etc/hosts, and dnsmasq will read them from there. Beyond the normal entries for localhost and some IPv6 ones, I have things that look like:

192.168.1.1     portal.internal.lan        portal
192.168.1.5     zoidberg.internal.lan      zoidberg
192.168.1.10    inara.internal.lan         inara
192.168.1.11    kaylee.internal.lan        kaylee

You can add as many of these as you like, making sure that the domain name part of them matches what is in /etc/dnsmasq.conf, otherwise they may not work properly.

Finally, back to /etc/ethers. This is a simple mapping between MAC addresses and either IP addresses or names, as long as the names can be resolved by either DNS or (in this case) the /etc/hosts file.

00:12:34:56:78:9A zoidberg.planetexpress.lan
00:BC:DE:F0:12:34 animal.planetexpress.lan

All the hosts in this file will be issued the same IP address every time they do a DHCP request, provided they also exist in /etc/hosts. Bear in mind that MAC addresses are per interface, not per machine, so if you have a laptop with a wired and a wireless interface I’d advise having two entries, one for each. Last of all, ensure that your router or other device isn’t running a DHCP server any more, and run /etc/init.d/dnsmasq restart. The new settings should take effect, and all being well, everything should work.

(I have updated this based on feedback from Jason Liquorish, adding a bit about DHCP option 3 and the localise-queries option, which I forgot earlier. Thanks Jason!)