James Stephens

March 24, 2006

Iptables On A Linksys-Cisco WRT54GL Broadband Router HOWTO

Filed under: Iptables — James Stephens @ 4:24 pm

Following on from the announcement of a renewed commitment to Linux by Linksys-Cisco and the release of the Linux-compatible WRT54GL Wireless-G series broadband router (discussed here), this post details how to run Iptables on a Linksys-Cisco WRT54GL router via firmware from DD-WRT. A fully functional example Iptables script is provided to get you started.

There are various aftermarket firmware options available for the WRT54G series routers. We are going to run the DD-WRT firmware which comes with Iptables as well as boasting an extensive feature set beyond the factory default firmware that comes installed on the router. It really is a very impressive firmware and it almost seems there is no end to the list of things you can do with it from the management GUI. I ran into a few difficulties in trying to run some custom Iptables commands but managed to find a way in the end ….

  1. First we need to switch out the factory installed Linksys firmware for the latest DD-WRT firmware. I downloaded both the standard firmware and the mini firmware here. The files may be unpacked using unzip.
  2. Now navigate to Administration --> Firmware Upgrade from the WRT54GL’s GUI administration tool. Browse to the wrt54g firmware file in the mini distribution (dd-wrt-v23_mini_wrt54g.bin for the v2.3 code). Select Upgrade to upload the new firmware on the router.

    NOTE - The DD-WRT Wiki states that you should upgrade from the Linksys factory firmware to the DD-WRT generic mini firmware before resetting to factory defaults and loading the generic standard (std) firmware. I tried this twice but each time I tried to load the mini firmware I ‘bricked’ the router rendering it unusable (see the section below on recovering from a bricked router) and was unable to reach the GUI in a browser although I could ping the unit. I also tried the generic standard firmware directly from the Linksys factory default firmware and was able to run that but discovered that the memory footprint was too large to enable a writeable JFFS filesystem (see later in this post).

  3. Now navigate to Administration --> Services --> SSHD. Select Enable. Reboot the router for the change to take effect.

    At this stage you should be able to securely connect to the router via ssh:

    [root@laptop root]# ssh 192.168.1.1
    root@192.168.1.1's password:
    ---------------------------------------------------------------
    
                         DD-WRT build #23
                  some code portions OpenWRT and EWRT
           additional thanks to Cesar Gonzales, Toxic,
              Elektik, MBChris, Nbd, TheIndividual
          and all the wonderful supporters of this Project
    
                       http://www.dd-wrt.com
    
    ---------------------------------------------------------------
    
    BusyBox v1.01 (2005.12.23-18:13+0000) Built-in shell (ash)
    Enter 'help' for a list of built-in commands.
     
  4. In order to add our own iptables rules ordinarily we would add them by passing a command to nvram. e.g. this rule, which allows remote managment to the router’s WAN IP on port 8080:
    ~ # nvram set rc_firewall="
       iptables -A PREROUTING -p tcp -m tcp -d 172.16.16.200
       --dport 8080 -j DNAT --to-destination 192.168.1.1:80"
    ~ # nvram commit
    

    Unfortunately, this doesn’t work as it should and I was unable to apply any iptables rules in this manner. I did some research online and found others with the same problem. It appears to boil down to a timing issue with the application of the nvram set rc_firewall command.

  5. We can get round the inability to apply firewall commands to nvram by running them from a script which includes a delay. This is done using JFFS, which allows you to have a writeable filesystem on a router running DD-WRT.
    Administration--> Management --> JFFS2 enabled --> Enable
    

    After making this change, click save and reboot the router. Now test if the JFFS filesystem is writeable by connecting to the router using SSH and touching a file under /jffs (touch /jffs/test). If this works without a no space on device error then JFFS is working.

    Note - There is a way to run the generic standard version of the firmware and have a writeable filesystem mounted using samba, instead of having it available locally on the router using JFFS and the mini version of the firmware. It was more trouble for me to setup samba than to sacrifice a few features from the full firmware but your needs may be different. See here for more information on Samba.

  6. We can now create an iptables script, save the script as e.g. /jffs/iptables.fw and make it executable. We then put /jffs/iptables.fw restart into nvram so it gets called whenever we change the firewall settings:
    ~ # nvram set rc_firewall="/jffs/iptables.fw"
    ~ # nvram commit
    
  7. Here is a basic example iptables script which will get you started on using iptables with the WRT54GL:
    #!/bin/sh
    IPTABLES="/usr/sbin/iptables"
    INTERFACES="br0 lo"
    LAN="192.168.1.0./24"
    WANIP="your.wan.ip"
    
    # Wait a while due to timing problem
    sleep 30
    
    # Set default policies to ACCEPT"
    $IPTABLES -P OUTPUT ACCEPT
    $IPTABLES -P INPUT ACCEPT
    $IPTABLES -P FORWARD ACCEPT
    
    # Flush all tables and chains
    #
    cat /proc/net/ip_tables_names | while read table; do
    $IPTABLES -t $table -L -n | while read c chain rest; do
    if test "X$c" = "XChain" ; then
    $IPTABLES -t $table -F $chain
    fi
    done
    $IPTABLES -t $table -X
    done
    
    # Allow all loopback traffic
    $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT
    $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT
    
    # Allow all ESTABLISHED and RELATED traffic"
    $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
    
    # Allow all LAN traffic to router"
    $IPTABLES -A INPUT -i br0 -s $LAN -m state --state NEW -j ACCEPT
    
    # Allow all traffic from router to ANY"
    $IPTABLES -A OUTPUT -m state --state NEW -j ACCEPT
    
    # Allow all traffic from LAN to ANY"
    $IPTABLES -A FORWARD -s $LAN -m state --state NEW -j ACCEPT
    
    # Allow dhcp
    $IPTABLES -A INPUT -i br0 -p udp -s 0.0.0.0 -d 255.255.255.255 \
     -p udp -m multiport --dports 68,67 -m state --state NEW -j ACCEPT
    
    # Enable Network Address Translation
    $IPTABLES -t nat -A POSTROUTING -o vlan1 -s $LAN -j MASQUERADE
    
    # Fix MTU size
    $IPTABLES -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN \
     -m tcpmss --mss 1421:65535 -j TCPMSS --clamp-mss-to-pmtu
    
    $IPTABLES -P OUTPUT ACCEPT
    $IPTABLES -P INPUT DROP
    $IPTABLES -P FORWARD DROP
    
    # enable IP forwarding
    echo 1 > /proc/sys/net/ipv4/ip_forward
    
    exit 0
    

Footnote - Recovering from a bricked router

I’ve had to reset my WRT54GL router a few times now, and it only takes a minute. The easiest way is to use a tftp client on Linux to reinstall Linksys firmware back to the unit as follows:

tftp
tftp> connect 192.168.1.1
tftp> mode binary
tftp> put firmware.bin

Note - Don’t hit Enter after the put command. Firstly, power off the router, wait a few seconds and reinsert the power cable. Immediately after the unit receives power, the power light will flash for a few seconds and at this point you should hit Enter to upload the firmware to the router. It won’t look like anything is happening but after 15 seconds or so you will see a message that the transfer has been completed.

14 Comments »

  1. Great Tutorial :-)

    THX

    Comment by Felix — June 27, 2006 @ 1:40 pm

  2. I recently purchased a new laptop computer with a built in WiFi connection. I soon discovered I could connect to my neighbor’s wireless router and use it to surf the Internet. But after a couple of days, I started receiving the most obscene pictures imaginable instead of the Web pages I wanted. Finally this neighbor laughingly told me that when he realized someone else was using his service, he disconnected the wireless router from the Internet and connected it to an old computer. Then he reconfigured the router so that anytime a Web page was requested, it would instead send random obscene pictures. How did he do this?

    Comment by Tiger — June 28, 2006 @ 1:59 pm

  3. Thanks for the tutorial.
    How would I keep certain IP addresses from connecting through the router? I run SSH and I often see connection attempts using guessed usernames and passwords and I want to block their IP blocks from being forwarded by the router. ATM I have to block them at each machine.

    Comment by Pollywog — October 26, 2006 @ 4:08 pm

  4. I found the answer to my question. As I thought, I needed a FORWARD rule to block certain traffic.

    Comment by Pollywog — October 26, 2006 @ 5:13 pm

  5. ~ # nvram set rc_firewall=”
    iptables -A PREROUTING -p tcp -m tcp -d 172.16.16.200
    –dport 8080 -j DNAT –to-destination 192.168.1.1:80″
    ~ # nvram commit

    That didn’t work because you need

    /usr/sbin/iptables instead of just iptables

    Comment by Nick Berardi — November 20, 2006 @ 11:37 am

  6. How to change firmware of WRT54GS v6 with serial number CGN9…
    How to change ttl=1
    Because v5 and v6 of this router are different with little less flash ram I have to try everything and only this works great. Here are the few steps:

     Download [vxworks_prep_gs_v03.zip] and extract.
     Download and extract [vxworks_killer_gs_v08.zip]
     Download [DD-WRT micro generic]. You may want to check [DD-WRT] to make sure there isn’t a newer version than v23 SP2. Do not use the one labelled ‘WRT54G’ or ‘WRT54GS’, use the ‘generic’ version.
     If you don’t know how to use (or don’t have) a console mode TFTP tool (i.e. tftp.exe), download the [Linksys TFTP transfer tool].
     You will want to assign your network adaptor a manual IP address, since you may loose your automatically configured one and have trouble TFTP’ing the firmware. It’s done at the properties dialog of your network connection, in the ‘Internet Protocol (TCP/IP)’ properties.
     Go to your router’s web based interface and enter the ‘Administration’ tab. Then select ‘Firmware Upgrade’ and choose the vxworks_prep_gs_v03.bin file. Hit apply. After a minute, your browser window will go blank. At this point, power cycle your router.
     Again point your web browser to http://192.168.1.1. You’ll see a different sort of firmware upgrade screen. This is the Management Mode. Select and apply the vxworks_killer_gs_v08.bin firmware upgrade. WAIT for your browser window to turn to report ‘Success’. Have troubles? Try a different web browser, the http daemon in management mode is very finicky.
     Now unplug the power cord of your router, then plug it back in. The power LED should now be blinking.
     Now you need to do a binary mode TFTP transfer of DD-WRT micro generic to your router. To do this you can use the Windows TFTP console mode utility, the Linksys TFTP Windows GUI utility, or some other TFTP client.
     Do NOT reboot your router after TFTP’ing, this will happen automatically. It takes a couple minutes after the TFTP transfer finishes for the firmware to actually be flashed.

    Finalizing
     After your router reboots itself following the TFTP transfer, you should have access to the DD-WRT’s HTTP interface at 192.168.1.1
     Congratulations, you’re now running DD-WRT micro! This was a one tim operation, future firmware updates do not require this process.
     If you have problems, please visit an appropriate user forum to get aid from your fellow users. There are many common problems, and common solutions. I suggest the forums at [dd-wrt.com].
     Remember, the default username and password for a new DD-WRT flash is:
    username: root
    password: admin

    How to TTL=1 to TTL=10:
    In the COMMANDS menu add this line in FIREWALL:

    iptables -t mangle -I PREROUTING -i ppp0 -j TTL –ttl-set 10

    If you have more questions email me: pacooo@abv.bg

    Comment by pacooo — January 13, 2007 @ 3:31 am

  7. Great manual! The only problem I had was flushing of the firewall rules - didn’t work for me. The rules were appended, so I came out with both old and new set together each time. I ended up replacing the flushing loop with:
    iptables -F
    iptables -X
    iptables -t nat -F
    iptables -t nat -X
    iptables -t mangle -F
    iptables -t mangle -X

    That works - at least for me ;)

    Comment by ap1000 — January 24, 2007 @ 9:33 am

  8. I would like to change the ttl value. I added the line:
    iptables -t mangle -I PREROUTING -i ppp0 -j TTL –-ttl-set 10 (it should be — in front of ttl-set) But the TTl does not change, whe I ping on the client. Can someone tell me what should I do.
    Thank’s!

    Comment by Moha — April 16, 2007 @ 4:35 pm

  9. (doubble -) in front of –-ttl-set

    Comment by Moha — April 16, 2007 @ 4:36 pm

  10. James,

    Thanks, this helped me.

    folks, don’t forget to make the script executable:

    chmod 755 /jffs/iptables.fw
    nvram commit

    James,

    I am curious why you set the default policies to ACCEPT just after the sleep? (I see they are set to DROP later, but not sure if there is some reason behind temporarily setting them to ACCEPT)

    Comment by Dave — May 20, 2007 @ 2:01 am

  11. Having just purchased the 54GL I have to say it was a big let down.

    Why?

    Because it very quickly became my door brick. Plugged it in, turned it on, bios fried, didn’t even boot past initial saftey check’s.

    Can’t even ftp into the thing to flash it.

    So back to the factory for this one. I have bookmarked this site though for when I get an actual working one.

    Cheers
    Marc

    Comment by Seo Elite Reviews — June 4, 2007 @ 8:19 pm

  12. Can someone tell me how to configure this for PPPoe?

    Comment by Joe — July 9, 2007 @ 3:15 pm

  13. I need help with a WRT54G v.6, after a bad f/w flash router is bricked (power failure)during flash, was converting to DD-WRT. tried all the safe ways to restore to no avail.
    I have done as the following:
    Reset router with a flash pin grounding
    Assigned static IP address to computer, and set speed to 10/ half MPB
    Conected stand alone D-Link 10/100 ethernet switch conected, adsl modem, router, and computer
    Held reset button 30 sec. pulled the power cord.
    Powered off router 10sec.
    Powered on
    Ping -t 192.168.1.1 recieve Reply from 192.168.1.1: bytes =32 time=1ms TTL=64
    Uploaded recent Linksys F/W with tftp.exe from Linksys
    says “upload success”, waited 10-15 mins, but does not reboot itself, power light continues to blink.
    pushed reset again, and powered off, and on, light still flashing?
    My question is it toast, or did I do something wrong?
    Please help if you can.
    Thanks
    ALex

    Comment by Alex — July 15, 2007 @ 9:06 pm

  14. [...] for upgrading your router to DD-WRT can be found at James Stephens Blog or on the DD-WRT wiki under [...]

    Pingback by RemoteRoot » Blog Archive » Cheap Linux Firewall - IPTables on the WRT54G — July 18, 2007 @ 12:43 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment

You must be logged in to post a comment.

Powered by WordPress