ipfw/nated stateful rules example
fbsd_user at a1poweruser.com
Tue Jan 20 06:42:30 PST 2004
As the original poster of this thread, I want to say thank you to
Ken Bolingbroke who posted his rule set and to the other posters who
voiced their comments.
I want to point out that Ken Bolingbroke acknowledged that has work
around of doing keep-state on both the Lan interface and the public
interface only works because the returning public packet is being
matched by stateful table entries posted from the Lan interface
keep-state rules. Yes he provided he could make it work, but not
work correctly. In the true security sense, this is un-secure and
invalidates the whole purpose of using keep-state rules at all.
I an surprised that I have not yet heard the old timers dogma that
the Nated process it self is really performing an keep-state like
process and that is why keep-state does not work with divert/Natd.
There is some truth to that because the Nat process does have to
keep it's own internal table to remap IP address, but it just
blindly does the mapping with out any regard to if the packet
belongs to an authorized session conversation, like the keep-state
The conclusion so far is that ipfw1 and ipfw2 using keep-state rules
on the interface facing the public internet with divert/nated does
not work period. By all accounts this is an long time bug propagated
by the continued use of the legacy divert keyword sub-routine call
to ipfw's userland Natd function. The using of keep-state rules on
the interface facing the public internet is restricted to situations
where there are no Lans behind the ipfw firewall or when 'user
ppp' -NAT function is used. I have tested using ipnat as an front
end to ipfw with keep-state but that also ends up handing off the
packet to ipfw at the wrong time.
Now that ipfw2 has replaced ipfw1 in 5.2, maybe some of that ipfw2
programming teams effort can be directed at fixing this problem. The
IPNAT code of IPFILTER runs in the kernel and could be modified to
be ipfw2's external Nat function.
So firewall users who want the maximum level of protection have to
use IPFILTER. IPFILTER has had the keep state function long before
the keep-state option was ever added to ipfw1.
Still would like to be provided wrong on my conclusion.
From: Micheal Patterson [mailto:micheal at tsgincorporated.com]
Sent: Tuesday, January 20, 2004 12:50 AM
To: Ken Bolingbroke; fbsd_user
Cc: freebsd-questions at freebsd.org
Subject: Re: ipfw/nated stateful rules example
----- Original Message -----
From: "Ken Bolingbroke" <hacker at bolingbroke.com>
To: "fbsd_user" <fbsd_user at a1poweruser.com>
Cc: <freebsd-questions at freebsd.org>
Sent: Monday, January 19, 2004 10:28 PM
Subject: RE: ipfw/nated stateful rules example
> On Mon, 19 Jan 2004, fbsd_user wrote:
> > That's a play on words. And still does not prove stateful rules
> > the interface facing the public internet. There is no
> > says keep-state and limit only works on the interface facing the
> > Lan network. And the implied meaning is they are to be used on
> > interface facing the public internet.
> I just jumped in the middle here, so I may be out of context.
> But, stateful rules don't play nice with NAT. Consider non-NAT, a
> IP address contacting an Internet address:
> 126.96.36.199 -> 188.8.131.52
> A rule is created for 184.108.40.206 coming to 220.127.116.11. When
> 18.104.22.168 replies, the stateful rule lets it in. This is good.
> But consider NAT:
> 10.0.0.10 changed to 22.214.171.124 -> 126.96.36.199
> If you do a keep-state before NAT, you have a rule to allow
> to 10.0.0.10, but the return incoming packet will be
> 188.8.131.52, so the rule doesn't match.
> If you do a keep-state after NAT, then you have a rule to allow
> 184.108.40.206 to 220.127.116.11. The return incoming packet matches
> rule, but it accepts the packet and packet processing stops, so
> passed through NAT, and never makes it back to 10.0.0.10.
> So as it stands now, I don't see that you can use stateful
> with NAT, unless check-state is changed to allow a packet to be
> through NAT.
> Ken Bolingbroke
Ken, try this one. This is what I use here at home and it does
Launch NATD with natd -interface ep0 -s -m -u (Only RFC1918 packets
## Divert everything to NAT.
ipfw add 1 divert natd ip from any to any via ep0
#Prevent inbound spoof attempts for my lan range
ipfw add 10 deny ip from 192.168.1.0/24 to any in via ep0
#Check State Rules
ipfw add 20 check state
#LAN Allow Stateful
ipfw add 31 allow ip from 192.168.1.0/24 to any keep-state
#Allow Outbound Stateful.
ipfw add 40 allow ip from 68.12.xx.xx to any keep-state
NAT keeps a seperate table of it's translations to provide a back
Traffic comes in, generates a dynamic ruleset, gets translated,
and creates the 2nd dynamic for the packet. You'll end up with
ipfw -d list
## Dynamic rules:
00040 4 692 (T 18, slot 215) <-> tcp, 68.12.xx.xx3777<->
00031 35 20374 (T 10, slot 219) <-> udp, 192.168.1.3 4986<->
00031 3 216 (T 1, slot 483) <-> tcp, 192.168.1.1 22<-> 192.168.1.2
00031 16 11902 (T 298, slot 752) <-> tcp, 192.168.1.2 3777<->
Granted, you'll end up with a dual entry for each packet in stateful
but it does work. Perhaps not as intended with a single match but
use statful with NAT.
More information about the freebsd-questions