[ login  ]
Path: Root » FreeBSD » Firewall Explained

FreeBSD Firewall Explained

Howto setup a ipfw stateful firewall on FreeBSD with a simple ruleset and explain certain details, including natd interaction.

Introduction

Why have protection? Computers on the internet run the risk of being damaged or hijacked. Firewall software is a very powerful tool in fighting this. Having FreeBSD firewall software doesn't mean that your safe. You will still have to update your system in order to fix security bugs and check for viruses. Although the later isn't much of a problem for Unix like computers at the time of writing.

The goal of this howto is to setup a simple firewall for FreeBSD and explain certain details of the ipfw firewall, from the user point of view, while doing so. At the end of this howto you will have a firewall for FreeBSD with a simple ruleset. The questions this article will give anwsers to are:

Related howto's

Notes

The newer versions of FreeBSD can load the ipfw firewall software when this is requires. Older versions of FreeBSD don't have this ability and need to have a kernel compiles. You also need to do this with the newer version when you like to create more advanced rules, like logging of traffic shaping.

Summary

  1. The FreeBSD firewall and the natd daemon are loaded by adding the following lines to /etc/rc.conf:
    firewall_enable="YES"
    firewall_quiet="NO"
    firewall_type="/etc/firewall.conf"
    
  2. The configuration file exists out of these rules:
    # check ip packet against state
    add 100 check-state
    
    # allow local traffic
    add 160 allow ip from any to any via lo0 out
    add 1010 allow ip from 192.168.1.0/24 to 192.168.1.0/24 via xl0
    
    # pass packet's comming from internal NIC and us
    add 2000 skipto 2100 ip from any to any via xl0
    add 2000 skipto 2100 ip from 192.168.1.0/24 to any via xl1 out
    add 2000 skipto 2100 ip from any to 192.168.1.0/24 via xl1 in
    add 2000 skipto 2100 ip from 10.0.0.0/24 to any via xl1 in
    add 2000 skipto 2100 ip from any to 10.0.0.0/24 via xl1 out
    
    # deny spoofing
    add 2010 deny ip from 10.0.0.0/8 to any in
    add 2010 deny ip from 127.0.0.0/8 to any in
    add 2010 deny ip from 172.0.0.0/12 to any in
    add 2010 deny ip from 192.0.2.0/24 to any in
    add 2010 deny ip from 192.168.0.0/16 to any in
    add 2020 reject ip from any to 10.0.0.0/8 out
    add 2020 reject ip from any to 127.0.0.0/8 out
    add 2020 reject ip from any to 172.0.0.0/12 out
    add 2020 reject ip from any to 192.0.2.0/24 out
    add 2020 reject ip from any to 192.168.0.0/16 out
    
    # allow traffic on the internal NIC
    add 4980 allow ip from any to any in via xl0
    
    # stateful firewall
    add 4990 allow tcp from any to any out via xl1 setup keep-state
    add 4990 allow udp from any to any out via xl1 keep-state
    add 4990 allow icmp from any to any out via xl1 keep-state
    
    # reject (unreach host) outgoing so we know and don't have to wait
    add 4998 reject ip from any to any out via xl1
    
    # deny incomming for stealth
    add 4999 deny ip from any to any
    

Loading the FreeBSD firewall rules

The first step is about loading the FreeBSD firewall rules. FreeBSD loads the ipfw firewall rules during the boot process. It needs some information in order to load the FreeBSD firewall rules. It looks for that information in /etc/rc.conf. Open it and the following lines.

firewall_enable="YES"
firewall_quiet="NO"
firewall_type="/etc/firewall.conf"

The FreeBSD firewall setup is done during the next boot, if firewall_enabled is true, by loading the firewall rules as indicated by file_type . If firewall_quiet isn't set or is set to NO, then the FreeBSD firewall rules will be printed to the screen duing boot.

Configuring the FreeBSD firewall rules

The ipfw firewall rules need to be written down in /etc/firewall.conf, since the previous section set ipfw up to load this file. This section explains first how the ip packet's are passed though and matched against the rules, before we go into the rules.

IP packet's are checked against the FreeBSD firewall ruleset when they pass though the ipfw firewall. The man pages tell us that the number of times it passes varies between 0 and 4 times depending on the packet's source and system configuration. In our case, that is with out adjusting the default settings, it will pass though just ones. The packet is run from top to buttom and rules can have it skip a range of rules.

A firewall rule tells what under which conditions the packet matches and what to do if a rule matches. You can specify the kind of packet, the source & destination ip address range, the direction a packet is heading, though what NIC it needs to travel and more. The fist rules that it matches and allows, rejects (unknow host) or denies it determain wheter it is crushed by the big hammer or if its allow to pass though the ipfw firewall.

Stateful firewall

The first thing on the agenda is to setup a security barrier between the internet and this computer. The task is to allow desired packet's by this computer. The stateful firewall is just the tool to use.

# stateful firewall
add 4990 allow tcp from any to any out via xl1 setup keep-state
add 4990 allow udp from any to any out via xl1 keep-state
add 4990 allow icmp from any to any out via xl1 keep-state

Stateful firewall is the art of having packet's denied or rejected by the ipfw firewall, unless the ip packet's belong to you. The FreeBSD firewall records certain information with these rules that allow it to sea if a returing packet contains requested information or if it belong to the other side.

# check ip packet against state
add 100 check-state

This rule checks if the table contains information that tell it whether packet's should be allowed to pass. Its advised to have this rule early on in the ipfw firewall rules set as it can efficiently check and could lower the load on the firewall by quite a lot. The search, for a match betain the packet and a rule, ends when this rule let the packet pass and continues otherwise.

Network Adress Translation

Please skip this section if you don't have compiled your own kernel or have no idea what that is. This section is intented to be informational for user who have completed my howto about 'Firewall Setup' and like a little more information on the working of there FreeBSD firewall.

If this computer is a gateway for you lan then you may need something like network address translation (NAT). NAT is a techniek where packet's with private ip address, that are non routable, get the public ip address of the gatewaybefore coing on the internet. This process is reversed on the way back.

# select traffic for natd
add 3000 skipto 3400 ip from any to any via xl0
add 3000 skipto 3400 ip from me to any via xl1
add 3210 divert 8668 ip from any to any
add 3220 skipto 3400 ip from any to me
add 3390 allow ip from any to any

Having these packet's being registed by the stateful firewall wouldn't work. Here's wat hapend. On there way out the packet's first go though natd and recieve a public ip address and then they would be registerd by the stateful firewall. On there way back two things can happen:

The packet's first are checked by the stateful firewall. This then accepts the packet preventing them from going to natd and getting there private ip address. Thus they would have recieved there destination in the eyes of the packet. The gateway off cource wouldn't know what to do with it.

The packet's pass though natd again and recieve there private ip adres. Then then are passed by the stateful firewall. This has no record of a private ip address and doesn't let the packet pass.

The solution is simple one. Natd keeps record in much the same way as the stateful firewall does. If it has a record of the packet then it belongs to the network and should be allowed to passed, never to be recorded by the stateful firewall. Thus the packet's comming or going to the lan can be allowed by the firewall afther passing though natd.

Deny spoofing

# deny spoofing
add 2010 deny ip from 10.0.0.0/8 to any in
add 2010 deny ip from 127.0.0.0/8 to any in
add 2010 deny ip from 172.0.0.0/12 to any in
add 2010 deny ip from 192.0.2.0/24 to any in
add 2010 deny ip from 192.168.0.0/16 to any in
add 2020 reject ip from any to 10.0.0.0/8 out
add 2020 reject ip from any to 127.0.0.0/8 out
add 2020 reject ip from any to 172.0.0.0/12 out
add 2020 reject ip from any to 192.0.2.0/24 out
add 2020 reject ip from any to 192.168.0.0/16 out

Spoofing is a techniek where crackers change certain information that can identify them. This can happen with the addresses in ip packet's. The ip address ranges you sea above are private ip addresses. This means that they are non routable. (Unleas you uses them.) Therefore the ruleset above blockes packes that have one of them set.

# pass packet's comming from internal NIC and us
add 2000 skipto 2100 ip from any to any via xl0
add 2000 skipto 2100 ip from 192.168.1.0/24 to any via xl1 out
add 2000 skipto 2100 ip from any to 192.168.1.0/24 via xl1 in
add 2000 skipto 2100 ip from 10.0.0.0/24 to any via xl1 in
add 2000 skipto 2100 ip from any to 10.0.0.0/24 via xl1 out

You will be, most likly be using some private ip addresses. These packet's can jump right over the spoofing block by setting up rules with the skipto command, as you see here above.

Allow local traffic

Next are rules for that allow all traffic from and to local LAN. There is no need to use natd or the stateful firewall here. And doing so would put a strain on there resources. I have seen cases where heavy use of the lan resulted in natd taking up 100% of the CPU. This will prevent that from accouring.

# allow local traffic
add 160 allow ip from any to any via lo0 out
add 1010 allow ip from 192.168.1.0/24 to 192.168.1.0/24 via xl0

Deny everything else

And everything else... is denies or rejected, depending on the source.

# reject (unreach host) outgoing so we know and don't have to wait
add 4997 reject ip from any to any in via xl0
add 4998 reject ip from any to any out via xl1

# deny incomming for stealth
add 4999 deny ip from any to any

Final notes

Using firewall protectection is important because it provides a powerfull security that gives protection from attacks. Everyone should have one on each computer. Only the most basic stuff was discussed in to howto. The FreeBSD firewall may not be to you liking the way it is. However, I hope I've given enough guidance and support to make some changes for your self. In addition, I like to encourage you to contact me, if you have questions or feedback about this howto. I can be contact my though the feedback link on top.