IPFW What am I doing wrong with my IPFW script?

What this all boils down to is: I've made some kind of mistake with how I'm trying to allow traffic in and out on specific ports, and I don't understand what I've messed up.

As both a learning exercise and just for the general benefit of having it active, I've been trying to write an IPFW script that blocks everything except traffic on the ports that I specify. This is just on my home server but I'd like to understand what it is that I'm doing wrong here.

This script began with me directly modifying the default /etc/rc.firewall script, then I started following the example configuration in the Handbook's ipfw section. I like verbosity and explicit rules which is why I'm specifying in and out for everything, if that matters. The script I've arrived at and am trying to debug now is where I arrived after taking those two paths.

This server handles a few different things for me but are two main things I'm trying to reach - samba (which I use for Time Machine on a macbook, as well as for general network storage purposes), and my Transmission instance. I think by resolving the problem with one of them I will be able to resolve it all, so for my post here I'll just focus on transmission. As you may be aware, transmission is a bittorrent client that can run as a daemon which I connect to with a desktop client via port 9091. If I turn off ipfw, or if I enable rules 00020 and 00021 (see script below), everything works just fine. Therefore I know it must be a problem with some other part of my script (and in fact everything has been working smoothly for the years that I have not bothered with a host firewall at all).

When I monitor /var/log/security for port 9091, I see the following, or something very much like it, whenever I try to connect. It hits 10995 instead of 10998 when it's an out connection being blocked:
Dec 24 15:02:33 hostname kernel: ipfw: 10998 Deny TCP 172.18.100.224:57194 172.18.100.123:9091 in via igb0

What I think I'm reading here is that my laptop (172.18.100.224) tries to connect to port 9091 on my server (172.18.100.123) and the firewall blocks it because it's caught by rule 10998. What I am not understanding is why it's not being allowed by rule 00503. I've tried tweaking the options by using established instead of setup, and just leaving nothing after igb0, but to no avail. I tried having the port after both destination and source, and it didn't make any difference either as far as I could see.

For my examples I stripped down my script to remove other services I have configured in it (DNS, etc) because as I mentioned, I'm fairly sure that whatever I'm doing wrong in this section, I'm doing wrong everywhere else and so I'll be able to adapt this solution to address the other services.

This server has one active interface (igb0) and one IP, at 172.18.100.123. The laptop used for testing is on the same subnet.

The output of ipfw show:
Code:
00010     0       0 allow ip from any to any via lo0
00501    15     840 allow tcp from me 9091 to 172.18.100.0/24 out via igb0 established
00502     0       0 allow tcp from me 51413 to any out via igb0 setup
00503     6     384 allow tcp from 172.18.100.0/24 to me 9091 in via igb0 setup
00504    27    1620 allow tcp from any to me 51413 in via igb0 setup
00610     0       0 allow udp from 172.18.100.0/24 to me 137 in via igb0
00611     0       0 allow udp from 172.18.100.0/24 to me 138 in via igb0
00612     0       0 allow tcp from 172.18.100.0/24 to me 139 in via igb0
00613     0       0 allow tcp from 172.18.100.0/24 to any 445 in via igb0
00614   117   36663 allow udp from 172.18.100.0/24 to any 5353 in via igb0
10995 41193 2695309 deny log ip from any to any out via igb0
10996     0       0 deny log ip from any to any frag offset in via igb0
10998   330   91845 deny log ip from any to any in via igb0
10999     0       0 deny log ip from any to any
65535 36813 5960196 deny ip from any to any

Firewall sections of /etc/rc.conf:
Code:
firewall_enable="YES"
firewall_type="client"
firewall_logging="YES"
firewall_logif="YES"
firewall_script="/data/custom_firewall.ipfw"

The (pared down) contents of my firewall script at /data/custom_firewall.ipfw:
Code:
#!/bin/sh
ipfw -q -f flush
cmd="ipfw -q add"
pif="igb0"
dns1="$(grep ^nameserver /etc/resolv.conf |cut -f2 -d' '|head -1)"
dns2="$(grep ^nameserver /etc/resolv.conf |cut -f2 -d' '|head -2|tail -1)"
lan="172.18.100.0/24"

# No restrictions on loopback
$cmd 00010 allow all from any to any via lo0

# Allow any traffic to or from my own net.
#$cmd 00020 allow all from me to $lan
#$cmd 00021 allow all from $lan to me

# Transmission
$cmd 00501 allow tcp from me 9091 to $lan out via $pif established
$cmd 00502 allow tcp from me 51413 to any out via $pif setup
$cmd 00503 allow tcp from $lan to me 9091 in via $pif setup
$cmd 00504 allow tcp from any to me 51413 in via $pif setup

# Samba
$cmd 00610 allow udp from $lan to me 137 in via $pif
$cmd 00611 allow udp from $lan to me 138 in via $pif
$cmd 00612 allow tcp from $lan to me 139 in via $pif
$cmd 00613 allow tcp from $lan to any 445 in via $pif
$cmd 00614 allow udp from $lan to any 5353 in via $pif

###############
## END RULES ##
###############

#$cmd 10994 allow all from any to any out via $vpn
$cmd 10995 deny log all from any to any out via $pif

# Fragments Rules
$cmd 10996 deny log all from any to any frag in via $pif

# Deny ACK packets that did not match the dynamic rule table (review this)
#$cmd 10997 deny tcp from any to any established in via $pif

# Reject and log all other incoming connections
$cmd 10998 deny log all from any to any in via $pif
$cmd 10999 deny log all from any to any
 
In line 00503:
Try removing the "setup" word.
Or try "setup keep-state".

Thanks, removing the setup option weirdly worked. I'm almost sure I tried that exact same thing before and it failed.

If you know, what's the default behavior if you don't specify setup versus established? Does it make the rule trigger under either condition instead of just the one specified? The manpage and handbook aren't totally clear on that, to me at least.
 
When you only write "setup" established connections are not triggered by the rule.

I have
Code:
cmd="/sbin/ipfw -q add"   # Set rules command prefix
pif="tun0"
localpif="re0"
# Allow incoming access from localnet
$cmd 04050 allow tcp from 192.168.1.0/24 to any in via $localpif setup keep-state
 
Back
Top