Introduction to IPFilter for FreeBSDA guide to protecting a stand-alone systemby Mark FosterMarch 7th, 2003 Welcome! This guide is intended to help you get better protection from the unruly Internet for your FreeBSD system. Computer systems that are directly connected to the Internet, meaning they have a publicly reachable IP address and possibly a published DNS hostname, are sitting ducks without some sort of protection. Another common situation is having a server sitting in a DMZ with little or no protection. As time marches on, the operating system and software running on top of it become more and more likely to be susceptible to known exploits. In other words, the system becomes more and more likely to be infiltrated the longer it goes unprotected. There are a couple of ways to combat this inevitable degradation in system security. These are generally NOT mutually exclusive, either.
This article focuses on IPFilter, which returns plenty of bang for the buck in terms of protecting your FreeBSD system. It is a TCP/IP port filter with NAT capabilities, stateful-ness(sp) and logging. I have been using IPFilter for over two years to protect about 15-30 servers, including my home network. It can also be using with bridging, but not on FreeBSD, just OpenBSD, which now uses pf in place of IPFilter (learn more).. PrerequisitesFreeBSD 4.8 RELEASE secure branch, but stable or current is fine.Customize your kernelTo use IPFilter you will need to rebuild your kernel. In most cases the FreeBSD system is installed with a GENERIC kernel which does not include the IPFILTER capability. Don't be afraid! Rebuilding your kernel is not as daunting as it sounds. Here is what to do, logged in as root.
Compile and Install the new KernelNow you are going to recompile and install your new kernel MYKERNEL. Perform these steps, again as root. cd /usr/src make buildkernel KERNCONF=MYKERNEL You will now observe gobs of output the the compile does it's thing. make installkernel KERNCONF=MYKERNEL reboot Upon reboot, monitor the screen output. You should see your new kernel boot, and you should see a line similar to this...
IP Filter: v3.4.29 initialized. Default = pass all, Logging = enabled
Congratulations! You have completely replaced your kernel and are ready to configure IPFilter for your needs. There are no cookie-cutter rules to this, but we can use a real world example to get you going. Define your filter rules based on your requirements
Let's say you are setting up an e-mail server for a friend. He wants it to be able to send and receive e-mail for his family and friends. So this server needs to allow incoming connections to port 25 (SMTP). It also needs to allow outbound connections to other mail servers. Both of these activities will require DNS traffic to pass, but we only want this traffic to be exchanged with our locally configured name servers (eg. whatever is in Furthermore, the mailboxes on the server will need to be accessed from arbitrary Internet addresses - preferably using SSL enabled IMAP(port 993) or POP3 (port 995) [3]. You will also want SSH access to the server from another location (eg. 216.70.142.13) for administrative purposes.
Here is the contents of our rule set, which would live in
# Default Deny block in log on dc0 from any to any # Malicious packets - drop 'em block in log quick on dc0 proto icmp from any to any icmp-type redir block in log quick on dc0 proto tcp/udp all with short # Block and log any packets claiming to originate from suspicious origins # RFC 1918 block in log quick on dc0 from 192.168.0.0/16 to any block in log quick on dc0 from 10.0.0.0/8 to any block in log quick on dc0 from 172.16.0.0/12 to any # Class D: multicast addresses. block in log quick on dc0 from 224.0.0.0/3 to any # Class E: reserved for future use. block in log quick on dc0 from 241.0.0.0/4 to any # localhost should be using the lo0 interface block in log quick on dc0 from localhost to any block in log quick on dc0 from 0.0.0.0/32 to any block in log quick on dc0 from 255.255.255.255/32 to any # Here's the TCP traffic I want to allow in pass in quick on dc0 proto tcp from any to any port = smtp keep state pass in quick on dc0 proto tcp from any to any port = imaps keep state pass in quick on dc0 proto tcp from any to any port = pop3s keep state pass in quick on dc0 proto tcp from 216.70.142.13 to any port = ssh keep state # Default deny on outbound block out log on dc0 from any to any # Allow outbound mail delivery pass out quick on dc0 proto tcp/udp from any to any port = smtp keep state # Allow outbound DNS queries and inbound replies pass out quick on dc0 proto tcp/udp from any to 216.149.21.2 port = 53 keep state pass out quick on dc0 proto tcp/udp from any to 216.149.21.3 port = 53 keep state
Now certainly everyone's situation will be different. A good way to determine what to allow through with your filters is the
Activate the rule setNow you can activate the rules using ipf -F a -f /etc/ipf.rules If all goes well there will be no noticeable change. Have a look at monitoring and reporting to see what's happening behind the scenes.
In all likelihood, you will want IPFilter to start upon (re)boot, which means you'll need to add the entries to ipfilter_enable="YES" # Set to YES to enable ipfilter functionality ipfilter_program="/sbin/ipf" ipfilter_rules="/etc/ipf.rules" # rules definition file for ipfilter, see ipmon_enable="YES" # Set to YES for ipmon; needs ipfilter, too! ipmon_program="/sbin/ipmon" # where the ipfilter monitor program lives ipmon_flags="-oI -D /var/log/ipflog" # typically "-Ds" or "-D /var/log/ipflog"
An easy way to do this is to run
MonitoringThere are a couple of other commands will be useful in checking on the status of your filter rules.
ReportingThere are at least a couple of reporting tools out there that will analyze the IPFilter log created by ipmon. These are described in more detail below. plogplog is a Perl script that produces plain text activity reports fromipmon's log. This is the program which I use myself by emailing the output of a nightly cronjob. Here is a sample of it's output: [5]~ mdf@c7613176-a>/home/mdf/scripts/plog.pl -AF block,log & /var/log/ipflog ### ### Traffic by destination address: ### c7613176-a [12.132.123.xxx] dc0 block 2 tcp ms-sql-s <- 12-210-22-175.client.attbi.com.<high> (S) dc0 block 3 tcp microsoft-ds <- h24-87-217-240.ed.shawcable.net.<high> (S) dc0 block 1 udp loc-srv <- 61.181.211.21.<high> dc0 block 2 tcp ftp <- 61-221-116-236.HINET-IP.hinet.net.<high> (S) dc0 block 3 icmp ? <- 63-216-14-194.sdsl.cais.net dc0 block 3 icmp ? <- vdslp240.phnx.uswest.net dc0 block 3 icmp ? <- 64.158.79.2 dc0 block 1 icmp ? <- 65.211.112.6 dc0 block 2 tcp <high> <- vrp1.lax.xpc-mii.net.http (A,AR) dc0 block 3 icmp ? <- 66.28.47.162 dc0 block 1 tcp microsoft-ds <- 66.237.35.195.<high> (S) dc0 block 1 udp ms-sql-m <- 208.158.2.79.<high> dc0 block 1 udp ms-sql-m <- 209.61.228.7.<high> dc0 block 3 tcp microsoft-ds <- 196.c58.ethome.net.tw.<high> (S) dc0 block 3 icmp ? <- 211.169.245.98 dc0 block 7 tcp <high> <- vrp1.lax.xpc-mii.net.http (A) 255.255.255.255 [255.255.255.255] dc0 block 780 udp bootpc <- 10.132.128.1.bootps ### ### Traffic by source address: ### 10.132.128.1 [10.132.128.1] dc0 block 780 udp bootps -> 255.255.255.255.bootpc 12-210-22-175.client.attbi.com [12.210.22.175] dc0 block 2 tcp <high> -> c7613176-a.ms-sql-s (S) h24-87-217-240.ed.shawcable.net [24.87.217.240] dc0 block 3 tcp <high> -> c7613176-a.microsoft-ds (S) 61.181.211.21 [61.181.211.21] dc0 block 1 udp <high> -> c7613176-a.loc-srv 61-221-116-236.HINET-IP.hinet.net [61.221.116.236] dc0 block 2 tcp <high> -> c7613176-a.ftp (S) 63-216-14-194.sdsl.cais.net [63.216.14.194] dc0 block 3 icmp ? -> c7613176-a vdslp240.phnx.uswest.net [63.227.249.240] dc0 block 3 icmp ? -> c7613176-a 64.158.79.2 [64.158.79.2] dc0 block 3 icmp ? -> c7613176-a 65.211.112.6 [65.211.112.6] dc0 block 1 icmp ? -> c7613176-a vrp1.lax.xpc-mii.net [65.216.116.114] dc0 block 2 tcp http -> c7613176-a.<high> (A,AR) 66.28.47.162 [66.28.47.162] dc0 block 3 icmp ? -> c7613176-a 66.237.35.195 [66.237.35.195] dc0 block 1 tcp <high> -> c7613176-a.microsoft-ds (S) 208.158.2.79 [208.158.2.79] dc0 block 1 udp <high> -> c7613176-a.ms-sql-m 209.61.228.7 [209.61.228.7] dc0 block 1 udp <high> -> c7613176-a.ms-sql-m 196.c58.ethome.net.tw [210.58.58.196] dc0 block 3 tcp <high> -> c7613176-a.microsoft-ds (S) 211.169.245.98 [211.169.245.98] dc0 block 3 icmp ? -> c7613176-a dsl231-038-184.sea1.dsl.speakeasy.net [216.231.38.184] dc0 block 4 tcp <high> -> c7613176-a.auth (S) fwanalogThis reporting tool converts the ipmon log into something analog can read. The reports look very nice (and familiar!) as shown here. Click on over to http://tud.at/programm/fwanalog/ for more information. You can install this from the ports directory /usr/ports/security/fwanalog. ResourcesYou may find additional help in installing or configuring IPFilter at:
Footnotes & References
Thanks to Brian Hatch and Dan Ebert for their contributions to this article.
If I was helpful, please let me know.
$Id: ipfilter.html,v 1.4 2005/11/12 16:36:00 mdf Exp $
|
|
|