Build a Linux bridge firewall
Tutorials
Written by Anna Hegedus   
Friday, 10 April 2009 16:50

This tutorial will show you how to build a nice little firewall out of a Shuttle KPC.  If you haven't built your KPC yet and want to know how, the other tutorial to do that is over here.  I picked the KPC because it's ridiculously cheap.  You can find the K45 for sale in some stores for as low as $99 by itself or for about $200 in a bundle that includes everything up to a hard drive.  It's an awesome little versatile machine, and it's tiny, so you can fit them anywhere.  This is a pretty low-power application so you don't really need a processor beyond a Celeron and maybe 2 gigs of RAM.  If you were putting this in front of a whole network or a machine that drank traffic though, you should probably go with a machine that's a little more powerful.  But if you're looking for something that'll protect a small network or a home, this is the ideal solution.  Assuming your KPC is in front of you, assemble it, and let's get started! :)

 

They're gonna build a fire...they're gonna build a fire(wall).


 

The first thing you want to do is install Debian on your KPC.  I like Debian because it's simple, modular, and relatively easy to work with.  If you want to download it, the images are at http://www.debian.org

 

KPC unassembled KPC assembled

 

The only real difference that you're going to see between this one and the other one that I built is that this one is going to have a beefier network card for ingress traffic.  It's an Intel Pro 1000 GT.  You can get them for about $50, and while it's not the greatest thing since Atari, you could do worse.

 

Intel Pro GT 10/100/100

 

Install Debian as you normally would.  Give your machine a decent hostname for a firewall, like, I don't know...

 

Firewall name



So when you install the system, you can do things rather bare bones.  I usually do a base-install and that's it.  You don't really need an X installation or Gnome, so I don't even install the desktop packages.  Basically, it's the "Standard" system option and that's all.  This also keeps the disk size small so you can use a flash card as a hard drive or backup your disks with relatively small image sizes.

 

Base install

 

Getting started with the software install.




Okay, so assuming your Debian install is done, the first thing you want to do is install an SSH server so you don't have to stand directly by the box when you want to do something to it.

 

sudo apt-get install openssh-server

 

Once you press the Y key and enter, the openssh server will be installed along with a bunch of other necessary packages.  Make sure your passwords are secure for your users.  You may want to disable root login for SSH.  To do that:

 

nano /etc/ssh/sshd_config



Find the line that says something like, "permitrootlogin yes" and change yes to no.  Save the file.  You can also change the port SSH listens on by changing "port 22" to some other number.  I recommend a weird one, that way people can't randomly stumble upon your listening daemon unless they scan you.  Security through obscurity is fun!

Next up, install iptables and ebtables.  These are the actual packet and frame inspection software tools that we'll use to manage the firewall.  Because this sucker will be operating as a layer 3 firewall, ebtables won't be necessary now, but you may choose to use this if you want to create a bridge that does MAC filtering.  That's another fun and ranting tutorial however.

 

Install the packages.


 

Issue this command to install the two network filters.  Iptables, the IP-based filter, and ebtables, the MAC address filter.

apt-get install ebtables iptables

Once those two packages are installed, you will want to get the software that makes bridging possible.  Because we have two network cards in our machine, we need to tell Debian that it's all right to allow traffic to pass from one port to another.  We will use the bridge-utils package to do this.

apt-get install bridge-utils

There's one major command you'll need to get used to with bridge-utils, and that's brctl.  The brctl command essentially sets the bridge, allows you to monitor it, add interfaces, remove interfaces...you name it.

Debian doesn't really know how to use the bridge yet.  To do that, you need to go into a file where Debian stores the network config and tailor the file to your needs/wants/desires.  The file is /etc/network/interfaces.

nano /etc/network/interfaces

Use the following file as a template.

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary and seconbdary network interfaces
iface eth0 inet manual
iface eth1 inet manual

iface br0 inet dhcp
pre-up iptables-restore < /etc/iptables.up.rules
bridge_ports eth1 eth0
auto br0 


Save that and quit.  But what do the lines above do, anyway?

 
# The loopback network interface
auto lo
iface lo inet loopback

 

Well, these lines are for the local interface, or loopback.  The interface doesn't really exist physically, but exists virtually so that your machine can talk to itself.  The "auto" line tells the interface that it's all right to come up by itself, while the iface line sets the basic parameters for the local interface.  Mainly, that this is a loopback.

 

# The primary and secondary network interfaces
iface eth0 inet manual
iface eth1 inet manual
 

This sets the network interfaces to manual so they don't attempt to come up by themselves and attempt to contact SkyNet.

 

iface br0 inet dhcp
pre-up iptables-restore < /etc/iptables.up.rules
bridge_ports eth1 eth0
auto br0 
 

The real meat of the file. This tells the machine that interface br0 (the bridge) will grab its address from DHCP and that interface br0 is composed of bridged ports ethernet 0 and ethernet 1.  Before the interface is brought up, the command "iptables-restore" will be ran, restoring the iptables configuration file that exists at /etc/iptables.up.rules.  We'll create that file now.  It'll be important when you create your firewall rules.  That's where they go! 

 
echo "" > /etc/iptables.up.rules


So after all of this is done, you can reboot with a swift ctrl+alt+del, or type reboot.  The machine should come back up shortly. 

 

Let's play Bridge -- I hate solitaire (I know, I'm sorry).


 

Once it does, look at the interface configuration and you'll see some jolly-good fun:

ifconfig | more
 
br0       Link encap:Ethernet  HWaddr ******  
          inet addr:****  Bcast:*****  Mask:*****
          inet6 addr:****** Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:227 errors:0 dropped:0 overruns:0 frame:0
          TX packets:71 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:22906 (22.3 KiB)  TX bytes:9759 (9.5 KiB)

eth0      Link encap:Ethernet  HWaddr 00:30:1b:47:22:4d  
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
          Interrupt:17 

eth1      Link encap:Ethernet  HWaddr **********  
          inet6 addr: ********* Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:290 errors:0 dropped:0 overruns:0 frame:0
          TX packets:77 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:32424 (31.6 KiB)  TX bytes:10227 (9.9 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:560 (560.0 B)  TX bytes:560 (560.0 B)

So there you see several interfaces and a new one named Br0 that stole your IP address.  That's okay -- that's what we wanted to happen.  You see, that new interface is actually the bridge interface that we wanted...the combined eth0 and eth1.  It's kind of the Voltron of both network cards.

Now for some fun.  Test to see if you've got network connectivity on the other side of the bridge by plugging your equipment into the other interface on the backside of the box.  By default, all traffic will flow through the box with no firewall rules in place, so anything should go.  The fun thing is that the box is completely transparent to the other side, so your IP address will still be whatever your DHCP box assigned.

For something even more interesting, try out the command "brctl show br0":
                             
firewall2:~#  brctl show br0



bridge name
bridge id
STP enabled
interfaces
br0
<MAC ADDRESS>
no
eth0

  
eth1


Oh yes, that's awesome, but what about something more?  Try "brctl showmacs br0".  The bridge will report back a list of the connected machines it can see on its network segment.  It will also show you the ageing timer, the amount of time that the address will stay in the forwarding table.  The port number tells you what side of the bridge the MAC is appearing on.  This becomes important if you want to use ebtables to keep some addresses on one side of the bridge but not get to the other side.  For my purposes though, iptables works nicely.  How do you program iptables and how does it work?

 

iptables: Let's do this.


 

By default, iptables comes with several different "chains" that you can work with...mostly, an INPUT chain, an OUTPUT chain, and a FORWARD chain.  There are many different things that you can do with iptables, but for the purposes of this, we are going to keep things simple.

First of all, keep in mind that you have two interfaces.  most of your commands will look something like this:

iptables -A FORWARD -s 191.2.0.0/16 -i br0 -p tcp -m tcp --dport 123 -j ACCEPT

That command will put a rule in the ruleset for the chain FORWARD that allows any machine on the network 191.2.x.x to send traffic on TCP port 123.  At the very end of the FORWARD chain, there's a rule that looks like this:

iptables -A FORWARD -i br0 -m state --state RELATED,ESTABLISHED -j ACCEPT

This rule will allow traffic that is a response of sent traffic to keep coming through the bridge.  The "related" statement allows certain traffic from FTP and ICMP messages through.

-A FORWARD -i br0 -j DROP 

This rule drops any and all other traffic that isn't explicitly allowed.  To list out the rules that you have so far, try the following:

iptables --list 

So lets do this Pittsburgh-style: Roughshod and with a Primanti's sandwich in one hand.

iptables -A FORWARD -s 1.2.244.0/23 -i br0 -p udp -m udp --dport 137:139 -j ACCEPT
iptables -A FORWARD -s 1.2.244.0/23 -i br0 -p tcp -m tcp --dport 21 -j ACCEPT
iptables -A FORWARD -s 1.2.244.0/23 -i br0 -p icmp -j ACCEPT
iptables -A FORWARD -s 1.2.244.0/23 -i br0 -p udp -m udp --dport 5353 -j ACCEPT
iptables -A FORWARD -s 1.2.244.0/23 -i br0 -p tcp -m tcp --dport 443 -j ACCEPT
iptables -A FORWARD -s 1.2.244.0/23 -i br0 -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A FORWARD -s 1.2.244.0/23 -i br0 -p udp -m udp --dport 161 -j ACCEPT
iptables -A FORWARD -s 1.2.244.0/23 -i br0 -p udp -m udp --dport 53 -j ACCEPT
iptables -A FORWARD -i br0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i br0 -j DROP
  1. Allows SMB traffic for printer sharing and files
  2. Allows FTP traffic
  3. Allows ICMP traffic
  4. Allows multicast dns and rendezvous queries
  5. Allows secure HTTPS traffic
  6. Allows unsecure HTTP traffic
  7. Allows SNMP traffic
  8. Allows DNS queries
  9. Allows related and established connections
  10. Allows...nothing. Go away!
Now, you may be wondering about the firewall itself.  If you want certain traffic to be able to touch the firewall box, put it in the INPUT chain.

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -s 1.2.244.0/23 -i br0 -p icmp -j ACCEPT
iptables -A INPUT -s 127.0.0.1/32 -d 127.0.0.1/32 -j ACCEPT
iptables -A INPUT -s 1.2.244.0/23 -p tcp -m tcp --dport 22 -j ACCEPT
iptables -A INPUT -j DROP
  1. Allows related and established connections.
  2. Allows ICMP traffic.
  3. Allows localhost to talk to itself.
  4. Allows SSH traffic from my house to go in.
  5. Allows...nothing.  Go away!

So when you're done building your ruleset, don't forget to save it to the file that we specified above in the /etc/network/interfaces config.

iptables-save > /etc/iptables.up.rules 

When you go to reboot, now it'll remember your rules.

And that's about that!

 


 

UPDATE - 5/18/2009

If you use something like multicast DNS or broadcasts, you may need to explicitly allow those in your firewall settings.  I had to use the following firewall rules on my personal box to allow mDNS and broadcast traffic across the wire:

iptables -A FORWARD -i br0 -o br0 -s 1.2.244.0/23 -m pkttype --pkt-type multicast -j ACCEPT
iptables -A FORWARD -i br0 -o br0 -s 1.2.244.0/23 -m pkttype --pkt-type broadcast -j ACCEPT
Comments (2)
  • Enrico  - great!
    I tried so many times to implement a bridge using pfsense and other stuff i
    found on internet. Always difficult to start, especially for a newbie like me.

    Great guide, thanks!
  • Anna  - re: great!
    Enrico wrote:
    I tried so many times to implement a bridge using pfsense and other stuff i
    found on internet. Always difficult to start, especially for a newbie like me.
    Great guide, thanks!


    Absolutely! That's why I'm here! :D
Write comment
Your Contact Details:
Comment:
[b] [i] [u] [url] [quote] [code] [img]   
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch:
:(:shock::X:side::):P:unsure::woohoo::huh::whistle:;):s
:!::?::idea::arrow:
Security
Please input the anti-spam code that you can read in the image.
Last Updated on Monday, 18 May 2009 17:46