OpenWRT is one of the key drivers behind the Wi-Fi revolution. It got its start as an embedded Linux platform for wireless routers, perhaps inspired by (while separate from) the GPL'd Linksys code, and since 2004 it has been managed as an open source project. OpenWRT has proven to be highly versatile and has spawned a number of forks such as FreeWRT, dd-WRT, and Ewrt, and serves as the operating system for such Wi-Fi notables as Fon and Meraki.
In this article, I will discuss the differences between the forks, how to install and configure OpenWRT without bricking your router, and some of the packages that will be useful for securing and managing your router.
There are currently three major active branches of the OpenWRT platform: OpenWRT, FreeWRT, and DD-WRT. OpenWRT is the original code base, which focuses on a minimal embedded Linux platform with a number of modules to add various functionalities. FreeWRT is a direct outgrowth of OpenWRT and focuses on providing an advanced platform for experienced developers. DD-WRT started with Sveasoft Alchemy but switched over to a WRT kernel to make use of commodity access points from companies like Linksys and Netgear as opposed to high-end APs. DD-WRT has a nice control panel and some other features for easy setup and use. (Ewrt is, alas, no more, so I won't describe it here).
There are a couple versions of OpenWRT: White Russian (stable), Kamikaze (experimental), and buildroot-ng. Development on White Russian has been concluded since February 2007, but for the purposes of this article, I'll stick to the White Russian version anyway since it's stable and there are readily-available binaries. The other forks build on the OpenWRT kernel, so if you decide to go down one of those paths what you learn from this article should still be applicable.
First, you should make sure that your router is supported by OpenWRT by checking the Table of Hardware. The OpenWRT wiki also has instructions for how to flash each supported router. It's important to read these instructions thoroughly to understand how to install OpenWRT on your particular device, as well as differences you might encounter between revs of the same device (like reduced memory, etc.).
Binaries are available for White Russian. Before downloading be sure to check http://wiki.openwrt.org/OpenWrtDocs/Hardware to make sure that your router is supported in White Russian (some are only supported in Kamikaze) and which White Russian binary to download. You'll probably want the binaries from the /default/ directory, which is the standard installation, unless you need PPTP or a micro distribution. Don't worry about any of the other files for now.
If you want to compile your own binaries, download the latest version from the svn repository. You'll also want to checkout the additional packages from https://svn.openwrt.org/openwrt/packages/ (to compile these packages you need to create symlinks to these in the package subdirectory of /trunk/ by typing
Once you checkout the latest release, go to the trunk directory and run the command:
%make menuconfig. This brings up a screen that will allow you to select your router platform and what packages to include in your build. To figure out what platform your router is (and if it's supported by OpenWRT), take a look at the Table of Hardware and your router-specific instructions. Make sure the kernel version and filesystem you select are recommended by the afore-mentioned router-specific instructions.
When you compile your binaries, I suggest using a minimal number of included packages and compiling most of the packages you want as "M" or maybes. By compiling the packages separately, you ensure that your base installation will fit on the limited flash memory on your router.
Exit menuconfig (the save dialog will pop up on exit) and then compile the binaries by typing:
%make. The script will then download the actual source (the files in the repository are linked to all of the source) and then compile it into your firmware binaries and packages. OpenWRT's make system downloads the latest source from the server and compiles it, so make sure you have an Internet connection when you compile your binaries.
Follow the instructions for your device under http://wiki.openwrt.org/OpenWrtDocs/Hardware to install OpenWRT on your router. In most cases, you will likely just use the firmware update interface provided by your manufacturer. However, in some cases you will need to use tftp or another method, so it's important to check for any issues before flashing your device.
If you're switching over from another version of OpenWRT or another WRT-style command line, copy the binary to the router then install the binary by typing:
%mtd –e linux –r write <filename> linux. This command will erase your earlier firmware and write the new firmware to flash. It's important that you erase the old firmware or you risk creating a conflict between the two versions. You should also check for device-specific instructions on the above wiki page, in case there are special instructions for your device.
Once you've flashed your router with OpenWRT, you will need to configure it. This includes changing the passwords, securing the router and wireless access, and updating the firewall.
The first time you access your newly flashed router, you will need to telnet into it using
%telnet <your router's last IP address>. There's no password for the first login, so the first thing you need to do is create a password by typing the command:
%passwd. Once you've changed the password, type
%reboot to reset the router with the new changes.
After you set a password, telnet will be disabled except in failsafe mode and SSH will be the only method you have to access the router. Your router can be accessed using SSH at
root@<your router's IP address>. This SSH terminal will give you access to the guts of OpenWRT, which acts just like a Linux terminal. However, Emacs is not a part of the binary, so you'll have to live with using Vim as your editor.
There's a limited web interface accessible through your browser at your router's IP address. It will let you check on the status of your router, see what packages are installed, and set a number network configuration parameters. Under the hood, your router is fully customizable, so even if you don't see it in the web interface you can probably still find a way to do it.
When you make changes to the router using the web interface, implementing them is a two step process. First, click the "Save Changes" button to save the changes in the appropriate config file. Next, click the "Apply Changes" link to refresh the router's settings with the new changes.
The router filesystem is loaded into a RAMdisk at boot, so normally you'll actually be working in RAM rather than directly on the flash. This approach is beneficial because it allows you to test things without making permanent errors (a hard reset creates a new RAMdisk from the flash). If you want to make permanent changes to your router's configuration, then you can make edits to the filesystem in the subdirectory /rom/. My recommendation is to make changes in the RAMdisk, test them out, and if satisfied then save the changes to the flash.
System variables, such as network interface variables, are stored in nvram (non-volatile RAM) and can be changed using the command
%nvram set <variable>=<value>. Once you've modified all of the nvram variables you need to change, then you can type
%nvram commit to save the changes to the flash.
OpenWRT sets up a number of network interfaces on installation, such as br0, eth0, eth1, lo, vlan0, and vlan1 for my Buffalo WHR-G54S. You should check the table on http://wiki.openwrt.org/OpenWrtDocs/Configuration for what physical interfaces the network interface names correspond, since they differ between routers.
The interfaces are either wifi (Wi-Fi), lan (Ethernet LAN), or wan (Ethernet WAN), and there's a few variables that govern most of the operations, which are listed in a table at the above link. The slightly unusual variable is
_ifnames, which is used to add interfaces to a bridge if the interface owning the variables is a bridge. You can also use the commands
ifup/ifdown wifi/lan/wan to bring up or down all of the interfaces under that type (e.g., wl0, lan, or wan).
You can also separate the LAN and Wi-Fi interfaces by removing both interfaces from the
lan_ifnames variable, setting the
lan_ifname variable to just its interface (eg. vlan0) and creating a new entry for Wi-Fi using the
wifi_* set of variables. This technique is useful if you want to put your router into ad-hoc mode, or if you want to provide public access via the Wi-Fi interface and protected access on the LAN interface.
A similar technique will allow you to create additional VLANs on specific ports on the router. There are two variables that control which ports are assigned to each VLAN:
vlan*hwname (where the star represents a number). A standard 4-port router is actually comprised of six switched ports which are stored by the firmware as 4 LAN ports, 1 WAN port, and 1 port representing the router itself. The variable
vlan*ports stores the specific ports (0-4 and always 5) with which a VLAN is associated, and
vlan*hardware should always be et0 (et0 is used instead of eth0 to maintain compatibility with VxWorks).
The initial configuration of OpenWRT has two VLANs: one for ports 1-4 (LAN) and one for port 0 (WAN). Port 5 is listed with a "*" next to it in the
vlan*ports variable for the LAN interface to denote that the LAN is port 5's primary interface, so any unmarked traffic on port 5 will be passed to the primary interface.
If you want to create new VLANs, you can do so by first creating new
vlan*hardware variables for your new variables (and of course removing those ports from the other VLAN interfaces). Next, create the network interface using the set of interface variables described above with a new name for the set (instead of lan/wan/wifi). Finally, add a line
ifup <interface name> in /etc/init.d/S40network next to the lines
ifup wan, and
ifup wifi to have your new VLAN start on bootup.
The firewall is controlled via rules in Iptables, which is the same firewall as comes standard with Linux. Your firewall is installed blocking all inbound requests from the WAN port of the router. However, you may want to enable some inbound requests or block some outbound requests from the LAN/WLAN ports to make your network more secure.
Custom rules for Iptables can be saved in two places: /etc/config/firewall and /etc/firewall.user. I recommend using /etc/firewall.user for your custom rules, because it is backwards compatible with earlier versions of White Russian. These files also contain a number of commented-out sample rules.
There are four main places to insert rules in the firewall: prerouting, input, output, and postrouting. Unless you want to block packet sniffers/snoops on your LAN (e.g., blocking connections originating and terminating on the LAN interface), you'll probably mostly be interested in the prerouting_wan rule responsible for port forwarding. The format of the rule is
iptables --table nat --append prerouting_wan --protocol <desired protocol> --dport <incoming port> --jump DNAT --to <LAN IP address>:<desired port>.
As you get comfortable with the basic configuration of your OpenWRT installation, you'll probably want to start modifying and adding functionality to your router. OpenWRT gives you a great mechanism to do this: ipkg (itsy-package).
The simplest way to install new packages is to use the System > Installed Software page of the web interface to download and install new packages--just make sure your router is connected to the Internet so that it can download the packages. This process will work well for White Russian, since the code is stable and compiled into binaries. However, if you're using another version, you'll want to be careful to make sure it's downloading binaries from the right directory (set in /etc/ipkg.conf to be http://downloads.openwrt.org/whiterussian/packages/).
In many cases, it may be more practical to copy the package to the router and install it locally. You can accomplish this task by scp'ing the package to the router using the command
%scp <filename> root@<your router's IP address>:~/. Once you've scp'd the package(s) to your router, SSH into your router and type
%ipkg install <filename> to install the package. In some cases, you'll need to be aware of dependencies and install the dependencies prior to installing your intended package.
If you're compiling your own packages, you have two sets of packages that you can install from: packages in the main trunk that you didn't install as part of your initial binary and additional packages from the /packages/ tree. In order to compile the second set of packages, you need to build symlinks by executing the command
%make package/symlinks from the /trunk/ directory. Once you've compiled your packages, it's the same process as above to install them on the router.
WPA encryption is available in OpenWRT with the installation of an additional package, called 'nas', which is available at http://downloads.openwrt.org/whiterussian/packages/non-free/ and can be installed using ipkg. Once you've installed the package you can configure it via the web interface or using the commands described here: http://wiki.openwrt.org/OpenWrtDocs/nas. If you want to go the command-line route, you should save the changes using nvram to ensure that your settings will persist through a reset.
OpenWRT provides you with many other feature sets that can be installed using the ipkg system. These sets include an enterprise-grade software router, an Asterisk server for VoIP, net-snmp for SNMP monitoring, and OpenVPN to set up your router as a VPN client or server, just to name a few. The uses of an OpenWRT router are almost endless, and hopefully I'll have the opportunity to cover some of these uses in future articles.
Ash Dyer is an expert in metro-scale, last-mile, and in-building wireless network infrastructure, applications, and business models.
Return to O'Reilly's ETel.
Copyright © 2009 O'Reilly Media, Inc.