IPFW: combining "divert natd" with "keep-state"

Jim Hatfield subscriber at insignia.com
Thu Jun 19 04:43:01 PDT 2003


Well, I *did* figure it out.


>>## Example ##
>>fxp0 = external nic
>>xl0 = internal nic
>>internal network = 10.10.10.0/24
>>internal traffic NAT'd to 1.2.3.4
>>
>>## handle nat traffic
>>100 divert 8668 ip from 10.10.10.0/24 to any out via fxp0
>>200 divert 8668 ip from any to 1.2.3.4 in via fxp0
>>
>>300 check-state
>>
>>## dynamic rules for internal clients access to everything
>>## needed so un-nat'd return traffic can flow out the 
>>## internal nic to the internal clients
>>400 allow tcp from 10.10.10.0/24 to any keep-state via xl0
>>500 allow udp from 10.10.10.0/24 to any keep-state via xl0
>>
>>## dynamic rules allow natd alias address access to
>>## external resources
>>600 allow tcp from 1.2.3.4 to any keep-state out via fxp0
>>700 allow udp from 1.2.3.4 to any keep-state out via fxp0
>
>This appears to work but I am at a loss to understand how!
>
>If I follow one TCP packet all the way out to the Internet and
>its reply back to the internal net, there are four ipfw trips:
>
>A - request packet incoming on xl0
>B - request packet outgoing on fxp0
>C - reply packet incoming on fxp0
>D - reply packet outgoing on xl0
>
>Trip A matches rule 400 and is accepted, creating a dynamic
>rule which will match trip D.
>
>Trip B first matches rule 100, gets rewritten by natd then
>matches rule 600 and is sent, creating a dynamic rule
>matching a reply to 1.2.3.4.
>
>Trip C is the problem. It matches rule 200 so gets rewritten,
>and now does not match the dynamic rule created by trip B 
>since that matches packets with 1.2.3.4 as destination
>address, which this packet no longer has. None of the other
>rules match either, so it is dropped.
>
>So how can it work?????

It works because I wrongly assumed that dynamic rules check
the interface if the rule which created them had a "via"
clause. But reading the manual reveals that this is not so.

So in my example above, the rule created by trip A is used
during both trip C and trip D since it doesn't check the
interface.

The rule created by trip B is wasted - it's never used to
match anything. The only use of the keep-state on rule 600
seems to be for conversations initiated by the router.

I don't know why but I don't really like the lack of symmetry
here. Plus there is a small problem in that if I telnet into
the router then leave the session open for a long time, the
rule is removed and next time I try to use the session it
dies. I guess I can fix that by increasing the timeout from
5 minutes to 24 hours, or by adding another static rule which
allows packets to go out on the internal network from the router
itself.

Jim


More information about the freebsd-security mailing list