The FreeBSD Diary

The FreeBSD Diary (TM)

Providing practical examples since 1998

If you buy from Amazon USA, please support us by using this link.
[ HOME | TOPICS | INDEX | WEB RESOURCES | BOOKS | CONTRIBUTE | SEARCH | FEEDBACK | FAQ | FORUMS ]
Firewalls / ipfw - protect your subnet 20 October 1998
Need more help on this topic? Click here
This article has 4 comments
Show me similar articles
see also Firewall rules - some more work.

A firewall is a good line of defense against external intruders. It can allow precisely what you want and exclude everything you don't want.  I'm using ipfw which [I think] means Internet Packet FireWall.

This section will deal mostly with how to configure ipfw.  For details on to install ipfw, see Firewalls, filtering, ipfw, and FTP clients.

Deny everything.  Accept nothing.
My first step was to try invoking the simple firewall by telneting to my box and typing sh /etc/rc.firewall.  That worked.  But it also terminated my telnet session!  <grin>  Then, from the console,  I did sh /etc/rc.firewall simple.  That worked but it also stopped IRC from working.   It must be something in the rules.

The existing rules did not allow me to ping other machines from my FreeBSD box.  That's because, by default, everything is denied.  That's a good thing because it means you aren't allowing things you don't want.  It also means you must explicitly state what you do want.

Getting ping to work
I received the following message.  This applied to local machines and to those in the outside world.

ping: sendto: Permission denied

After some thought I noticed that I did not have the following rule:

$fwcmd add pass all from any to any

This allowed me to ping my local network.  And the outside world.  NOTE: The above rule isn't for long term use.  I plan to explicitly allow things rather than allow everything like that.

What is denying?
But I have bigger problems.  I can access my local webserver via internal address and by external address.  But I cannot access an external website.  I can access my local POP3 server but not my ISP.  Something in the rules is preventing this.   I think I must explicitly allow these things.

I tried removing some of the deny rules, but that didn't achieve anything.  Here is the firewall rules you get if you don't specify which model you want:

00100 allow ip from any to any via lo0
00200 deny ip from any to 127.0.0.0/8
00300 divert 8668 ip from any to any via ed0
65000 allow ip from any to any
65535 deny ip from any to any

The above rule set allows me me to do whatever I need to do.  So these rules within the simple rule set aren't the problem.  It must be the other rules.

Found!
I've done some testing.  By removing rules one at a time and trying connections to the outside world, I've found that the rules which prevent the connections.

Here are the rules and the connections they prevented:

  • prevents Agent from connecting to my ISP's news server.
$fwcmd add deny all from any to 192.168.0.0:255.255.0.0 via ${oif} out
  • prevents IRC connections from occurring.
$fwcmd add deny log tcp from any to any in via ${oif} setup
IRC
I spent some time talking to virus on Undernet #FreeBSD.  He suggested I add some rules to allow these two rules to allow IRC:
# allow IRC
$fwcmd add allow tcp from any to ${oip} 194
$fwcmd add allow udp from any to ${oip} 194

By doing that, I could reinstate rule 01300 listed above

A temporary fix
This rule sets seems fine now:
01800 allow ip from any to any

Now I've started to get rid of rule 1800 above.  It's not very secure.

21 October 1998
I've replaced:
$fwcmd add deny all from any to 192.168.0.0:255.255.0.0 via ${oif}

with

$fwcmd add deny all from any to 192.168.0.0:255.255.0.0 via ${oif} out

I'm not sure what's at fault.  It's either the rule or it's ipfw.  I'm undecided.  I've posted a message to the questions mailing list.

I've also noticed that it takes much longer to connect via IRC with the simple firewall model than with the open model.  I have no idea why.

rc.firewall model open simple
time to connect via IRC 0:02 1:30

Something is definitely wrong somewhere.  I'll find out where.

ipfw version
I've discovered which version of ipfw I'm running (as taken from /usr/src/sbin/ipfw/ipfw.c)
* $Id: firewall.php,v 1.26 2007-08-27 16:34:46 dan Exp $
Speeding things up
In attempt at speeding up the connection time, I decided to remove some rules.   After a few tests, I found this rule was the culprit:
$fwcmd add deny log tcp from any to any in via ${oif} setup

This was the bottleneck.  For whatever reason, this causes the connection time to become unacceptable long.  Without this rule, the connect time is < 2s.  With this rule, the time required to connect is > 1:30.  Interesting!  Perhaps I need other rules before this in order to speed things up.

After some talk in #nz, I was told that I was probably blocking ident.  So I added the following two rules:

    # allow IDENT
    $fwcmd add allow tcp from any to ${oip} 113
    $fwcmd add allow udp from any to ${oip} 113

With this rule in placed, I removed the following rule which I added earlier:

pass all from any to any

ipfw with DHCP etc 8 August 2000

Ernie wrote in with these tips:

If you're trying to configure your firewall to work with DHCP or another dynamic connection, then use this line in /etc/rc.firewall (ed. note: remember to change ep0 as appropriate to your situation):

onet=`ifconfig ep0 |grep "inet " |awk '{print $6}'`

to replace:

onet=255.255.255.x

Also replace the entry for the ip address with:

oip=`onet=`ifconfig ep0 |grep "inet " |awk '{print $2}'`

This works because rc.firewall is a shell script, and using the backticks runs the command within.  Note that ifconfig ep0 gets all the information on the specified network interface, grep gets the right line, and awk sucks in the right field. (in this case, the netmask).  I'd try this command at the command line before putting it into rc.firewall though. :)

Also remember when you're setting up your firewall to actually block things, (ie, not "open") that the order of the firewall rules is very important, and that when ipfw blocks internet requests, it logs the information in /var/log/security (and sometimes /var/log/messages) complete with the rule number, which you can look up in the output from "ipfw show," making it easy to find out why people can't get into your webserver. :)

Thanks Ernie.


Need more help on this topic? Click here
This article has 4 comments
Show me similar articles