(Edited by Andy "Monomaniac" Mallett with collaborative assistance from Chris "Relentless" Riley, Tim "Gleek" Gee and his faithful sidekick, Adam "Silent-but-deadly" Smith.)
No matter what you do with your computer, once it's on a network - especially The Big One - some wanker's gonna try and screw with it sooner or later.
There aren't too many Unix viruses at the moment, but there are plenty of knob-heads out there with nothing better to do than to try and hack your system.
This is why we have firewalls and yes, even Unix needs 'em. One of the good things about FreeBSD's firewalling system is that you have to configure the access rules yourself. Manually. Which means you get to learn about security and services and ports and well, stuff you need to know as a Network Admin.
Prerequisites
The following assumes you have a working
ipnat gateway - see
Building a Gateway/Firewall for instructions. Note that it is not necessary to recompile the FreeBSD 6.2 kernel for firewall functionality.
Network Layout
1. Gateway Interfaces
The following instructions assume the external interface is
rl0 and the internal LAN-facing interface is
fxp0. Yours is likely to be different, so modify these instructions accordingly.
2. IP Addresses
The following instructions assume the external interface has an IP Address of 10.147.86.63 and the internal LAN-facing interface has an IP Address of 192.168.0.13. Yours is likely to be different, so again, modify these instructions accordingly.
Introduction
The basic firewall setup is a reasonably quick and straightforward 3-step process which involves making modifications to your existing
rc.conf and
ipnat.rules files, as well as the addition of an
ipf.rules file for the firewall instructions. Most of the time and effort will involve tweaking the firewall (and gateway) rules, once it's all up and running.
1. Edit rc.conf
Add the following options to
rc.conf..
vi /etc/rc.conf
#ip filter firewall and monitoring
ipfilter_enable="YES"
ipfilter_rules="/etc/ipf.rules"
ipmon_enable="YES"
#network address translation
gateway_enable="YES"
ipnat_enable="YES"
ipnat_rules="/etc/ipnat.rules"
ipmon_flags="-Ds"
Save and close
rc.conf. Note that the system will need to be rebooted before these settings take effect.
2. Edit ipnat.rules
Add the following options to
ipnat.rules..
vi /etc/ipnat.rules
#Don't change the order of the following rules
#These two lines deal with FTP and passive mode..
map rl0 192.168.0.0/24 -> 0/32 proxy port 21 ftp/tcp
map rl0 0.0.0.0/0 -> 0/32 proxy port 21 ftp/tcp
#Allow everything out..
map rl0 192.168.0.0/24 -> 0/32 portmap tcp/udp auto
Save and close
ipnat.rules
After modifying the file, reload the
ipnat.rules with the following command..
ipnat -CF -f /etc/ipnat.rules
2a. Create a Flush Script for the Gateway Rules
If you're gonna be playing with the
ipnat.rules a lot, why not create a flush script to perform the above task without having to type it out all the time..
vi /bin/fgw
The script contains just the one line..
ipnat -CF -f /etc/ipnat.rules
Save and exit the editor and make the file executable..
chmod 755 /bin/fgw
Now all you need to do is type
fgw (Flush GateWay) to flush and reload the gateway rules after you have modified them. The script has been put inside
/bin because this directory is in the system path (type
set to see this) which means it can be run from anywhere in the directory tree.
3. Edit ipf.rules
Create the following
ipf.rules file which will define the firewall rule set..
vi /etc/ipf.rules
# pass all internal packets
pass out quick on fxp0 all
pass in quick on fxp0 all
# all internal loopback interfaces
pass out quick on lo0 all
pass in quick on lo0 all
#allow dns requests
pass out quick on rl0 proto tcp from any to any port = 53 flags S keep state
pass out quick on rl0 proto udp from any to any port = 53 keep state
# allow icmp
pass out quick on rl0 proto icmp from any to any icmp-type 8 keep state
# allow ftp
pass out quick on rl0 proto tcp from any to any port = 21 flags S keep state
pass in quick on rl0 proto tcp from any to any port = 20 flags S keep state
#allow http and secure http
pass out quick on rl0 proto tcp from any to any port = 80 flags S keep state
pass out quick on rl0 proto tcp from any to any port = 8080 flags S keep state
pass out quick on rl0 proto tcp from any to any port = 443 flags S keep state
# allow smtp and pop3
pass out quick on rl0 proto tcp from any to any port = 25 flags S keep state
pass out quick on rl0 proto tcp from any to any port = 110 flags S keep state
#allow ssh out
pass out quick on rl0 proto tcp from any to any port = 22 flags S keep state
pass in quick on rl0 proto tcp from any to any port = 22 flags S keep state
#lock down public interface; allow only established and related packets;
# allow in only on request; set to static ip and port
#block incoming private addresses
#block in quick on rl0 from 192.168.0.0/16 to any
#block in quick on rl0 from 172.16.0.0/12 to any
#block in quick on rl0 from 10.0.0.0/8 to any
block in quick on rl0 from 127.0.0.0/8 to any
block in quick on rl0 from 169.254.0.0/8 to any
block in quick on rl0 from 204.152.64.0/23 to any
block in quick on rl0 from 224.0.0.0/3 to any
#block in quick on rl0 from 0.0.0.0/8 to any
#block all else open as requested by ip and protocol
block out log first quick on rl0 all
Save and close
ipf.rules
After modifying thew file, load the
ipnat.rules with the following command..
ipf -FA -v -f /etc/ipf.rules
3a. Create a Flush Script for the Firewall Rules
If you're gonna be playing with the
ipf.rules a lot, why not create another flush script to perform the above task without having to type it out all the time..
vi /bin/ffw
Again, the script contains just the one line..
ipf -FA -v -f /etc/ipf.rules
Save and exit the editor and make the file executable..
chmod 755 /bin/ffw
Now all you need to do is type
ffw (Flush FireWall) to flush and reload the firewall rules after you have modified them. The script has been put inside
/bin because this directory is in the system path (type
set to see this) which means it can be run from anywhere in the directory tree.
What does it all mean?
The subject of firewalling and network security is a speciality in its own right and way beyond the scope of this article. The reader is urged to experiment and seek out further information on optimising these firewall rules. Note that this is certainly not an exhaustive ruleset, it is just an example to get the beginner started. You will need to tailor this ruleset to your own specific needs and then test it works properly.
Do not assume your firewall is secure or complete until you have become familiar with how the rulesets work.
It is always good practice to include hashed out explanations in all your custom scripts. This not only helps others to understand what you've done, but it also serves as a reminder after you return to one of your own scripts, after many moons of absence. From the above examples, the explanations should help to indicate what most of the rules are doing.
References and Further Reading
Recommended:
IPF and IPNAT Explained (.txt file)
http://www.enderunix.org/docs/en/freebsd61/06.08-NAT_Explanation.htm
http://www.schlacter.net/public/FreeBSD-STABLE_and_IPFILTER.html
http://www.mostgraveconcern.com/freebsd/ipfw.html
http://inc2.com/isba/080-compilation-installation.html
https://neon1.net/misc/firewall.html
http://www.obfuscation.org/ipf
http://www.instructables.com/id/EN69P8RZ28EP2871BW
- A.