December 30, 2008

WRT54GL as an 802.1x client (aka wrt54gl@eduroam)

… after a quite long time (again), here comes a simple HOWTO describing the process of running a Linksys WRT54GL as a wifi client with 802.1x authentication+wpa encryption, in this case for the international wifi educational network initiative – eduroam.


The Linksys WRT54g brand of wifi routers have become quite popular in the past years as many non-Linksys, but open firmware became available for this device. If you own a WRT54g router, you might be familiar with firmware files from dd-wrt or openwrt.

Basically, after flashing and thus replacing the genuine Linksys provided firmware on the WRT54g with the dd-wrt or the openwrt firmware you can get additional functionality available on commercial $1000 routers out of the $60 router. Like, the original Linksys firmware does not contain functionality even for a basic wifi client mode. The dd-wrt firmware is a ready to use firmware available in different flavors – with vpn functionality, with voip or just “basic” functionality. Compared to openwrt firmware, openwrt is in its basic form not so powerful. Openwrt in its basic form does contain only basic stuff, no additional functionality. On the other hand, the advantage of openwrt is that it is nicely customizable and you can pretty easily install additional applications and functionality with a simple apt-get like utility. For this reason I am more used to use the openwrt firmware as it gives me more control of the box.

Well, a step into the $subject: a friend of mine has asked me to help him with connecting his WRT54GL router as a client to our university wireless network. Our university wifi network uses mandatory 802.1x authentication + wpa or wpa2 encryption. Few years ago, even standard computers and laptops had issues with connecting to a 802.1x secured wireless network so what to expect from a small wifi router? Well, a lot :-)

The basic Linksys firmware does not even support wifi client mode on the WRT54GL. Obviously, the next step is to upgrade the firmware to something better. dd-wrt or openwrt? dd-wrt supports wifi client mode, even with static wep keys (maybe even wpa-psk?) but not with 802.1x authentiocation :-/ openwrt in it’s basic form does not support 802.1x, but fortunately a wpa_supplicant package is available already precompiled for this platform. Wpa_supplicant is an EAP supplicant with 802.1x authentication + wpa/wpa2 support.

Few steps to make it work:

  1. Download the openwrt firmware from Make sure to download a firmware based on 2.6 kernel, as the 2.4 version uses the proprietary “nas” Broadcom utility to manage the wireless connection and it does not support 802.1x. I used the openwrt 8.09_RC1 based openwrt-wrt54g-squashfs.bin file.
  2. Download and install the wpa_supplicant package:
    opkg install
    (or opkg update && opkg install wpa-supplicant)
    (the 8+ version of openwrt will use the “opkg” package management utility, pre 8 versions of openwrt used “ipkg”)
  3. Create a configuration file for the wpa_supplicant. The file may look like:
    root@OpenWrt:~# cat /etc/wpa_supplicant.conf
  4. Try it with
    wpa_supplicant -Dwext -iwlan0 -c/etc/wpa_supplicant.conf
    This command will start the wpa_supplicant, will scan for the “eduroam” ssid, connect to AP and try to authenticate as user@domain. If everything is OK, at the end will show some OK messages and will also activate the wifi interface – wlan0. If you start a dhcp client (udhcpc -i wlan0), you should get an IP address now, and you can start pinging the Internet.
  5. Wrap it up, create startup scripts that will at the bootup start the wpa_supplication, do the dhcp client, enable IP routing and NAT and there you go. Ready :-)

My startup scripts look like (not so cool but it works :):

root@OpenWrt:~# cat /etc/init.d/XStartEduroam
#!/bin/sh /etc/rc.common
# Jozef Janitor (c) 2008
# !!!
# make sure that this file has a +x (executable) flag
# enable this script with /etc/init.d/XStartEduroam enable
# dont't forget to disable the preinstalled openwrt firewall script
# !!!


start() {

# Basic filewall and SNAT
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
iptables -A INPUT -s -d -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i br-lan -j ACCEPT
iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type 4 -j ACCEPT
iptables -A INPUT -j DROP

# Set time - otherwise the default WRT's time makes problems
# with a certificate validation in wpa_supplicant
date "`cat /etc/dateToSet`"
date "`cat /etc/dateToSet.backup`"

# Start 802.1x authentication
wpa_supplicant -Dwext -iwlan0 -c/etc/wpa_supplicant.conf &

# wait some time till the interface is authenticated
# and activated
sleep 5

# get the IP address from the DHCP server
udhcpc -i wlan0 &

# start the WatchDog to check if we have access
# to the Internet
/watchGW &

# sync time with the NTP server and store the local
# time into a file for reboot use
/updateDate &


root@OpenWrt:~# cat /watchGW
# Jozef Janitor (c) 2008
# This is a "watchdog" script that checks the IP connectivity to a specified destination.
# When it's not available, restart the device.

echo "Starting GW watchdog"
echo "If host ( is down, reboot"

# root@OpenWrt:/# ping -c 5
# PING ( 56 data bytes
# 64 bytes from seq=0 ttl=59 time=3.199 ms
# 64 bytes from seq=1 ttl=59 time=7.602 ms
# 64 bytes from seq=2 ttl=59 time=3.212 ms
# 64 bytes from seq=3 ttl=59 time=4.804 ms
# 64 bytes from seq=4 ttl=59 time=2.827 ms
# --- ping statistics ---
# 5 packets transmitted, 5 packets received, 0% packet loss
# round-trip min/avg/max = 2.827/4.328/7.602 ms

while true; do

   sleep 300

   out=`ping -c 5 2>&1`

   isFrom=`echo $out|grep "from"`

   if [ "x$isFrom" = "x" ]; then
      echo "!!!!!! REBOOTING !!!!!!!!!!" > /dev/tty
      sleep 5


root@OpenWrt:~# cat /updateDate
# Jozef Janitor (c) 2008
# Sync the actual time and store it in a file to be used after the reboot.

while true; do
        sleep 3600
        ntpclient -c 1 -h -s
        date "+%F %R" > /etc/dateToSet
        sleep 1
        date "+%F %R" > /etc/dateToSet.backup