Date: Thu, 19 Jun 2003 12:42:57 +0100 From: Jim Hatfield <subscriber@insignia.com> To: freebsd-security@freebsd.org Subject: Re: IPFW: combining "divert natd" with "keep-state" Message-ID: <bv73fv0l9i6rd30lj79qdoq636ji365684@4ax.com> In-Reply-To: <3203DF3DDE57D411AFF4009027B8C367447C45@exchange-uk.isltd.insignia.com> References: <3203DF3DDE57D411AFF4009027B8C367447C45@exchange-uk.isltd.insignia.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Well, I *did* figure it out. >>## Example ## >>fxp0 =3D external nic >>xl0 =3D internal nic >>internal network =3D 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=20 >>## 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=20 >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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bv73fv0l9i6rd30lj79qdoq636ji365684>