IPFILTER (IPF) Firewall
IPFILTER (IPF) Firewall
The author of IPFILTER is Darren Reed. IPFILTER is not FBSD operating system dependant. IPFILTER is an open source application and has been ported to FreeBSD, NetBSD, OpenBSD, Sun, HP, and Solaris operating systems. IPFILTER is actively being supported and maintained, with updated versions being released regularly.
The IPFILTER program runs in the kernel and consists of the firewall and separate NAT facilities. IPFILTER also has user-land front-end interactive interfaces for controlling the firewall rules, NAT, packet accounting, and the logging facility. Program IPF is used to load the firewall rules. Program IPNAT is used to load the firewall NAT rules. Program IPFSTAT reports on packet filter statistics and lists active rules sets. Program IPMON monitors IPFILTER for logged packets.
From this point on IPFILTER will be written as IPF and is intended to mean the same thing as IPFILTER.
IPF was originally written using a rules processing logic of ‘the last matching rule wins’ and used only stateless types of rules. Over time IPF has been enhanced to include a ‘quick’ option and a stateful ‘keep state’ option which drastically modernized the rules processing logic. IPF’s official documentation covers the legacy rule coding parameters and the legacy rule file processing logic, the modernized functions are only included as additional options, completely understating their benefits in producing a far superior secure firewall.
The instructions contained in this guide are based on using rules that contain the ‘quick' option and the stateful ‘keep state’ option. This is the basic framework for coding an inclusive firewall rule set.
An inclusive firewall only allows services matching the rules through. This way you can control what services can originate behind the firewall destined for the public internet and also control the services which can originate from the public internet accessing your private network. Everything else is blocked and logged by default design. Inclusive firewall rule sets are much more secure than exclusive firewall rule sets and are the only rule set type covered herein.
For detailed explanation of the legacy rules processing method, see http://www.obfuscation.org/ipf/ipf-howto.html#TOC_1
To see the FAQ: http://www.phildev.net/ipf/index.html
To search the open source IPFilter questions archives: http://marc.theaimsgroup.com/?l=ipfilter
Since all firewalls are based on interrogating the values of selected packet control fields, the creator of the firewall rules must have an understanding of how TCP/IP works, what the different values in the packet control fields are and how these values are used in a normal session conversation. For a good explanation go to http://www.ipprimer.com/overview.cfm
IPF is included in the basic FBSD install as a separate run time loadable module. IPF will dynamically load its kernel loadable module when the rc.conf statement ipfilter_enable="YES" is used. The loadable module was created with logging enabled and the ‘default pass all’ options. You do not need to compile IPF into the FBSD kernel just to change the default to ‘block all’; you can do that by just coding a block all rule at the end of your rule set.
Using the IPF run time loadable module is recommended.
It is not a mandatory requirement that you enable IPF by compiling the following options into the FBSD kernel. It’s only presented here as background information. Compiling IPF into the kernel causes the loadable module to never be used.
Sample kernel source IPF options statements are in the /usr/src/sys/i386/conf/LINT kernel source and are reproduced here.
options IPFILTER options IPFILTER_LOG options IPFILTER_DEFAULT_BLOCK
IPFILTER This tells the compile to include IPFILTER as part of it’s core kernel.
IPFILTER_LOG enables the option to have IPF log traffic by writing to the ipl packet logging pseudo-device for every rule that has the "log" keyword.
IPFILTER_DEFAULT_BLOCK This option changes the default behavior so any packet not matching a firewall ‘pass’ rule gets blocked.
To build a custom kernel see the Kernel Customizing section.
You need the follow statements in /etc/rc.conf to activate IPF at boot time.
ipfilter_enable="YES" # Start ipf firewall ipfilter_rules="/etc/ipf.rules" # loads rules definition text file
# IE: not script file with rules in it
ipmon_enable="YES" # Start IP monitor log ipmon_flags="-Ds" # D = start as daemon
# s = log to syslog # v = log tcp window, ack, seq # n = map IP & port to names
If you have a LAN behind this firewall that uses the reserved private IP address ranges, then you need to add the following to enable NAT functionality.
gateway_enable="YES" # Enable as LAN gateway ipnat_enable="YES" # Start ipnat function ipnat_rules="/etc/ipnat.rules" # rules definition file for ipnat
The ipf command is used to load your rules file. Normally you create a file containing your custom rules and use this command to replace in mass the currently running firewall internal rules.
ipf –Fa –f /etc/ipf.rules
-Fa means flush all internal rules tables
-f means this is the file to read for the rules to load
This gives the user the ability to make changes to their custom rules file and run the above IPF command, thus updating the running firewall with a fresh copy of all the rules without having to reboot the system. This method is very convenient for testing new rules as the procedure can be executed as many times as needed.
See man IPF(8) for details on the other flag options available with this command.
The ipf command expects the rules file to be a standard text file. It will not accept a rules file written as a script with symbolic substitution.
There is a way to build IPF rules that utilities the power of script symbolic substitution. See the Building Rule Script section.
The default behavior of ipfstat is to retrieve and display the totals of the accumulated statistics gathered as a result of applying the user coded rules against packets going in and out of the firewall since it was last started or since the last time the accumulators were reset to zero by the ipf –Z command.
See ‘man ipfstat’ for details.
This is what the ipfstat command displays without any flags:
input packets: blocked 99286 passed 1255609 nomatch 14686 counted 0 output packets: blocked 4200 passed 1284345 nomatch 14687 counted 0 input packets logged: blocked 99286 passed 0 output packets logged: blocked 0 passed 0 packets logged: input 0 output 0 log failures: input 3898 output 0 fragment state(in): kept 0 lost 0 fragment state(out): kept 0 lost 0 packet state(in): kept 169364 lost 0 packet state(out): kept 431395 lost 0 ICMP replies: 0 TCP RSTs sent: 0 Result cache hits(in): 1215208 (out): 1098963 IN Pullups succeeded: 2 failed: 0 OUT Pullups succeeded: 0 failed: 0 Fastroute successes: 0 failures: 0 TCP cksum fails(in): 0 (out): 0 Packet log flags set: (0)
When supplied with either -i for inbound or –o for outbound, it will retrieve and display the appropriate list of filter rules currently installed and in use by the kernel.
Ipfstat –in displays the inbound internal rules table with rule numbers
Ipfstat –on displays the outbound internal rules table with rule numbers
Rules will be displayed like this:
@1 pass out on xl0 from any to any @2 block out on dc0 from any to any @3 pass out quick on dc0 proto tcp/udp from any to any keep state
Ipfstat –ih displays the inbound internal rules table, each rule prefixed with count of times the rule was matched
Ipfstat –oh displays the outbound internal rules table, each rule prefixed with count of times the rule was matched
Rules will be displayed like this:
2451423 pass out on xl0 from any to any
354727 block out on dc0 from any to any 430918 pass out quick on dc0 proto tcp/udp from any to any keep state
Ipfstat –t [ -C | -D | -P | -S | -T ]
The most important function of the ipfstat command is the –t flag which activates the display state table in a way similar to the way the ‘top’ command shows the FBSD running process table. When your firewall is under attack this function gives you the ability to identify, drill down to, and see the attacking packets. The optional sub-flags give the ability to select destination IP and port, or source IP and port, or protocol that you want to monitor in real time. See man ipfstat for details.