Building an invisible firewall
Bridging makes your Linux machine into a very large and expensive Ethernet switch. You can put 2 or more NIC's in the machine and send packets from one segment out to another based entirely on MAC address. This will work for any protocol, not just TCP/IP.
This would be useful if you don't have administrative control over your upstream routers, or have sensitive machines to protect but don't want to set up a full routed network.
Of course you didn't spend hundreds or thousands of dollars to take the place of a $30 100BaseT switch (I hope). The exciting part is when you can transparently block and alter packets as they traverse your bridge. You can get the same blocking and mangling effect with the low-quality HP ProCurve switches, but good luck picking what gets mangled. :-)
I used RedHat 7.3 for the OS on my machine. It doesn't make too much difference, but they do include the utilities that you will need and one of the bridging code authors makes a kernel RPM available. No services will be listening at all on this machine, so network security won't be hard.
Do a minimal installation, you should be able to get it under 1 gig. Include kernel development and development tools, in case you need to recompile. You shouldn't have to, but it's easier now. Leave the network cables unconnected and give the NIC's any random IP. They won't be used.
After the installation is complete, remove the files /etc/sysconfig/network-scripts/ifcfg-eth*. The bridge won't work if the underlying NIC's have addresses assigned to them. Also, use ntsysv to turn off any services that are listening to the network, like xinetd, sshd, portmap, and nfslocking. You can manually stop the services now also, or reboot and check again if you don't know how (hint: service sshd stop).
Grab the file bridge and drop it in /etc/rc.d/init.d/. Run chkconfig --level 345 bridge on. This will take care of creating the bridge device and adding the NIC's to the bridge.
You will also need to install the bridge-utils rpm. You can get it from your RedHat CD's or download it from ftp://rpmfind.net/linux/redhat/7.3/en/os/i386/RedHat/RPMS/bridge-utils-0.9.3-4.i386.rpm.
Next, grab the bridge+netfilter kernels from http://www.math.leidenuniv.nl/~buytenh/bridge-nf-rpms/. If you are using RedHat 7.3, you can just rpm --upgrade kernel-2.4.18-10brnf0.0.7.i686.rpm. It will adjust your grub.conf automatically for you. Reboot and cross your fingers. Watch for error messages.
At this point, you should be able to insert the bridging firewall into your network and everything will work just like it did before. Below is a diagram of a suggested configuration:
192.168.1.10 192.168.1.5 +----------+ +----------+ | Desktop | | Server | +-----+----+ +-----+----+ | | eth1 eth0 192.168.1.1 | | +----------+ +----------+ +-------------+---------| Firewall |-----| Router |-- Internet +----------+ +----------+You should be able to ping the router and get to the Internet. There is a delay of 10-30 seconds while the bridge determines what is on each side and waits to forward packets. You can check what the bridge is doing by running brctl showstp br0 and check the status of each interface. If it doesn't show LEARNING or FORWARDING, something is probably wrong. If they are listed as DISABLED, you haven't brought up your underlying NIC's.
After your network is behaving like it did before you started messing with it, we can do the firewalling. I have put sample IP addresses on the devices above. Notice there isn't one on the firewall. It will be mostly invisible and not require and IP address.
We will say that our network policy allows incoming SMTP, ssh, and POP-3 to the server, and nothing to the client machine. Our firewall commands will look like this:
# allows connection tracking support, needed modprobe ip_conntrack modprobe ip_conntrack_ftp # enables connection tracking, needed iptables -I FORWARD -m state --state INVALID -j DROP iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT # allows all outbound traffic iptables -A FORWARD --in-interface eth1 --out-interface eth0 -j ACCEPT # allow inbound services iptables -A FORWARD --in-interface eth0 --out-interface eth1 -p tcp -d 192.168.1.5 --destination-port smtp -j ACCEPT iptables -A FORWARD --in-interface eth0 --out-interface eth1 -p tcp -d 192.168.1.5 --destination-port pop-3 -j ACCEPT iptables -A FORWARD --in-interface eth0 --out-interface eth1 -p tcp -d 192.168.1.5 --destination-port ssh -j ACCEPT # drop everything else iptables -A FORWARD --in-interface eth0 --out-interface eth1 -d \! 192.168.1.5 -j REJECTYou can download this file as a text file.
After running these commands and verifying that they work as you anticipate, run /etc/rc.d/init.d/iptables save and chkconfig --level 345 iptables on to save your firewall rules and apply them at boot.
If you really, really think you need to have an IP address on the firewall, you can give one to the interface br0. DO NOT give an IP to eth0 or eth1, bad things will happen. I'm not sure what, but the bridging docs told me so.