Installing IPF Firewall
Set some firewall rules to protect your Unix box (FreeBSD 6.2)
Posted 11.11.2005 | Updated 31.05.2007 | Edited by Andy "Monomaniac" Mallett with collaborative assistance from Chris "Relentless" Riley, Tim "Gleek" Gee and his faithful sidekick, Adam "Silent-but-deadly" Smith.

These instructions are still under development, pending testing by my highly dependable Guinea Pigs IT students..

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.
These instructions comprise a complete reworking of the previous IPFW firewalling article, which is now defunct.

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.




Network Layout

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 & C