You've supercharged your router with DD-WRT, you're using it to monitor your bandwidth use, and yet you still wish it could do more. Well it can; today we're looking at how to connect to and use your router with an external USB drive.
DD-WRT is pretty powerful by default, but it isn't perfect. Most of the system is read-only, with the editable configuration stored in nvram, which means you have a Linux router that you can't tweak as freely as a normal Linux system. Some routers, however, have a USB port that can be used to connect external storage; using this, we can replace parts of the read-only filesystem with directories on the writable external disk.
Benefits of doing this include a writable /etc/ for easier software configuration, the ability to add new users, and easier use of ipkg for new software installation. It sounds extreme, but it's quite safe! Nearly every change made is to the external storage, which is loaded over the read-only filesystem. The original data is left unharmed, so you can undo the entire thing by disconnecting the storage device and rebooting.
Before We Begin
Most of this guide assumes your router is one of the models that has USB support. For this guide, we'll be using the Buffalo WZR-HP-G300NH, but any DD-WRT router with a USB port should work. If yours isn't one, don't worry! We'll cover some alternatives and their pros and cons, too.
You will also need access to Linux or a Linux live-CD (preferably GParted Live CD), some type of removable storage, such as an external hard disk or a USB flash drive, and most importantly, you need a router with DD-WRT installed. If you're using the G300NH, you don't have to do anything; DD-WRT is installed by default. For the others, you should refer to our guide or the DD-WRT wiki.
Preparing the Drive
Boot your Live CD and run GParted, then connect the USB device you want to reformat and use. If it's automatically mounted, right click the drive icon and choose "Unmount". In Gparted, select the proper device from the dropdown at the upper right of the window. Make sure you're using the right device by checking the device capacity information in parentheses. When you choose, the rest of the window will update to show the partition information of the selected device.
Under the Device menu, choose Create Partition Table and press Apply to create a new MS-DOS partition table. Right click "Unallocated Space" and select New. The first partition should take most of the space, leaving only a small amount (around 64MiB) at the end. This first partition should be a Primary Partition, and the filesystem should be ext2 (for flash drives) or ext3 (for an external hard disk). You'll need to know what filesystem type you used later, so make a note of it now. The label can be anything you like.
Right click the remaining unallocated space and create a second new partition. The size should be all remaining space (64MiB), it should be a primary partition, and the filesystem should be linux-swap. Some routers can make use of the swap space for extra memory, but others may not be able to (the G300NH cannot), so don't set this too high in case it cannot.
Click the green check box to apply all changes and wait. When it's done, your drive will be ready for its new life attached to your router.
Now that you have a drive ready to use, you need to prepare the router for its use. To do that, you will change some settings via the web interface, so fire up a new tab and enter your router's IP address. After you've logged in, click the Services link at the top and scroll down to the "Secure Shell" section. Enable SSHd and Password Login and save your settings.
Next, click the USB tab. There, you'll need to enable the following: Core USB Support, USB 2.0 Support, USB Storage Support, and ext2 / ext3 file system support. Set the Disk Mount Point to /mnt/ and apply your settings.
Your router is ready for USB storage, so go ahead and plug in the drive now.
Mounting the Drive
The rest of this guide will rely heavily on the command line, so if you're CLI shy, you my want to get familiar with it with our command line primer. Connect to your router via SSH (ssh in Linux and OS X; use PuTTY or KiTTY in Windows) and log in with the username root and your router's password.
Once you're in, type cd /dev/discs/;ls and then cd to the directory listed (probably disc0). Another ls will list the partitions available, which should be part1 (the storage) and part2 (swap space). Make note of filename and the path you used to get here (e.g. /dev/discs/disc0/part1), because it's important.
The drive is connected and we have the location of the device itself, but the filesystem isn't attached (or mounted) to any locations yet, so next we use the path to the device file to mount the partition. Type in mount -t ext2 /dev/discs/disc0/part1 /mnt, replacing ext2 with ext3 if necessary. Type mount again with no arguments and the last line will be similar to /dev/discs/disc0/part1 on /mnt type ext2 (rw,data=ordered) if it was successful.
If it worked, the next step is to make the partition mount at bootup by typing nvram set rc_startup="mount -t ext2 /dev/discs/disc0/part1 /mnt/" (Don't forget to change ext2 and the /dev/ path if needed!)
Preparing the Filesystem
Now the drive is mounted, but most of your filesystem is still read-only. Let's fix that. The first step is to create something that resembles a normal root filesystem inside /mnt/. Change directory to /mnt (cd /mnt) and then mkdir bin etc home jffs lib opt root sbin tmp usr var www; chmod 1777 tmp. Now you have a bunch of directories that can be mounted over existing read-only location. Not every directory created will be used in this guide; the extra ones are for additional tweaking if it is needed later.
One of the goals to this is to replace /etc with /mnt/etc, but that won't work unless the needed files exist. cp -a /etc /mnt/; cd /mnt/etc/ will copy everything from /etc/ into /mnt/etc/, preserving all attributes, and then switch to that directory. Next, mkdir passwd.d group.d; mv passwd passwd.d; mv group group.d
Putting it to Work
Everything is in place, we just need a simple shell script, so it's time to fire up vi. If you don't know vi or don't like it, don't worry, it won't last long. Type vi /mnt/mount.sh to start creating the file, press i to enter insert mode, and put this in the file:
Now press escape to leave insert mode, then :wq to save and quit. Make the file executable with chmod u+x /mnt/mount.sh and your script is ready. Run it with /mnt/mount.sh and you'll have writable directories in /opt, /jffs, /usr/local, /etc/, and root's home directory without causing any damage to the original filesystem.
Left like this, your router will return to its default mostly read-only state when you reboot the router; if you want the writable system and any changes you've made to the configurations and other parts, you'll have to run the mount.sh script manually again. If you decide you like the change and want to make it automatic, you can add it to the previous automount with the following command: nvram set rc_startup="`nvram get rc_startup` && /mnt/mount.sh"
It's still not permanent and you can always revert to the original read-only state by removing the USB storage and rebooting the router.
You've gotten this far and now you want to know what you can do with the modified system. Root's home directory is now available on the removable drive instead of in RAM, so you can store files and user settings and not have them reset on reboot. Likewise, /etc is editable, so you can change system configurations. We can put that to use and make installing software easier.
echo PATH=/usr/local/bin:/usr/local/sbin:$PATH > .profile
The next time you log in to the router, /usr/local/bin and /usr/local/sbin will be at the top of your search path, so you can put your own scripts in there (don't forget to make them executable) and run them by name. One use of this is to fix a problem with the ipkg script that is distributed with DD-WRT. The script tries to use the --passive-ftp switch with wget, but the DD-WRT built-in doesn't accept it, which leaves the entire thing broken. cp /bin/ipkg /usr/local/bin and now you can edit the script and remove the --passive-ftp switch.
While you're editing files, you'll want to look at /etc/ipkg.conf. The supplied package list is most likely older and only usable for certain chipsets (mipsel), so you may need to change repositories. For example, if you're using a Buffalo router, it uses an Atheros chipset, so you can't use packages from the default whiterussian release. Comment out those lines with # and add src kamikaze http://downloads.x-wrt.org/xwrt/kamikaze/snapshots/atheros/packages instead for the G300NH.
After you have ipkg fixed and configured, run ipkg update. You can now list, search for, and install packages with it. If you're not a vi fan, your first install will probably be nano. (Sorry emacs lovers, but it doesn't seem to be available) You may also be able to install swapon and make use of that small swap partition, though it doesn't work on all chipsets and couldn't be tested for this guide.
You can also create new user accounts, though you need access to the htpasswd command and you have to add them by hand-editing the passwd file. On a system that has htpasswd installed, you can run it with the -n switch and then paste the encrypted password into the appropriate place in the /etc/passwd file. Adding new users without a good understanding of what you're doing can be a security risk, so we suggest learning more about the passwd file before trying to add users.
A special note about adding users: when you run the mount script, it reads all the files in /mnt/etc/passwd.d/ and creates a new passwd file from them. If you decide to add new users, create a new file there so that it doesn't cause problems with the users created by the firmware at bootup.
Depending on the router's hardware, there is a wide variety of software that can be added now, including some that expect an editable /etc. There are text-based browsers, IRC clients and servers, image manipulation tools, and more. Your router is now super-powered; happy hacking!
But My Router Doesn't Have USB!
If your router isn't endowed with a USB port, there's still some hope. You can still power up the router by following instructions on setting up JFFS and then adapting everything from "Preparing the Filesystem" onward. This has the disadvantage of putting a lot of wear on the router's flash memory, however, so it's not suggested. Instead, consider purchasing a router with USB support when you replace your current one.