Gary Court

  • Home
  • About
  • Blog
  • Contact

Blog » Post

« Installing OpenWRT on the Linksys WRT54GL JavaScript DOM to BadgerFish Encoder »

OpenWRT Advanced Firewall

In continuation of my previous article on installing OpenWRT on a Linksys WRT54GL, I discuss how to set some of the more advanced network configurations of the router, and how to setup a firewall with traffic shaping.

Controlling the Network Switch

WRT54GL Internal ArchitectureIf you’ve had a chance to look at the hardware layout of the WRT54GL, you will notice that the router uses VLAN tagging to seperate the WAN port from the rest of the switch. This VLAN configuration settings are stored in NVRAM and, as such, we can modify them to our heart’s content. The WRT54G series router’s switch supports up to 15 VLAN tags which, since there are only 6 switch ports, is overkill. By default, your router will have the following vlan configuration settings: (you can get/set these using nvram)

vlan0ports="3 2 1 0 5*"
vlan0hwname=et0
vlan1ports="4 5"
vlan1hwname=et0

For a quick explanation; Each vlan’s setting are defined in vlan[#][setting]. Ports defines which ports belong to that vlan, and must always include port 5 or the vlan will not be able to talk to the router (making it essentially useless). The asterisk next to the 5 at the end of the ports list indicates that this vlan is the default vlan. Hwname is the physical port the switch is connected to, and should always be et0 for the WRT54GL.

If you would like to add a DMZ to your router, you can set your nvram settings as such: (this makes port 4 (internal 0) the DMZ)

vlan0ports="3 2 1 5*"
vlan0hwname=et0
vlan1ports="4 5"
vlan1hwname=et0
vlan2ports="0 5"
vlan2hwname=et0

Now that you have the vlan tagging setup properly, you will need to initialize the interface within OpenWRT. First, setup your configuration options for the DMZ zone:

dmz_ifname=vlan2
dmz_proto=static
dmz_ipaddr=192.168.3.1
dmz_netmask=255.255.255.0

Then, make sure in /etc/init.d/S40network that the following line exists:

ifup dmz

At bootup, when the S40network script is run, ifup will look for all nvram settings starting with dmz_ and use them to initialize the interface. It is also smart enough to look at [name]_ifname and determine if it is ethernet interface, vlan, or bridge.

For example, if you look at your lan settings (nvram show | grep "lan_"), it will look something like this:

lan_ifname=br0
lan_ifnames="vlan0 eth1 eth2 eth3"
lan_proto=static
lan_ipaddr=192.168.1.1
lan_netmask=255.255.255.0

What’s happening here is that the lan interface is a bridge of vlan0 (LAN) and eth1 (Wifi). (Don’t ask about eth2 & eth3, I have no idea why they are there)

If you would like to seperate the LAN from the Wifi network, change your settings to:

lan_ifname=vlan0
lan_ifnames="vlan0 eth2 eth3"
lan_proto=static
lan_ipaddr=192.168.1.1
lan_netmask=255.255.255.0
 
wifi_ifname=eth1
wifi_proto=static
wifi_ipaddr=192.168.2.1
wifi_netmask=255.255.255.0

Then make sure /etc/init.d/S40network has the following line within it:

ifup wifi

Just reboot and your seperated.

Note that if you are adding more zones to your router, you should also configure your other services such as firewall script and DHCP client to take advantage of the new configuration.

For dnsmasq, you should add something like the following to /etc/dnsmasq.conf:

dhcp-range=lan,192.168.1.100,192.168.1.199,255.255.255.0,24h
dhcp-range=wifi,192.168.2.100,192.168.2.199,255.255.255.0,1h
dhcp-range=dmz,192.168.3.100,192.168.3.199,255.255.255.0,24h

You should also allow the “safe” zones to talk among each other by adding the following firewall rules to /etc/init.d/S45firewall:

...
WIFI=$(nvram get wifi_ifname)  #add if LAN/Wifi are seperated
DMZ=$(nvram get dmz_ifname)  #add if you have a DMZ zone
...
#replace references to br0
iptables -A FORWARD -i $LAN -o $LAN -j ACCEPT
iptables -A FORWARD -i $LAN -o $WAN-j ACCEPT
 
#add if wifi is seperated
iptables -A FORWARD -i $LAN -o $WIFI-j ACCEPT
iptables -A FORWARD -i $WIFI-o $LAN -j ACCEPT
iptables -A FORWARD -i $WIFI-o $WAN-j ACCEPT
iptables -A FORWARD -i $WIFI-o $WIFI-j ACCEPT
 
#add if dmz is available
iptables -A FORWARD -i $LAN -o $DMZ -j ACCEPT
iptables -A FORWARD -i $WIFI -o $DMZ -j ACCEPT  #if wifi is also seperated
...

Firewall Made Easy

Despite your experience with iptables, this network routing program is hard to read and even harder to remember all the switches when its time to add a new rule to your firewall. Thankfully there is a much easier way to configure your firewall, and it’s called Shorewall.

The Shoreline Firewall, more commonly known as “Shorewall”, is a high-level tool for configuring Netfilter. You describe your firewall/gateway requirements using entries in a set of configuration files. Shorewall reads those configuration files and with the help of the iptables utility, Shorewall configures Netfilter to match your requirements.

You can download one of the latest builds of Shorewall for the OpenWRT from Fabio Longarai’s OpenWRT site. To install Shorewall, it’s as simple as:

cd /tmp
wget http://openwrt.homelinux.net/shorewall_x.x.x_mipsel.ipk
ipkg install shorewall_x.x.x_mipsel.ipk
rm shorewall_x.x.x_mipsel.ipk

Note that the following guide was written for Shorewall v3.0.4-2.

All your configuration files can be found in /etc/shorewall/. Since every person’s needs and router settings are unique, their firewall will be unique as well. As such, the following configuration settings are stereotypical settings only and should be customized to one’s needs. For more information on configuring Shorewall, please see the official documentation.

For beginners to Shorewall, I recommend tackling the firewall files in the following order:

zones

This file specifies the available zones you want to control by your firewall. The names of zones are nothing more then aliases, and as such Shorewall has no understanding of the meaning of them. Do not assume a zone called DMZ will behave like a DMZ zone.

###############################################################################
#ZONE   TYPE            OPTIONS         IN                      OUT
#                                       OPTIONS                 OPTIONS
fw      firewall
lan     ipv4
wifi    ipv4
dmz     ipv4
wan     ipv4
#LAST LINE
policy

This file defines the default behavior for a zone. Any zone is allowed to talk to itself, so you don’t need to specify a zone in both the source and destination. Also, (assuming your networking is A->FW->B) just because A can talk to FW, doesn’t mean that A can talk to B - you must explicitely define it.

You can also, in this file, define what the default behavior of traffic being forwarded from one zone to another is and the type of logging the firewall does.

###############################################################################
#SOURCE         DEST            POLICY          LOG             LIMIT:BURST
#                                               LEVEL
fw      all     ACCEPT
lan     all     ACCEPT
wifi    all     ACCEPT
dmz     fw      ACCEPT
dmz     wan     ACCEPT
dmz     all     REJECT  notice
wan     dmz     ACCEPT
wan     all     DROP
all     all     REJECT  notice
#LAST LINE
interfaces

In this file, you define the interfaces and how they map to the available zones. You can also specify options on restricting what types of erronious traffic can be let through.

###############################################################################
#ZONE   INTERFACE       BROADCAST       OPTIONS
lan     vlan0   detect  routeback,dhcp
wifi    eth1    detect  routeback,tcpflags,dhcp,routefilter,detectnets,nosmurfs
dmz     vlan2   detect  routeback,dhcp
wan     vlan1   detect  routeback,tcpflags,blacklist,dhcp,routefilter,nosmurfs
#LAST LINE
masq

This file defines how source NAT-ing is done through the firewall, and through which interface.

###############################################################################
#INTERFACE              SUBNET          ADDRESS         PROTO   PORT(S) IPSEC
vlan1     vlan0
vlan1     eth1
vlan1     vlan2
#LAST LINE
rules

This is the brain of your firewall, where you define the complicated exceptions to the default policy and let traffic through. A lot can be done in this file, so be sure to read up on it. For this example, I’m going to allow pings to the firewall, and incoming BitTorrent to my main system. The first rules uses a macro while the second is a typical rule that employs DNAT-ing.

#############################################################################################################
#ACTION SOURCE          DEST            PROTO   DEST    SOURCE          ORIGINALRATE            USER/
#                                               PORT    PORT(S)         DEST   LIMIT            GROUP
#SECTION ESTABLISHED
#SECTION RELATED
SECTION NEW
Ping/ACCEPT     wan     fw
DNAT            net     lan:192.168.1.100 tcp     6881:6889   -
#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE
routestopped

The rules in this file define the default behavior when Shorewall is stopped. For the most part, to allow “safe” zones to talk properly when Shorewall is stopped, added them to this file as so:

###############################################################################
#INTERFACE      HOST(S)                 OPTIONS
vlan0   -       source
eth1    -       source
vlan2   -       source
#LAST LINE    
tos

Unfortunately, OpenWRT’s iptables does not support TOS, so don’t bother adding any entries to this file.

params

For the most part, if you are doing basic firewalling, you can ignore the rest of the files in this folder. The only other file you may be interested in is params, where you can define variables to be used in the other config files in this directory. For example, you could put in this file…

$LAN_ZONE=lan
$LAN_IFNAME=$(nvram get lan_ifname)
$LAN_BROADCAST=192.168.1.255
...

… and then, you could use these variables in your scripts …

/etc/shorewall/interfaces:
...
$LAN_ZONE    $LAN_IFNAME    $LAN_BROADCAST    $LAN_OPTIONS
...

… in order to simplify the changing of your network configurations.

Traffic Control

One of my primary goals of setting up a dedicated firewall was to have Traffic Shaping/QoS determine the priority of my internet traffic and adjust accordingly based on the needs to the network. For example, my primary network traffic is VoIP, BitTorrent, and HTTP/web. I want VoIP to have the highest priority of my network communications, while BitTorrent to be the lowest. Therefore, my phone conversations won’t drop when I’m downloading heavy.

In order to use traffic shaping, you must have the tc package installed. You can do this by running:

ipkg install tc

It should be noted before you start that you can only shape outbound traffic. You may ask why, but think about how a network works. The router can only make a decision on what packet has priority over another packet when it has received that packet and examined it. Therefore, it does not make sense to shape incoming traffic since a)your internal network is likely must faster then your incoming internet traffic thus making prioritization useless, and b) you’ve already received the packet, so you might as well just send it on its way (your ISP has determined which packet was important to go down the line first).

tcdevices

First, you need to define the devices on your router you would like to enable traffic shaping on. You can do this by editing the tcdevices config file:

###############################################################################
#INTERFACE      IN-BANDWITH     OUT-BANDWIDTH
wan     5mbit   512kbit
#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE

You should set these settings to your theoretical maximum speed on that line. If traffic starts moving faster then these defined settings, the router will begin dropping packets in order to slow down the traffic.

tcclasses

For my purposes, I created five “buckets” to prioritize my traffic in. Note that a higher priority will get served first (till its empty) before a lower priority is served. In the example below, priority 4 is the default priority and all unmarked traffic will go into this priority queue. I also auto-marked all (small) ACK packets as highest priority to artifically speed up downloads.

###############################################################################
#INTERFACE      MARK    RATE    CEIL    PRIORITY        OPTIONS
br1     1       full    full    1       tcp-ack #CRITICAL
br1     2       full    full    2               #HIGH
br1     3       full    full    3               #NORMAL
br1     4       full    full    4       default #LOW
br1     5       full    full    5               #USELESS
#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE
tcrules

Finally, this is the file where we specify how our traffic is prioritized. I wanted my VoIP traffic to be priority 2, my common internet traffic as priority 3, and my BitTorrent traffic and everything else as 4. The reason I did not make priority 3 my default and then just (add rules to) put BitTorrent in priority 4 is due to the fact that my BitTorrent client does not allow me to define the source ports of outbound traffic. So instead, any unrecognized traffic gets low priority.

In the example below, I specify that Pings & Rdate (time update) requests are highest priority, VoIP traffic & DNS requests are next highest, my common internet traffic (HTTP, SSH, FTP) are next, and everything else is last.

###############################################################################
#MARK   SOURCE          DEST            PROTO   PORT(S) CLIENT  USER    TEST
#                                                       PORT(S)
1       vlan0,eth1      0.0.0.0/0       icmp    8               #Ping
1       vlan0,eth1      0.0.0.0/0       tcp     37              #Rdate
2       vlan0           0.0.0.0/0       udp     5060:5061       #VoIP
2       vlan0           0.0.0.0/0       udp     16384:16482     #VoIP
2       vlan0,eth1      0.0.0.0/0       udp     53              #DNS
2       vlan0,eth1      0.0.0.0/0       tcp     53              #DNS
3       vlan0,eth1      0.0.0.0/0       tcp     80              #HTTP
3       vlan0,eth1      0.0.0.0/0       tcp     22              #SSH
3       vlan0,eth1      0.0.0.0/0       tcp     20              #FTP-DATA
3       vlan0,eth1      0.0.0.0/0       tcp     21              #FTP
#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE

For more advanced rules, see the docs.

Conclusion

Last thing, in order to start using Shorewall, use the command shorewall start. If you would like to have Shorewall start on bootup, add the following code to /etc/init.d/S46shorewall. (Don’t forget to make it executable: chmod a+x S46shorewall)

#!/bin/bash
shorewall start

Please note that you can easily prevent yourself from accessing the CLI with Shorewall. And if Shorewall starts on startup, a reset will not fix the problem. Please thoroughly test your firewall scripts before auto-starting shorewall on startup.

Well, its getting late and I need to crash. I hope you enjoyed the article, and look forward to reading your comments. If you would like more information on a particular section, feel free to drop me a note and I’ll look into updating it. Later!

3 Responses to “OpenWRT Advanced Firewall”

  1. duaux Says:
    August 29th, 2006 at 12:35 pm

    Gary,

    Thank you for this detailed walkthrough! It was exactly what I was looking for. However, after i followed through step by step, I ran into a small problem.

    After I rebooted the router, my DNS request stoped working.

    ie. I get an IP but cannot goto www.google.com, but can go by http://72.40.xx.xx

    I suspect it has to do with:

    /etc/dnsmasq.conf vs. /etc/init.d/S50dnsmasq

    I stopped using S50dnsmasq and used /etc/dnsmasq.conf only.

    Comments in the S50dnsmasq said if I am using /etc/dnsmasq.conf I can get rid of S50dnsmasq.

    Thats what I did… :(

    Anycomments appreciated.

    Thank you.

  2. Gary Court Says:
    August 30th, 2006 at 5:39 pm

    Yea, looks like I forgot to comment on that. I commented out, in S50dnsmasq, the line…

    args=”-l /tmp/dhcp.leases -K -F $(int2ip $start),$(int2ip $end),$(int2ip $netmask),12h ${wanif:+-I ${wanif} }”

    …which essentially removes the overriding configuration options that you then define in dnsmasq.conf.

    You do need to have S50dnsmasq in there in order to start the dnsmasq service.

  3. ibague Says:
    April 20th, 2008 at 4:39 pm

    Well, The best firewall i have found in my experience with linux is APF, very simple configuration and work great! Is there a distribution for openwrt???? i googled a lot some minutes ago without answer

Leave a Reply

Information

  • Author

    Gary Court
  • Posted

    Thursday, February 23rd, 2006 at 11:43 pm
  • Category

    • Linux
    • Tutorial
  • Tags

    • OpenWRT
    • WRT54GL
    • Shorewall
    • advanced
    • firewall
    • traffic
    • shaping
    • qos
    • vlan
    • Linksys
    • network
    • networking
    • router
    • configuration
    • setup
    • switch
    • nvram
    • architecture
    • lan
    • wan
    • dmz
    • wifi
    • port
    • ports
    • init.d
    • dhcp
    • dnsmasq
    • iptables
    • Shoreline
    • ipkg
    • zone
    • zones
    • policy
    • interface
    • interfaces
    • masq
    • nat
    • rules
    • control
    • voip
    • bittorrent
    • tc
    • tcdevices
    • tcclasses
    • tcrules
    • boot
    • bootup
    • startup
  • Response

    • Comment
    • Trackback
  • Syndication

    • RSS 2.0 Comments
  • Related Posts

    • VPNC with Shorewall on OpenWRT
    • Installing OpenWRT on the Linksys WRT54GL
    • Stream Transcoded Media To Your XBox 360 Using TVersity
    • PHP OSGi Framework Concept
CourtNET

© 2005 Gary Court. All rights reserved. | Valid: XHTML CSS | XFN | Powered by WordPress & Gallery 2.