Setting up a BSD Firewall.
By Gerry Patterson
A couple of years ago I installed a BSD Firewall. Recently I had to
rebuild the firewall after a hardware failure.
So this time, I documented the process and this article is the result.
Understanding How it Works.
- Compiling the kernel:
Unless you have already compliled firewalls into your kernel, you will have to rebuild it. Put the official FreeBSD CDROM in the hardrive and enter the following commands:
# mount /cdrom # mkdir -p /usr/src/sys # ln -s /usr/src/sys /sys # cat /cdrom/src/ssys.[a-d]* | tar -xzvf - # cat /cdrom/src/sbase.[a-d]* | tar -xzvf - # cd /usr/src/sys/i386/conf # cp GENERIC CUSTOM # cd /usr/src/sys/i386/conf # mkdir /root/kernels # cp GENERIC /root/kernels/CUSTOM # ln -s /root/kernels/CUSTOM
Now, edit CUSTOM with vi. Add these options to the end of the file
options IPFIREWALL options IPFIREWALL_DEFAULT_TO_ACCEPT options IPFIREWALL_VERBOSE options IPDIVERT
Run these commands:
# ln -s /usr/include /usr/src/include # cd /usr/src # make buildkernel KERNCONF=CUSTOM # make installkernel KERNCONF=CUSTOM
- Understand How It Works:
This can be achieved by the following three simple steps:
- After you have installed your new kernel, you will find a new script called rc.firewall. You should read this script carefully and the rc.conf script. Make sure that you understand how these work and the order in which they are called. You should also read and understand the man pages for natd, ipfw, divert, ip, and other related topics.
- Go back and repeat the above step.
- Go back and repeat the above step.
You now know enough to install and configure your firewall. You no longer need to read any of this.
My own Firewall Recipe.
Ok, if you are still reading, you have decided to take a cookbook approach. Hope you like my recipe. Good Luck!
- Edit the /etc/rc.conf script and add the following lines:
named_enable="YES" ifconfig_rl0="inet 192.168.1.1 netmask 255.255.255.0" ifconfig_rl1="inet 203.213.17.11 netmask 255.255.255.248" ifconfig_rl1_alias0="inet 203.213.17.10 netmask 255.255.255.255" ifconfig_rl1_alias1="inet 203.213.17.12 netmask 255.255.255.255" defaultrouter="203.213.17.9" hostname="pgts01.pgts.com.au" portmap_enable="YES" gateway_enable="YES" natd_enable="YES" natd_interface="rl1" natd_flags="-f /etc/natd.conf" firewall_enable="YES" firewall_type="PGTS"
- create the script /etc/natd.conf containing the following:
redirect_port tcp 192.168.1.3:80 203.213.17.10:80 redirect_port tcp 192.168.1.12:80 203.213.17.12:80 redirect_port tcp 192.168.1.11:25 203.213.17.11:25
- Add the following lines to the rc.firewall script (substituting values
appropriate for your local setup):
PGTS) ############ # This has been copied from the "simple" firewall entry in the # original rc.firewall script (GWP - 2007-07-22) ############ # set these to your outside interface network and netmask and ip oif="rl1" onet="203.213.17.8" omask="255.255.255.248" oip="203.213.17.11" # set these to your inside interface network and netmask and ip iif="rl0" inet="192.1.1.0" imask="255.255.255.0" iip="192.1.1.1" # set these special addresses for PGTS ihtm1="192.168.1.3" ihtm2="192.168.1.12" ohtm1="203.213.17.10" ohtm2="203.213.17.12" imail="192.168.1.11" omail="203.213.17.11" # Stop spoofing ${fwcmd} add deny all from ${inet}:${imask} to any in via ${oif} ${fwcmd} add deny all from ${onet}:${omask} to any in via ${iif} # Stop RFC1918 nets on the outside interface ${fwcmd} add deny all from any to 10.0.0.0/8 via ${oif} ${fwcmd} add deny all from any to 172.16.0.0/12 via ${oif} ${fwcmd} add deny all from any to 192.168.0.0/16 via ${oif} # Stop draft-manning-dsua-03.txt (1 May 2000) nets (includes RESERVED-1, # DHCP auto-configuration, NET-TEST, MULTICAST (class D), and class E) # on the outside interface ${fwcmd} add deny all from any to 0.0.0.0/8 via ${oif} ${fwcmd} add deny all from any to 169.254.0.0/16 via ${oif} ${fwcmd} add deny all from any to 192.0.2.0/24 via ${oif} ${fwcmd} add deny all from any to 224.0.0.0/4 via ${oif} ${fwcmd} add deny all from any to 240.0.0.0/4 via ${oif} # Network Address Translation. This rule is placed here deliberately # so that it does not interfere with the surrounding address-checking # rules. If for example one of your internal LAN machines had its IP # address set to 192.0.2.1 then an incoming packet for it after being # translated by natd(8) would match the `deny' rule above. Similarly # an outgoing packet originated from it before being translated would # match the `deny' rule below. # always run this (GWP 2007-07-22) ${fwcmd} add divert natd all from any to any via ${oif} # Stop RFC1918 nets on the outside interface ${fwcmd} add deny all from 10.0.0.0/8 to any via ${oif} ${fwcmd} add deny all from 172.16.0.0/12 to any via ${oif} ${fwcmd} add deny all from 192.168.0.0/16 to any via ${oif} # Stop draft-manning-dsua-03.txt (1 May 2000) nets (includes RESERVED-1, # DHCP auto-configuration, NET-TEST, MULTICAST (class D), and class E) # on the outside interface ${fwcmd} add deny all from 0.0.0.0/8 to any via ${oif} ${fwcmd} add deny all from 169.254.0.0/16 to any via ${oif} ${fwcmd} add deny all from 192.0.2.0/24 to any via ${oif} ${fwcmd} add deny all from 224.0.0.0/4 to any via ${oif} ${fwcmd} add deny all from 240.0.0.0/4 to any via ${oif} # Allow TCP through if setup succeeded ${fwcmd} add pass tcp from any to any established # Allow IP fragments to pass through ${fwcmd} add pass all from any to any frag # Allow setup of incoming email ${fwcmd} add pass tcp from any to ${imail} 25 setup # Allow access to our DNS ${fwcmd} add pass tcp from any to ${oip} 53 setup ${fwcmd} add pass udp from any to ${oip} 53 ${fwcmd} add pass udp from ${oip} 53 to any # Allow access to our WWW ${fwcmd} add pass tcp from any to ${ihtm1} 80 setup ${fwcmd} add pass tcp from any to ${ihtm2} 80 setup # Reject&Log all setup of incoming connections from the outside ${fwcmd} add deny log tcp from any to any in via ${oif} setup # Allow setup of any other TCP connection ${fwcmd} add pass tcp from any to any setup # Allow DNS queries out in the world ${fwcmd} add pass udp from ${oip} to any 53 keep-state # Allow NTP queries out in the world ${fwcmd} add pass udp from ${oip} to any 123 keep-state # Everything else is denied by default, unless the # IPFIREWALL_DEFAULT_TO_ACCEPT option is set in your kernel # config file. ;;
Test your firewall. If it doesn't work you need to go back the step marked Understand How It Works
BIBLIOGRAPHY:
There are many links on building BSD firewalls. I found the following helpful.
Managing an IP address change. How to change the IP address of NIC in FreeBSD. This article also gives details of how to uses aliases on a single NIC.
IP Aliasing More details about IP aliasing.
Configuring the FreeBSD Kernel. Detailed steps of how to build a custom kernel in FreeBSD.