IPFW built-in NAT

Hello,

I'm trying to create a router/firewall to replace the current router at my work. So, I got an old Barracuda Networks Webfilter we had laying around doing nothing for the last 3 years and put FreeBSD on it. I'm want to use IPFW's built-in NAT functionality but it doesn't seem to be working. I've read the man page many times and just can't figure it out. And after a many days of testing and researching I turn to those more knowledgable than I...

I'm connecting to my ISP via cable modem. The modem is a straight pass-through, no routing/NAT or anything else.

My rc.conf is as follows:
Code:
hostname="cuda.cclh.local"
ipv6_enable="YES"
gateway_enable="YES"
sshd_enable="YES"
named_enable="YES"

ifconfig_rl0="DHCP"     #WAN Interface
ifconfig_rl1="inet 10.1.13.1 netmask 255.255.255.0"  #LAN Interface
nameserver="10.1.13.10"

firewall_enable="YES"
firewall_type="open"
firewall_script="/etc/ipfw.rules"
firewall_logging="YES"

router_flags="-s"
router="routed"
router_enable="YES"

And my ipfw.rules are:

Code:
#rl0=WAN, rl1=LAN
00005     0       0 allow ip from any to any via rl1
00010   158   21158 allow ip from any to any via lo0
00013     0       0 nat 1 ip from any to any in via rl0
                    ipfw nat 1 config if rl0 log reset same_ports
00015     0       0 check-state
00020     0       0 skipto 800 tcp from any to 209.18.47.61 dst-port 53 out via rl0 setup keep-state
00021     0       0 skipto 800 tcp from any to 209.18.47.62 dst-port 53 out via rl0 setup keep-state
00030     0       0 skipto 800 udp from any to 76.85.238.3 dst-port 67 out via rl0 keep-state
00040     0       0 skipto 800 tcp from any to any dst-port 80 out via rl0 setup keep-state
00050     0       0 skipto 800 tcp from any to any dst-port 443 out via rl0 setup keep-state
00060     0       0 skipto 800 tcp from any to any dst-port 25 out via rl0 setup keep-state
00061     0       0 skipto 800 tcp from any to any dst-port 110 out via rl0 setup keep-state
00070     0       0 skipto 800 tcp from me to any out via rl0 setup uid root keep-state
00080     0       0 skipto 800 icmp from any to any out via rl0 keep-state
00090     0       0 skipto 800 tcp from any to any dst-port 37 out via rl0 setup keep-state
00110     0       0 skipto 800 tcp from any to any dst-port 22 out via rl0 setup keep-state
00120     0       0 skipto 800 tcp from any to any dst-port 43 out via rl0 setup keep-state
00130     0       0 skipto 800 udp from any to any dst-port 123 out via rl0 keep-state
00300     0       0 deny ip from 192.168.0.0/16 to any in via rl0
00301     0       0 deny ip from 172.16.0.0/12 to any in via rl0
00302     0       0 deny ip from 10.0.0.0/8 to any in via rl0
00303     0       0 deny ip from 127.0.0.0/8 to any in via rl0
00304     0       0 deny ip from 0.0.0.0/8 to any in via rl0
00305     0       0 deny ip from 169.254.0.0/16 to any in via rl0
00306     0       0 deny ip from 192.0.2.0/24 to any in via rl0
00307     0       0 deny ip from 204.152.64.0/23 to any in via rl0
00308     0       0 deny ip from 224.0.0.0/3 to any in via rl0
00315     0       0 deny tcp from any to any dst-port 113 in via rl0
00320     0       0 deny tcp from any to any dst-port 137 in via rl0
00321     0       0 deny tcp from any to any dst-port 138 in via rl0
00322     0       0 deny tcp from any to any dst-port 139 in via rl0
00323     0       0 deny tcp from any to any dst-port 81 in via rl0
00330     0       0 deny ip from any to any frag in via rl0
00332     0       0 deny tcp from any to any established in via rl0
00360     0       0 allow udp from 76.85.238.3 to any dst-port 68 in via rl0 keep-state
00380     0       0 allow tcp from any to me dst-port 16000 in via rl0 setup limit src-addr 2
00400     0       0 deny log logamount 5 ip from any to any in via rl0
00450     0       0 deny log logamount 5 ip from any to any out via rl0
00800     0       0 nat 2 ip from any to any out via rl0
00801     0       0 allow ip from any to any
00999     0       0 deny log logamount 5 ip from any to any
65535    29    2683 deny ip from any to any

Essentially I took the rules from the handbook and modified them according to my needs and replaced any instances of natd with ipfw's built in NAT. I think this may be what is messing me up but I'm not sure of the proper syntax for the rules.

I've also compiled te following options in my kernel:
Code:
options         IPFIREWALL              # Enables IPFW
options         IPFIREWALL_VERBOSE      # Enables logging of packets
options         IPFIREWALL_VERBOSE_LIMIT=5# Limits the number of packets logged through syslog
options         IPDIVERT                # Enable NAT
options         IPFIREWALL_NAT          # Enable NAT
options         LIBALIAS                # Needed for NAT

I appreciate any help/advice anyone can give.
 
I did some more testing last night and I tried changing the nat rules (rule 13 and 800) so they were both 1
Code:
ipfw add 13 nat 1 ip from any to any in via rl0
ipfw nat 1 config if rl0 log reset same_ports
# More ipfw commands
ipfw add 800 nat 1 ip from any to any out via rl0

When I did this I was able to ping out to ip addresses from the FreeBSD box as well as a workstation on the LAN. But when I tried pinging a domain name (ie "google.com) all I got was a hostname lookup failure. I thought there might be a conflict from my internal DNS server so I tried changing the default DNS server on the workstation to a public DNS server and was still unable to ping "google.com". I also tried changing the value of nameserver in my rc.conf to point to my ISP's nameservers but that didn't work either. Is it correct to have nameserver pointing to my internal DNS server or my ISP's DNS server?

I also tried switching the order of my nat rules so rule 13 was out, and rule 800 was in but that didn't get me anywhere. I just googled the ports DNS uses and apparently it uses UDP not TCP so I'll try changing that and testing it later today.

If anyone has any advice or insights they could give it would be much appreciated.

Also, I forgot to mention in my first post that I'm running 8.2.
 
Ok tried adding an exception for DNS via UDP last night and that didn't fix anything either... I'm really not sure where to go from here (maybe PF? :p). I really feel like I'm just overlooking something really simple.
 
The only (well, at least the only I'm aware of) way to get in kernel ipfw NAT working is to have the following two "add" rules (one will not do):

Code:
ipfw nat 1 config if age0 reset
ipfw add 10 nat 1 all from 192.168.192.0/24 to any via age0 out
ipfw add 20 nat 1 all from any to me via age0 in

Test it without any other rules first to make sure you got the nat rule working, then add whatever rules you need.
 
Back
Top