LINUX GAZETTE
[ Prev ][ Table of Contents ][ Front Page ][ Talkback ][ FAQ ][ Next ]

"Linux Gazette...making Linux just a little more fun!"


Implementing a Bridging Firewall

By David Whitmarsh


What is the difference between a bridging firewall and a conventional firewall? Usually a firewall also acts as a router: systems on the inside are configured to see the firewall as a gateway to the network outside, and routers outside are configured to see the firewall as the gateway to the protected network. A bridge is piece of equipment that connects two (or more) network segments together and passes packets back and forth without the rest of the network being aware of its existence. In other words, a router connects two networks together and translates between them; a bridge is like a patch cable, connecting two portions of one network together. A bridging firewall acts as a bridge but also filters the packets it passes, while remaining unseen by either side.

Why might you want to so such a thing? A couple of reasons spring to mind:

My Problem

In my office I had a shiny new ADSL connection from Demon Internet with an assigned 16 address subnet (less base, broadcast and router IP = 13 IP addresses). Because of the vagaries of the UK commercial and regulatory environment, the line and router were installed and owned by British Telecom plc. and there was no facility to configure the router to use an internal gateway. This left me two choices: The first was untenable. Multiplying the number of iptable configurations multiplied the chances of error and the administration overhead. The second had its own drawbacks. While most things can be set up to work quite happily with IP masquerading, there are exceptions, including some technologies that I wished to explore, such as VPNs. A bridging firewall would solve this problem. The firewall could stand between the ADSL router and the rest of the router and protect the network without reconfiguring the router. The one remaining obstacle was that the bridging code in the standard Linux kernel completely bypasses iptables, so you can have a box which is either a bridge, or a firewall, but not both.

The Solution

Fortunately, there is a project to implement bridging in conjunction with iptables, so that any packets transmitted across the bridge can be subject to iptables rules. The result is a firewall that can be totally transparent to the network, requiring no special routing. As far as the Internet is concerned, the firewall does not exist, except that certain connections are blocked. The bridge software is a kernel patch to allow the existing bridge code to work inside iptables. Conveniently, the developers have made available a Redhat 7.2 kernel rpm with the patch installed. Less conveniently, documentation on how to use it is minimal, so I thought to document this implementation as an aid to anyone else following the same path.

Bridging and Routing - how it works

Briefly. the linux bridge implementation works by tying together two or more network interfaces. By monitoring activity on all the attached network segments the bridge code learns which MAC addresses are accessible from each interface and uses this information to decide which packets to send out on each interface. The interfaces attached to the bridge to not normally have an IP address associated with them, but the entire bridge is configured as a single interface to the firewall. packet flows within the firewall

Network topology

My allocated static IP addresses are in the range xxx.xxx.xxx.48-63, i.e. a subnet mask of 255.255.255.240. I decided to split this range into two network segments,xx.xxx.xxx.48-56 would be used outside the firewall, and this includes the IP address of the ADSL router itself (xxx.xxx.xxx.49). xxx.xxx.xxx.57-62 would be the secure section behind the firewall. Note that these are not truly subnets as they are linked by a bridge rather than a router.

network topology

Firewall Rules

The sample firewall script is broadly similar to a conventional firewall setup (cribbed from Oskar Andreasson's iptables tutorial. The basic firewall policy is:
  1. Block packets from unlikely IP addresses
  2. Allow any outgoing connections from behind the firewall
  3. Allow packets in that belong to established connections
  4. Allow connections to specified ports and hosts from outside

Variable definitions

For clarity and maintainability it is a good idea to keep interface names and IP addresses as variables. The values used for these examples are:

BR_IP="xxx.xxx.xxx.57"
BR_IFACE=br0

LAN_BCAST_ADDRESS="xxx.xxx.xxx.63"
INTERNAL_ADDRESS_RANGE="xxx.xxx.xxx.56/29"

INET_IFACE="eth1"
LAN_IFACE="eth0"

LO_IFACE="lo"
LO_IP="127.0.0.1"
"xxx.xxx.xxx" represents the first three bytes of the network IP addresses. $INTERNAL_ADDRESS_RANGE is the secure network segment.

Setting up the bridge

We have to do a some less conventional things to set up the bridge. First we shut down our two interfaces and remove any IP address from them.

ifdown $INET_IFACE
ifdown $LAN_IFACE
ifconfig $INET_IFACE 0.0.0.0
ifconfig $LAN_IFACE 0.0.0.0
If you just executed these commands from a telnet connection (or ssh as you are so security conscious), get up and cross the room to your firewall's console.

Next we create a bridge and assign the Ethernet interfaces to it.

brctl addbr $BR_IFACE

brctl addif $BR_IFACE $INET_IFACE
brctl addif $BR_IFACE $LAN_IFACE
You can now bring up the bridge as an internal interface if you wish:
ifconfig $BR_IFACE $BR_IP

Blocking spoofs

We can block spoofed packets in the mangle PREROUTING chain. By blocking here we can catch both INPUT and FORWARDED packets at the same time. We use mangle PREROUTING rather than nat PREROUTING because only the first packet of each stream is checked in the nat table.

This line ensures that only packets with valid internal addresses are accepted on the internal interface.

$IPTABLES -t mangle -A PREROUTING -i $LAN_IFACE -s $INTERNAL_ADDRESS_RANGE -j ACCEPT
And this prevents packets with internal addresses being accepted on the external interface:

$IPTABLES -t mangle -A PREROUTING -i $INET_IFACE ! -s $INTERNAL_ADDRESS_RANGE -j ACCEPT

Accessing the firewall from the internal network

You may choose to leave your firewall completely invisible to the network, or you may wish for convenience to allow connections from within. These commands will allow all connections to the firewall from the internal network only. You may wish to be more selective depending on your level of trust of your network systems and users.

$IPTABLES -A INPUT -p ALL -i $BR_IFACE -s $INTERNAL_ADDRESS_RANGE -d $LAN_BCAST_ADDRESS -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $BR_IFACE -s $INTERNAL_ADDRESS_RANGE -d $BR_IP -j ACCEPT
Remember that we have already eliminated packets that claim to be from $INTERNAL_ADDRESS_RANGE that appear on the wrong interface.

More information

The kernel patch without which all your iptables rules are in vain.
Oskar Andreasson's iptables tutorial is recommended reading.
Try Rusty's Remarkably Unreliable Guides for background on packet filtering and networking.

Sparkle Home Page (the author's company)

Acknowledgments

Thanks to Lennert Buytenhek for a really useful patch, and also for reviewing this article.

David Whitmarsh

David is an independent consultant working mostly for financial institutions in the City of London through his company, Sparkle Computer Co Ltd. With four young children, spare time is a precious commodity, so the daily commute from Sussex is his main opportunity for tinkering with Linux and open source software on his laptop.


Copyright © 2002, David Whitmarsh.
Copying license http://www.linuxgazette.com/copying.html
Published in Issue 76 of Linux Gazette, March 2002

[ Prev ][ Table of Contents ][ Front Page ][ Talkback ][ FAQ ][ Next ]