From: Georg Wagner http://www.free-x.ch/pub/ipf-conf-en.html
Subject: Настройка IPFilter под FreeeBSD (eng)
Configuration of ipfilter on FreeBSD
http://www.free-x.ch/pub/ipf-conf-en.html
Georg Wagner
1 Introduction
ipfilter is a small but efficient firewall package. It does everything
done by other firewalls and even more. It's also a very portable
package. FreeBSD versions above 3.3.3 have it already integrated and
you only have to activate it via the kernel configuration. In earlier
versions of FreeBSD you have to patch the kernel.
2 Installation
2.1 FreeBSD before version 3.3.3
If you are using a FreeBSD version above 3.3.3 you can skip this
section.
ipfilter does not exist as package or port in the BSD meaning.
Therefore you have to download the tarball first. You can get it here:
http://packetstorm.securify.com/UNIX/firewall/ipfilter/ip-fil3.2.10.tar.gz
After uncompressing you will find installation instructions in a file
named INST.FreeBSD-2.2 in the directory ip-fil3.2.10. For the
3.x-releases of FreeBSD the file INST.FreeBSD is relevant.
ipfilter can be installed in two different ways:
1. directly in the kernel or
2. as Loadable Kernel Module (LKM)
Both ways are described in the above mentioned files. The entry
options IPFILTER will be written into the kernel configuration file by
the installation script.
2.2 FreeBSD above 3.3.3
You only have to add the entry options IPFILTER to the kernel
configuration file, after the line containing options INET.
2.3 All FreeBSD versions
In order to get logging information I have added the entry options
IPFILTER_LOG to the kernel configuration.
After the installation you have either to load the LKM or your machine
has to be rebooted.
2.4 Loading the filter rules via rc.network
Since I wanted to load the filter rules during the startup of my
FreeBSD server I applied several changes to the files rc.conf and
rc.network:
Changes in rc.conf
In rc.conf these lines were added:
ipfilter=YES; # NO to switch off
ipfilter_rules=/etc/ipf.rc # file with rules
ipmon_flags=-Ds # NO for no logging
ipnat=YES
ipnat_rules=/etc/ipnat.rc
Changes in rc.network
In the file rc.network I added the following code in the subroutine
network_pass_1() before the configuration of the interfaces:
# Configure the IP filter before configuring network interfaces
if [ X"${ipfilter}" = X"YES" -a -f "${ipfilter_rules}" ]; then
echo ``configuring IP filter''
echo ``ipf -Fa -f ${ipfilter_rules} -E''
ipf -Fa -f ${ipfilter_rules} -E
else
ipfilter=NO
fi
...
In the subroutine network_pass_2() I added this code after the
configuration of named:
...
# insert after named
if [ X"${ipfilter}" = X"YES" -a X"${ipmon_flags}" != X"NO" ];
then
echo 'starting ipmon';
ipmon ${ipmon_flags}
fi
I also added code for ipnat in network_pass_3() after the original
natd-code:
# CHG-BEGIN: ipnat out of the ipfilter package
# Configure NAT after configuring network interfaces
if [ "X${ipnat}" = X"YES" -a "X${ipfilter}" = X"YES" ]; then
if [ -f "${ipnat_rules}" ]; then
echo 'configuring NAT'
ipnat -CF -f ${ipnat_rules}
else
echo 'ipnat: file ${ipnat_rules} not found.'
fi
else
echo 'no network adress translation.'
ipnat=NO
fi
# CHG-END: ipnat out of the ipfilter package
In order to get some basic filter rules I executed the command:
# mkfilters > /etc/ipf.rc
which resulted in the following rules:
#
block in log quick from any with ipopts
block in log quick proto tcp from any to any with short
pass out on ed1 all head 150
block out from 127.0.0.0/8 to any group 150
block out from any to 127.0.0.0/8 group 150
block out from any to 192.168.1.110/32 group 150
pass in on ed1 all head 100
block in from 127.0.0.0/8 to any group 100
block in from 192.168.1.110/32 to any group 100
block in from 192.168.0.1/0xffffff00 to any group 100
pass out on fxp0 all head 250
block out from 127.0.0.0/8 to any group 250
block out from any to 127.0.0.0/8 group 250
block out from any to 192.168.0.1/32 group 250
pass in on fxp0 all head 200
block in from 127.0.0.0/8 to any group 200
block in from 192.168.0.1 to any group 200
block in from 192.168.1.110/0xffffff00 to any group 200
3 Creating filter rules
3.1 Preconditions
On my machine I use the interface fxp0 for the internal network. The
internal network is a class C network in the range of 192.168.0.x with
a netmask of 255.255.255.0. The external network - the internet - is
connected via an ISDN-router. This router does a dialup when it
receives packages destined for the internet. It also does network
address translation. My FreeBSD server is connected to this
ISDN-router via the interface ed1 with the ip-address 192.168.1.110.
The ISDN-router has the internal ip-adress 192.168.1.111, which will
be translated in the router to the adress dynamically assigned by the
provider during a dialup. I use ipnat, which belongs to ipfilter, to
redirect pakets destined for the outside to the external interface. In
this configuration network address translation happens twice; first on
the server and then in the router.
3.2 How to configure ipnat ?
For ipnat I created the file /etc/ipnat.rc containing the following
lines:
Having clarified the preconditions the question remains, what do I
want to filter? Basically I had to decide which stance I wanted to
take:
Permissive stance: Everything not explicitely forbidden is allowed.
Restrictive stance: Everything not explicitely allowed is
forbidden.
The permissive stance is easily implemented. If you do not give any
rules to ipfilter, it follows exactly this stance. Also the rules
generated by the script mkfilters are based on a slightly enhanced
permissive stance. With this stance you take the risk to allow to
much, what you normally realise when the damage is already done.
The restrictive stance is more secure but is also more difficult to
implement. If you forget something some services may stop to work. On
a network with a lot of user you won't have to wait for a long time to
get complaints.
Dos and don'ts
Before describing the rules I want to give some hints, how to proceed
while generating rules:
* Use groups from the beginning
* Only add rules for one service at a time
* Use the log keyword with all newly added rules, even with permit
(pass) rules.
* After the addition of a rule, do test!
* Test incoming and outgoing traffic.
* Verify that the paket is really caught by the rule you added and
not by another one.
* Make a list of the services you want/have to allow including the
direction of the service, the port and the protocol; for example
outgoing http-traffic, port 80/tcp.
Filter rules for the permissive stance
The basic rules you will get by calling mkfilters (see above). To
these we'll add some rules to catch pakets, which are principally
suspect and to prevent spoofing. The augmented rules for the
permissive stance are:
# augmented rules generated by mkfilters
block in log quick from any with ipopts
block in log quick proto tcp from any to any with short
block in log quick all with opt lsrr
block in log quick all with opt ssrr
#-------------------------------------------------------
# loopback pakets left unmolested
pass in quick on lo0 all
pass out quick on lo0 all
#-------------------------------------------------------
pass out on ed1 all head 150
block out from 127.0.0.0/8 to any group 150
block out from any to 127.0.0.0/8 group 150
block out from any to 192.168.1.110/32 group 150
#-------------------------------------------------------
pass in on ed1 all head 100
block in from 127.0.0.0/8 to any group 100
block in from 192.168.1.110/32 to any group 100
block in from 192.168.0.1/24 to any group 100
#-------------------------------------------------------
pass out on fxp0 all head 250
block out from 127.0.0.0/8 to any group 250
block out from any to 127.0.0.0/8 group 250
block out from any to 192.168.0.1/32 group 250
#-------------------------------------------------------
pass in on fxp0 all head 200
block in from 127.0.0.0/8 to any group 200
block in from 192.168.0.1/32 to any group 200
block in from 192.168.1.110/24 to any group 200
Filter rules for the restrictive stance
* Services to be allowed
First we do trust our internal users, but we prepare to be more
restrictive on the fly.
Before we start to formulate the rules, we select the services we want
- rsp. have - to support. In this list we also mention the service -
not the paket - direction, the port and the protocol.
+ DNS:
We do not want DNS per se, but without DNS nothing will work.
We will allow:
Outgoing DNS on port 53/udp to primary DNS-server of my
provider
Outgoing DNS on port 53/tcp to secondary DNS-server of my
provider
+ http:
We will allow outgoing http-requests on port 80/tcp
+ smtp:
Outgoing smtp on port 25/tcp to be able to send email via
sendmail or postfix[4]2
+ pop3:
Outgoing pop3[5]3 on port 110/tcp to be able to receive email
via fetchmail
+ ftp:
Outgoing ftp on ports 20/tcp/udp
Incoming ftp-data on port 21/tcp/udp[6]4
* Creating the rules
#---------------------------------------------------------------------
-----
# ed1 - external interface
# fxp0 - internal interface
#------------------------------------------------------------------------
# First, nasty pakets which we don't want near us at all
# pakets which are too short to be real except echo replies on lo0
pass in log quick on lo0 proto icmp from 127.0.0.1/8 to 127.0.0.1/8 with short
block in log quick all with short
block in log quick all with opt lsrr
block in log quick all with opt ssrr
#--------------------------------------------------------------
------------
# loopback packets left unmolested
pass in log quick on lo0 all
pass out log quick on lo0 all
#--------------------------------------------------------------
------------
# Group setup:
# 100 incoming ed1
# 150 outgoing ed1
# 200 incoming fxp0
# 250 outgoing fxp0
#--------------------------------------------------------------
------------
block in log body on ed1 all head 100
block out log body on ed1 all head 150
#--------------------------------------------------------------
------------
block in log on fxp0 all head 200
block out log on fxp0 all head 250
#--------------------------------------------------------------
------------
# incoming ed1 traffic - group 100
# 1) prevent localhost spoofing
block in log quick from 127.0.0.1/32 to 192.168.0.0/24 group 100
block in log quick from 127.0.0.1/32 to 192.168.1.0/24 group 100
block in log quick from any to 127.0.0.1/8 group 100
#--------------------------------------------------------------
------------
# 2) deny pakets which should not be seen on th internet (paran oid)
block in log quick from 10.0.0.0/8 to any group 100
block in log quick from any to 10.0.0.0/8 group 100
block in log quick from 172.16.0.0/16 to any group 100
block in log quick from any to 172.16.0.0/16 group 100
block in log quick from 192.168.0.0/16 to any group 100
block in log from any to 192.168.0.0/16 group 100
# 3) implement policy
# allow incoming ftp-data
pass in log quick proto tcp/udp from any to 192.168.1.1/24 keep state group 100
# if nothing applies, block and return icmp-replies (unreachable and rst)
block return-icmp(net-unr) in proto udp from any to any group 100
block return-rst in log proto tcp from any to any group 100
#------------------------------------------------------------------------
# outgoing ed1 traffic - group 150
# Setup outgoing DNS
pass out log quick proto tcp/udp from any to 212.40.0.10 port = 53 keep state group 150
pass out log quick proto tcp/udp from any to 212.40.5.50 port = 53 keep state group 150
# allow outgoing http-service
pass out log quick proto tcp from any to any port = 80 flags S/SA keep state keep frags group 150
# allow outgoing smtp traffic
pass out log quick proto tcp from 192.168.1.1/24 to any port = 25 flags S/SA keep state group 150
# allow outgoing pop3 traffic
pass out log quick proto tcp from 192.168.1.1/24 to any port = 110 flags S/SA keep state group 150
# allow outgoing ftp traffic
pass out log quick proto tcp/udp from 192.168.1.1/24 to any port = ftp keep state group 150
pass out log quick proto icmp from any to any keep state keep frags group 150
#--------------------------------------------------------------------------
# incoming traffic on fxp0 - group 200
#--------------------------------------------------------------------------
# 1) prevent localhost spoofing
block in log quick from 127.0.0.0/8 to any group 200
block in log quick from 192.168.0.1/32 to any group 200
block in log quick from 192.168.1.110/24 to any group 200
pass in log quick from any to any group 200
#--------------------------------------------------------------------------
# outgoing traffic on fxp0 - group 250
#--------------------------------------------------------------------------
block out log quick from 127.0.0.0/8 to any group 250
block out quick from any to 127.0.0.0/8 group 250
block out log quick from any to 192.168.0.1/32 group 250
pass out log quick from any to nay group 250
#--------------------------------------------------------------------------
These rules may serve as a starting point for additional and more
elaborated rules.
4 Conclusion
While starting up the my FreeBSD server is configurated as firewall
using ipfilter. The configuration shown is easily extended.
If you find any errors in this article or if you have any suggestions,
please contact me.
_________________________________________________________________
Footnotes:
I have taken this version because newer versions only support LKM
on a 2.2.x-version of FreeBSD.
In some tutorial about ipfilter it was said, that the way ipfilter
handles keep state is confusing. But if you think in outgoing or
incoming services the rules correspond nicely with the service's
direction. Look at the pass out rules for smtp !
This is outgoing because we - resp. fetchmail - initiate the pop3
paket exchange.
There is a better way doing ftp by using the internal proxy of
ipfilter.
_________________________________________________________________