ipfw with NAT won't work with my own rules

I'm a new convert to FreeBSD (2 days in) and the guys over on the Networking formum have been awesome in getting me immersed. My home server is a dual NIC router and routing is working over NAT just fine. However, when I try to get my firewall set up everything stops working properly and I can't for the life of me figure it out. I also can't afford to lose much more hair or sleep :-)

The server I've set up in running IMAPS, Postfix (well, postfix won't run right now, but that's another issue) and web server. It's also providing DHCP and DNS services for the LAN, so I've tried to setup the firewall appropriately. If I remove my own rules, I can access the internet just fine from any of the clients on the LAN. However, when I use my rules, I lose access to the internet. I can however SSH in to the machine from a remote machine on a different network entirely with my rules running so it's something got to do with the outbound connections from my LAN through the router. I'm new to ipfw coming from openSUSE. My config "seems" simple enough...

rc.conf (I've tried with firewall_type="OPEN" present and not!

Code:
   defaultrouter="xx.xx.xx.xx"
   gateway_enable="YES"
   natd_enable="YES"
   natd_interface="em0"      <---public facing nic
   firewall_enable="YES"
   firewall_script="/etc/ipfw.rules"

ipfw.rules contains
Code:
fwcmd="ipfw add"

# Set these to your outside interface network and netmask and ip.
oif="em0"
onet="xx.xx.xx.0"
omask="255.255.255.192"
oip="xx.xx.xx.31"

# Set these to your inside interface network and netmask and ip.
iif="re0"
inet="172.17.3.0"
imask="255.255.255.0"
iip="172.17.3.1"

# Flush all rules
ipfw -q flush

# Stop spoofing.
${fwcmd} deny all from ${inet}:${imask} to any in via ${oif}
${fwcmd} deny all from ${onet}:${omask} to any in via ${iif}

# Setup the NAT
${fwcmd} divert natd all from any to any via ${oif}

# Stop RFC1918 nets on the outside interface.
${fwcmd} deny all from any to 10.0.0.0/8 via ${oif}
${fwcmd} deny all from any to 172.16.0.0/12 via ${oif}
${fwcmd} deny all from any to 192.168.0.0/16 via ${oif}

# Stop draft-manning-dsua-03.txt (1 May 2000) nets (includes RESERVED-1,
# DHCP auto-configuration, NET-TEST, MULTICAST (class D), and class E)
# on the outside interface.
${fwcmd} deny all from any to 0.0.0.0/8 via ${oif}
${fwcmd} deny all from any to 169.254.0.0/16 via ${oif}
${fwcmd} deny all from any to 192.0.2.0/24 via ${oif}
${fwcmd} deny all from any to 224.0.0.0/4 via ${oif}
${fwcmd} deny all from any to 240.0.0.0/4 via ${oif}

# Special early rules for protocols handled on the gateway machine,
# so that these packets don't have to go through natd which is slow.
${fwcmd} allow tcp from any to ${oip} 22 in via ${oif}      # ssh
${fwcmd} allow tcp from ${oip} 22 to any out via ${oif}
${fwcmd} allow tcp from ${oip} 22 to any out via ${oif}
${fwcmd} allow tcp from any to ${oip} 25 in via ${oif}      # smtp
${fwcmd} allow tcp from ${oip} 25 to any out via ${oif}
${fwcmd} allow tcp from any to ${oip} 53 in via ${oif}      # tcpdns
${fwcmd} allow tcp from ${oip} 53 to any out via ${oif}
${fwcmd} allow tcp from any to ${oip} 80 in via ${oif}      # http
${fwcmd} allow tcp from ${oip} 80 to any out via ${oif}
${fwcmd} allow tcp from any to ${oip} 443 in via ${oif}     # https
${fwcmd} allow tcp from ${oip} 443 to any out via ${oif}
${fwcmd} allow tcp from any to ${oip} 993 in via ${oif}     # imaps
${fwcmd} allow tcp from ${oip} 993 to any out via ${oif}
${fwcmd} allow tcp from any to ${oip} 25565 in via ${oif}   # minecraft

# Stop RFC1918 nets on the outside interface.
${fwcmd} deny all from 10.0.0.0/8 to any via ${oif}
${fwcmd} deny all from 172.16.0.0/12 to any via ${oif}
${fwcmd} deny all from 192.168.0.0/16 to any via ${oif}

# Stop draft-manning-dsua-03.txt (1 May 2000) nets (includes RESERVED-1,
# DHCP auto-configuration, NET-TEST, MULTICAST (class D), and class E)
# on the outside interface.
${fwcmd} deny all from 0.0.0.0/8 to any via ${oif}
${fwcmd} deny all from 169.254.0.0/16 to any via ${oif}
${fwcmd} deny all from 192.0.2.0/24 to any via ${oif}
${fwcmd} deny all from 224.0.0.0/4 to any via ${oif}
${fwcmd} deny all from 240.0.0.0/4 to any via ${oif}

# Allow anything on the internal net.
${fwcmd} allow all from any to any via ${iif}

# Allow anything outbound from this net.
${fwcmd} allow all from ${onet}:${omask} to any out via ${oif}

# Deny anything outbound from other nets.
${fwcmd} deny log all from any to any out via ${oif}

# Allow TCP through if setup succeeded.
${fwcmd} allow tcp from any to any established

Can anyone help me understand what has gone wrong? I've googled relentlessly and tried numerous configurations, but all to no avail.
 
The NAT rule is displaced. It should come after the block of your custom rules and before the second instance of the rules labeled "# Stop RFC1918 nets on the outside interface.".
 
Many thanks Rolf. I made those changes, but I still don't get external access to the internet. When I remove the firewall_script from rc.conf and restart with the basic rules, I'm all good again. I'm beginning to think that ipfw means "Insanity Possible, Fury Welcome!" LOL :-)
 
nonsequitur said:
I made those changes, but I still don't get external access to the internet. When I remove the firewall_script from rc.conf and restart with the basic rules, I'm all good again.

1. Generate a new firewall script using the working basic rule set as a template:

# echo -e '#!/bin/sh\n\nipfw -q flush\n' > ipfw.conf
# ipfw list >> ipfw.conf
# sed -e 's/\(^[0-9]\)/ipfw -q add \1/' -i "" ipfw.conf
# chmod ugo+x ipfw.conf

2. Edit that template
- change the rule numbers in order to leave space for your rules
- add your rules at the appropriate place
- if you are in doubt, then post the template, and we can work on it together

3. Copy the readily created ipfw.conf to /etc/ipfw.conf

4. Activate it in /etc/rc.conf

5. Enjoy :beer
 
Thanks again Rolf, appreciate the push in the right direction, everything seems to be working now and I just have an odd Minecraft thing to sort out (still diagnosing that one though!)
 
Back
Top