Tuesday, February 20, 2007 at 10:50 pm by Brady Wilson
Pf as a transparent bridging firewall on FreeBSD 6.2
The Goal:
We needed a way to protect a set of load balanced web servers that host public facing web sites for a client. The web servers each run a copy of the hosting control panel DirectAdmin on top of FreeBSD 6.2 Release.
The Problem:
DirectAdmin licensing requires a real public IP address on the server’s external interface to protect against using the license multiple times by hiding it on a private network. Many different flavors of control panel software have this requirement.
This, of course, eliminates the ability to take the easy way out and NAT the servers behind a firewall.
We would have simply purchased a firewall appliance for this installation (we implement GB-2000 firewall appliances by GTA Inc. however an additional requirement was to use existing 1U server hardware and not purchase an additional appliance.
Solution:
The end solution was to install FreeBSD 6.2 Release on the 1U server hardware and utilize packet filter (pf) as a transparent bridge to meet the IP addressing requirements.
Hardware load balancing was used to load balance HTTP traffic to the web servers but will not be discussed here.
Howto:
1.) Install FreeBSD 6.2.
We have a checklist list of tasks to perform to install and lock down our production servers. Follow your own best practices to get a basic install of FreeBSD 6.2 running and patched. Install the minimal amount of options and packages necessary.
You will need, or at least you will most likely want, a third NIC installed in the server. In a transparent bridge the WAN and LAN interfaces become “transparent” and no longer take an IP address. So without the third NIC installed and connected to your network you will have no way to remotely manage the server. A benefit of this though is that without an IP address to attack your transparent bridging firewall itself would be free from attack.
Pf is available in a default install by re-compiling the kernel with specific changes made, or by enabling pf via kernel loadable module.
We re-compiled the kernel. The options below were added at the end of the kernel source and the new kernel compiled:
# pf support
device pf # Packet Filter firewall
device pflog # PF logging facility
device pfsync # PF state syncing
# ALTQ support
options ALTQ
options ALTQ_CBQ
options ALTQ_RED
options ALTQ_RIO
options ALTQ_HFSC
options ALTQ_PRIQ
2.) Configure your third NIC with an IP address and verify you can remotely access your server.
In the /etc/rc.conf file we have the following definition for the management IF:
ifconfig_fxp0=”inet 123.123.123.2 netmask 255.255.255.0″
We will be building pf rules for this NIC as well to protect the firewall itself.
3.) Create the bridge between the two desired interfaces.
Use your favorite editor to edit /etc/rc.conf and enable the bridge
Add:
cloned_interfaces=”bridge0″
ifconfig_bridge0=”addm bge0 addm nfe0 up”
ifconfig_bge0=”up”
ifconfig_nfe0=”up”
In this case we are bridging the two interfaces bge0 and nfe0.
Use your favorite editor to edit /etc/sysctl.conf
Add:
net.link.bridge.pfil_onlyip=1
net.link.bridge.pfil_member=1
net.link.bridge.pfil_bridge=0
4.) Enable the use of pf on your server.
Use your favorite editor to edit /etc/rc.conf and enable the use of pf
Add:
pf_enable=”YES” # enable PF (load module if required)
pf_rules=”/etc/pf-bridge.conf” # rules definition file for pf
pf_flags=”" # additional flags for pfctl startup
pflog_enable=”YES” # start pflogd(8)
pflog_logfile=”/var/log/pflog” # where pflogd should store the logfile
pflog_flags=”" # additional flags for pflogd startup
5.) Build the firewall ruleset.
First make a copy of the default ruleset and designate it as a bridging ruleset.
# cp /etc/pf.conf /etc/pf-bridge.conf
Use your favorite editor to edit /etc/pf-bridge.conf. Place your ruleset within the pf-bridge.conf file and save the changes.
Here is the sample ruleset we used: pf-bridge_generic.txt
6.) Apply the rules and enable the firewall.
Finally to actually enable a new ruleset we need to tell pf to read the config file. This would also automatically happen upon reboot.
# pfctl –f /etc/pf-bridge.conf
# pfctl –e
That’s it! You will now need to go through and test the bridge and verify you can access what you intended to allow access to, and that what you wanted to block is now blocked. Hopefully you still have access to the management interface as well. The best test will be to perform some form of vulnerability testing against IPs behind your firewall and the firewall itself.
Some notes on the ruleset specifically:
Hurdles:
The first major hurdle we ran into had to do with Multiple MAC address tables on the switch (or lack thereof). We wanted to use a single switch to handle the connectivity for both the inside (LAN) and outside (WAN) of my transparent bridge. To do this we created two VLANs on the switch so that the WAN IF of the bridge connected to VLAN 1 and the LAN IF and the web servers connected to VLAN 2.
The problem is that because of the bridging, the MAC addresses of the web server network adapters were now appearing in both VLANs on the switch thoroughly confusing it.
It turns out that the switch we were using – an older HP Procurve – only had a single MAC address table.
The interim solution was to use two switches, one for each side of the transparent bridge. A better solution will be to use a switch that has more than one MAC address table so that we can use only a single switch for this solution.
The second hurdle is really only the fact that it can take time to perfect the pf ruleset. There are so many options and more than one way to do the same thing. Keep working till it works out correctly.
Some additional commands for managing pf:
# pfctl -s rules : list current parsed rules
# pfctl -f filename : reload the ruleset with the specified file
# pfctl -d : disable pf
# pfctl -e : enable pf
# pfctl -R /etc/pf.conf : enable rules from specified file
# pfctl -s rules -v : hit stats for each rule
View current log with TCPDump:
Log specific tcp packets to a different log file with a large snaplen
(useful with a log-all rule to dump complete sessions)
# pflogd -s 1600 -f suspicious.log port 80 and host evilhost
Display binary logs:
# tcpdump -n -e -ttt -v -r /var/log/pflog
Display the logs in real time (this does not interfere with the operationof pflogd):
# tcpdump -nexttti pflog0
Article Archives:
Virtualized for Non-Profit
Opus Interactive has virtualized 22 of their servers in a effort to upgrade internal systems. Instead of trying to sell the servers, or reprovision them, Opus Interactive decided the best thing to do is to donate them to Omni Media Networks Inc. The donated servers were needed in an effort to expand Omni Media Networks Internet outreach programs. Opus Interactive is very [...]
July 1st, 2008
If a tree gets planted in the forest will anyone hear?
Opus Interactive has joined with Arbor Day Foundation in their mission to “…inspire people to plant, nurture and celebrate trees.” Arbor Day Foundation is the largest nonprofit tree-planting organization, with nearly one million members and averages over 12 million trees planted each year.
So with that, the question becomes with almost 12 million trees each year, why [...]
June 16th, 2008
Protecting the minds and hearts of our children with OpenDNS
There is no argument that there is a lot of crap on the Internet. And I am not referring to poorly designed web sites, time wasting games and an overabundance of news about absolutely everything. The deep, dark alleys of the Internet (and sometimes not all that far removed) are filled with pornography, crime, drugs, [...]
June 9th, 2008
Interop Las Vegas 08 Photo Journal
Interop Las Vegas 08 . The adventures over the course of 5 days. Below you will see somethings you wish you didn’t and other you are glad to see. Enjoy.
Arrived at the MGM Grand Hotel Checked in Room #4136. Look at that view.
Well what would Vegas be like without a little gambling? Eric at his first slot [...]
May 22nd, 2008
Smokeping on FreeBSD 7
This write-up assumes a working copy of FreeBSD 7.0. It was built using 7.0-RELEASE. It should work on FreeBSD 6.x-STABLE and future versions of FreeBSD 7. The package versions listed were current as of this writing but may have been updated by the time someone uses this howto.
This is a basic setup of Smokeping. There [...]
April 24th, 2008
Installing MySQL4 and MySQL5 on a single FreeBSD 6.2 Server.
This write-up makes the following assumptions:
Working copy of FreeBSD 6.2.
Build: 6.2-RELEASE.
Which should work on 6.2-STABLE and 7.0 as well.
Please let me know if you run into typos or other technical issues when implementing this.
Download the latest binaries from mysql.com.
At write-up time this was:
mysql-5.0.45-freebsd6.0-i386.tar.gz
mysql-standard-4.1.22-unknown-freebsd6.0-i386.tar.gz
Install MySQL 4.
Uncompress the binary source.
# cd /usr/local
# gunzip < [...]
March 11th, 2008
Article Comments: