# IPFW strange behavior



## Serge1978 (Jul 8, 2013)

Hello!

Can anyone please explain to me what I'm doing wrong?

I needed to set up a content control and banner removal pack, and I ended up with Squid+SquidGuard, everything was fine at that moment. Then I noticed that if users change their browser to "No Proxy", they'll be able to bypass and browse whatever they want.

The solution appeared: setup IPFW to forward all WWW traffic to Squid using _the_ 'fwd' option, which needed to compile and install _a_ custom kernel. After installing _the_ new kernel _the_ internal LAN lost ability to pass to _the_ default gateway.


```
[LAN PC]---------[em1_____SERVER_____em0]---------------[default_router]
192.168.2.3/24   192.168.2.1/24      192.168.1.198/24   192.168.1.1/24
```

New kernel options:

```
include		GENERIC
ident		MYKERNEL1
options		IPFIREWALL
options		IPFIREWALL_VERBOSE
options		IPFIREWALL_FORWARD
options		IPFIREWALL_VERBOSE_LIMIT=5
options		IPFIREWALL_DEFAULT_TO_ACCEPT
options		IPDIVERT
```

/etc/rc.conf:

```
ifconfig_em0="inet 192.168.1.198 netmask 255.255.255.0"
ifconfig_em1="inet 192.168.2.1 netmask 255.255.255.0"
defaultrouter="192.168.1.1"
sshd_enable="YES"
gateway_enable="YES"
firewall_enable="YES"
firewall_type="/etc/ipfw.conf"
firewall_nat_enable="YES"
firewall_nat_interface="em0"
natd_enable="YES"
natd_interface="em0"
natd_flags="-dynamic -m"
squid_enable="YES"
```
/etc/ipfw.conf is empty for now. _The_ LAN PC can ping both em1 and em0, but cannot reach default_gateway (Request timed out.). _The s_erver can ping anything successfully.

`# ipfw -f flush` doesn't change anything, and has

```
65535 allow ip from any to any
```
at the end of _the_ list.

Any suggestions would be greatly appreciated. Thanks in advance.


----------



## irbis (Jul 8, 2013)

*your /etc/rc.ipfw is empty*

With _a_ "nat" ruleset you must use _the_ default /etc/rc.firewall script because it contains default _NAT_ rules, or write your own in ipfw.conf.

Change 

```
firewall_type="/etc/ipfw.conf"
```
to 

```
firewall_type="open"
```
then 
`# service ipfw restart`

Or edit your own rc.ipfw and add _the_ following lines*:*


```
if [ -z "${source_rc_confs_defined}" ]; then
if [ -r /etc/defaults/rc.conf ]; then
  . /etc/defaults/rc.conf
  source_rc_confs
elif [ -r /etc/rc.conf ]; then
  . /etc/rc.conf
fi

${fwcmd} add 50 divert natd ip4 from any to any via ${natd_interface}
```


----------



## Anonymous (Jul 8, 2013)

First I got several comments:


You do not need (anymore) to compile a custom kernel for ipfw, however, it doesn't harm either.
You enabled the modern in kernel NAT as well as the old natd, you would need to decide for one.
The flag for specifying the ipfw script is named firewall_script, and not firewall_type.
The default router at 192.168.1.1 needs to have NAT enabled at its external interface too.
On the NAT interface it is best to disable TSO.

Next, here come my recommendations for the modern in kernel NAT:

In your /etc/rc.conf remove all natd related flags and correct firewall_type to firewall_script. Specify the NAT interface within /etc/ipfw.conf.

```
ifconfig_em0="inet 192.168.1.198 netmask 255.255.255.0"
ifconfig_em1="inet 192.168.2.1 netmask 255.255.255.0 -tso"
defaultrouter="192.168.1.1"
sshd_enable="YES"
gateway_enable="YES"
firewall_enable="YES"
firewall_nat_enable="YES"
firewall_script="/etc/ipfw.conf"
squid_enable="YES"
```

In your /etc/ipfw.conf add the following:


```
#!/bin/sh
ipfw -q flush
ipfw -q nat 1 config if em1 reset

# Allow everything within the LAN
ipfw -q add 10 allow ip from any to any via em0
ipfw -q add 20 allow ip from any to any via lo0

ipfw -q add 90 deny ip from any to any not antispoof in

#replace this line with your customized actual ruleset

ipfw -q add 65534 allow ip from any to any
```

Now you have to decide, whether you are going to set up a stateful or a traditional firewall.

In the traditional case, you would #replace this line... with:


```
# traditional (no state) ruleset
# the actual allow/deny rules are only examples, adapt them to your specific requirements

ipfw -q add nat 1 ip from any to any via em1

# Rules for outgoing traffic - allow everything that is not explicitely denied
ipfw -q add 1000 deny ip from not me to any 25 via em1
ipfw -q add 1001 deny ip from any to any 5353 via em1

# Rules for incomming traffic - deny everything that is not explicitely allowed
ipfw -q add 5000 allow tcp from any to me 22,25,80,443,587 via em1

# Catch all other tcp/udp packets, but don't touch other packets, e.g. gre, esp, icmp
ipfw -q add 9998 deny tcp from any to any via em1
ipfw -q add 9999 deny udp from any to any via em1
```


In the stateful case, you would #replace this line... with:

```
# statful ruleset
# the actual allow/deny rules are only examples, adapt them to your specific requirements

ipfw -q add 100 nat 1 ip from any to any via em1 in
ipfw -q add 101 check-state

# Rules for outgoing traffic - allow everything that is not explicitely denied
ipfw -q add 1000 deny ip from not me to any 25 via em1 out
ipfw -q add 1001 deny ip from any to any 5353 via em1 out

# Allow all other outgoing connections
ipfw -q add 2000 skipto 10000 tcp from any to any via em1 out setup keep-state
ipfw -q add 2010 skipto 10000 udp from any to any via em1 out keep-state

# Rules for incomming traffic - deny everything that is not explicitely allowed
ipfw -q add 5000 allow tcp from any to me 22,25,80,443,587 via em1 in setup keep-state

# Catch all other tcp/udp packets, but don't touch other packets, e.g. gre, esp, icmp
ipfw -q add 9998 deny tcp from any to any via em1
ipfw -q add 9999 deny udp from any to any via em1

ipfw -q add 10000 nat 1 ip from any to any via em1 out
```

Note, that there are two NAT rules in the stateful case, one for incoming and one for outgoing traffic. Also in the stateful case, the packets may pass more than once the ruleset, so you need to allow this by setting the respective sysctl variable, so add in /etc/sysctl.conf:


```
net.inet.ip.fw.one_pass=0
```

And once you are there anyway, add another useful one:


```
net.inet.ip.fastforwarding=1
```


----------

