Transparent bridging firewalls

The commands in this article can be used on any Ubuntu/Debian machine.

A transparent bridging firewall is a firewall which can be inserted anywhere on a network, but usually between the network segment containing internet access and the rest of a LAN. Generally they are used to silently police and log traffic from the network to the internet and vice versa, the main advantage being that they can easily be inserted and removed without any network reconfiguration.

Further to this the segment between and including the bridged firewall and internet router can be considered a DMZ where internet facing servers can be placed. Personally I think it is a good idea to place all servers in this no mans land as they are as likely to come under attack from Windows clients on their own LAN as any hacker from the internet. The bridged firewall provides protection for both sides.

In my own usage scenario bridged firewalls are a “have my cake and eat it” solution. In order to use Serial Over LAN for out of band access to servers you need to have a separate router which forwards IPMI traffic, even if the server is down. Generally broadband routers don’t come with robust firewalls i.e. which implement egress filtering, access by exception or logging, so to provide a robust firewall in my config, the transparent bridging firewall is part of the server we want out of band access to.

In this example I have bridged a wireless and ethernet device together but generally it would be 2 ethernet cards i.e. eth0 and eth1 so you should change the config accordingly.

/etc/network/interfaces:

auto br0
iface br0 inet static
address 192.168.1.254
netmask 255.255.255.0
network 192.168.1.0
gateway 192.168.1.252
pre-up ifconfig eth0 down
pre-up brctl addbr br0
pre-up brctl addif br0 eth0
pre-up brctl addif br0 wlan1
pre-up ifconfig eth0 0.0.0.0
pre-up ifconfig wlan1 0.0.0.0
post-down ifconfig eth0 down
post-down ifconfig wlan1 down
post-down ifconfig br0 down
post-down brctl delif br0 eth0
post-down brctl delif br0 wlan1
post-down brctl delbr br0

/etc/rules-save:

# Generated by iptables-save v1.4.4 on Fri AugĀ  6 20:53:42 2010
*filter
:INPUT ACCEPT [33394:2816896]
:FORWARD ACCEPT [73745:4845726]
:OUTPUT ACCEPT [18134:2282560]
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -p tcp -m physdev --physdev-in wlan1 --physdev-out eth0 -m multiport --dports 20:22,25,43,80:81,443,465,587,873,995,3389,5900,8008 -j ACCEPT
-A FORWARD -p tcp -m physdev --physdev-in wlan1 --physdev-out eth0 -m multiport --dports 8080,9002,11371,18990 -j ACCEPT
-A FORWARD -p udp -m physdev --physdev-in wlan1 --physdev-out eth0 -m multiport --dports 123,623,5060 -j ACCEPT
-A FORWARD -p icmp -m physdev --physdev-in wlan1 --physdev-out eth0 -j ACCEPT
-A FORWARD -m physdev --physdev-in wlan1 --physdev-out eth0 -j LOG --log-prefix "iptables denied: "
-A FORWARD -m physdev --physdev-in eth0 --physdev-out wlan1 -j LOG --log-prefix "iptables denied: "
-A FORWARD -m physdev --physdev-in wlan1 --physdev-out eth0 -j DROP
-A FORWARD -m physdev --physdev-in eth0 --physdev-out wlan1 -j DROP
COMMIT
# Completed on Fri AugĀ  6 20:53:42 2010

Ok, so some other things to note. Add “iptables-restore /etc/rules-save” to “/etc/rc.local” so that the firewall starts on boot. This script doesn’t block any traffic to the firewall itself or to other interfaces which may be in the bridge. For instance I have an LXC container which has it’s own dynamically created and destroyed interface which is part of the bridge and since this container serves my network I also use the DMZ feature of my router to direct all internet traffic to it. To make it truely transparent, if the firewall weren’t doing other things, you could remove the ip address from the bridge.

You can also forward all traffic to the firewall and then DNAT any that needs to go to a different machine accordingly. That way the bridge will log blocked traffic coming in from the internet too. For instance at the beginning of /etc/rules-save I have the following rules:-

*nat
:PREROUTING ACCEPT [1334:84566]
:OUTPUT ACCEPT [351:22825]
:POSTROUTING ACCEPT [929:58559]
-A PREROUTING -d 192.168.1.254/32 -p tcp -m multiport --dports 25,80,110,995 -j DNAT --to-destination 192.168.1.253
-A PREROUTING -d 192.168.1.254/32 -p tcp -m multiport --dports 5500 -j DNAT --to-destination 192.168.1.125
-A PREROUTING -d 93.107.47.184/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.253
COMMIT

So to explain the 3 “prerouting” rules, the first one directs all incoming SMTP, HTTP, POP3 and POP3SSL traffic to the LXC container, the second directs reverse VNC traffic to my workstation and the third one allows outgoing requests to websites hosted in the LXC container from the LAN to work correctly.

Leave a comment