Debian server on the NSLU2
Getting conscious about the amount of energy I use in running a large workstation (an AMD64 machine with cool'n'quiet, granted), I decided to look at replacing it with something smaller.
I wanted a small Linux box, with no moving parts, requiring no cooling and with a low power draw.
After finding out about the Linksys NSLU2 or "slug", I decided this was just the thing and went for it. I had to do quite a bit of hacking to get it where I wanted it (the fun part!), and at the end of the exercise I'm amazed with just how well this thing performs.
I had some Amazon gift money left over, so the net cost to me was £30 (they can be found on eBay for anything up to £50). I then needed some storage and again, being power conscious I bought a 2GB USB stick in the print shop up the road, which was about £10 (yes, I could have got it cheaper online but I wanted it now).
So, total cost is £40 (about $80 for Americans). This gets me a silent Linux machine with 32MB RAM, 2GB storage, it's about the size of a coaster and it draws just 7W while in use. Given that my workstation draws about 70W when idle and electricity averages 11p per KW/h here, I estimate it will take about a year to recoup the cost of the hardware from my electricity bill.
I decided to ignore the advice on the nslu2-linux site of using Unslung, because the packages I wanted either weren't there, or had problems. Also, the kernel used is the older 2.4 series and lacks many new drivers and features.
I went straight for Debian Etch and followed the advice here, which is excellent.
Installation took a couple of hours. I'd advise the following though from my first experiences:
- Untick ALL of the boxes when the software selection choices come around and just install what you need after you've rebooted via the apt repositories. The standard system by default installs a lot of stuff you probably don't need.
- The installer can auto-partition incorrectly. Before you start, plug the USB key into a PC/Laptop and use fdisk to partition the disk into at least a single root partition and a minimum 256MB swap partition.
Saving your USB key
Now for the fun bit. Since I'm using a USB key with limited writes, I absolutely don't want to write to it unless I have to.
Use tmpfs for commonly written to areas
This will be the saviour of your USB key - Linux systems tend to be extremely noisy on certain portions of the disk (particularly /var/log if you're using a syslog daemon obviously). We can save a lot of hassle by simply mounting those directories as tmpfs so they become virtual RAMdisks that don't touch the disk. After some trial and error, I came up with the sizes below for my fstab entries:
none /tmp tmpfs defaults,size=256K 0 0 none /var/run tmpfs defaults,size=128K 0 0 none /var/lock tmpfs defaults,size=64K 0 0 none /var/tmp tmpfs defaults,size=64K 0 0 none /var/log tmpfs defaults,size=512K 0 0 none /etc/network/run tmpfs defaults,size=16K 0 0
Even though Debian defaults to ext3 file systems, we really don't want to use ext3 on our USB key because it writes journal metadata at frequent intervals and will quickly destroy our key. I've seen other articles suggest that you should use commit=secs on your fstab line to at least turn it down but that sounds like delaying the inevitable to me.
I'd say don't bother with that altogether, instead, mount your ext3 partition as ext2 (ext3 is just ext2 with a journal) so the journal isn't touched. I run my slug through a UPS, but you should be fairly safe if you have a power cut as if you're anything like me, you'll be using your slug for serving and most operations will be read only anyway (in fact, you could make your root partition read only when you're finished like I have).
Rewrite the root (and if you have other ext3 partitions, do those as well) to use ext2 and enable noatime to prevent a write to the disk every time you read a file:
/dev/sda1 / ext2 noatime,errors=remount-ro 0 1
You'll also want to get rid of /etc/mtab as its written every time a filesystem is mounted - this symlinks it to /proc/mounts instead (which contains the same information):
ln -sf /proc/mounts /etc/mtab
Once you have everything set up the way you want, you could mark the disk root to mount read only by adding "ro," to the beginning of the fstab entry.
Other articles suggest using vm.swappiness to reduce swapping unless there is no other choice (ie. No file system cache left to reclaim). If you need swap, the software you're running is too heavy and will eventually kill your USB key. Disable swap altogether.
Comment out the line that mounts the swap partition in your /etc/fstab (fstype is "swap"). If you don't want to reboot right now, you can turn off the swap partition from the command line:
For extra cool, you could put the USB key back in a PC and remove the swap partition, then increase the size of the primary partition and extend your ext2/3 filesystem to fill it.
The Debian base system is pretty efficient. If you look at other articles they suggest disabling the serial line and a few other bits and pieces that won't really save much.
What will save memory is being very careful in what software you choose to run on the machine.
For starters, install inetd. Inetd, is a very simple service daemon that listens on ports you tell it, and then spawns the correct program for that service. It means that when your slug isn't serving requests, none of the programs are loaded.
My other suggestions are to use telnet for remote access on your local network (save the overhead of encryption/memory) and to use dropbear via inetd instead of sshd to save about 4MB of RAM (sshd uses about 4MB of RAM and dropbear only 1MB and of course, thanks to inetd, you won't be using it all the time).
apt-get install openbsd-inetd telnetd dropbear
After doing this, edit /etc/securetty and add:
to the end of the file. This will allow one session to log in as root via telnet (you could still log in as your normal non-root user and su to become root if you like and skip this step).
Now, quit your SSH link and log back in over telnet:
Now to get dropbear/inetd working, stop your OpenSSH daemon (it's cool, you're on telnet now):
Then edit your /etc/inetd.conf file and add this line to the end:
ssh stream tcp nowait root /usr/sbin/dropbear /usr/sbin/dropbear -i
You should be able to ssh back in now. Assuming that all is well, you can disable the OpenSSH daemon by removing the S20ssh file from /etc/rc2.d.
A lot of what I use my slug for is serving web requests, streaming music and as a jabber instant message server. I wasn't happy with the memory footprint of these things, so I wrote my own - all of which run through inetd to minimise memory usage.
If possible, try and run everything you can through inetd so the RAM isn't being used all the time - you want an FTP server? Use the netkit OpenBSD one (apt-get install ftpd).
My slug does OpenVPN, DHCP serving, DNS, web, mail, ftp, SSH, TFTP, jabber among many other things and generally runs with about 22MB of its 32MB free, has no swap and a read only root partition.