Date: Fri, 30 Jan 2015 21:50:14 +1100 (EST) From: Ian Smith <smithi@nimnet.asn.au> To: Lev Serebryakov <lev@freebsd.org> Cc: freebsd-net@freebsd.org Subject: Re: ipfw, nat and stateful firewall: why "keep-state" on "skipto" works at all and how do this properly? Message-ID: <20150130211405.Q66172@sola.nimnet.asn.au> In-Reply-To: <54CB4943.4050104@FreeBSD.org> References: <54CAD234.3020407@FreeBSD.org> <54CAED70.1080501@freebsd.org> <54CB4943.4050104@FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 30 Jan 2015 12:05:07 +0300, Lev Serebryakov wrote: > On 30.01.2015 05:33, Julian Elischer wrote: > > >> 12700 skipto 12900 ip from any to any keep-state 12800 deny ip > >> from any to any 12900 nat 1 ip from any to any out 12999 allow ip > >> from any to any > >> > >> And rules for inbound ones are: > >> > >> 11000 deny ip from any to not me 11500 nat 1 ip from any to any > >> 11510 check-state 11600 allow tcp from any to me ssh,http setup > >> keep-state 11999 deny ip from any to any > > ok so the dynamic rule is created on the outgoing packet, and > > associated with skipto 12900 which sets up a NAT session. > > > > on a later incoming packet, the rule 11500 is hit first so the > > packets are NAT'd back, and then their state is compared to that > > stored in the outgoing path, and if they match, they go to 12900 > > where they are not checked again becasue they are not 'out' > > packets. so it falls through to 12999 and is allowed in. (in its > > changed form). packets that are not in a known session fall through > > teh check-state and are dropped. > > > > it all looks ok to me. kinda cute actually. > Not cute at all for me, as 12900 needs "out" (it is already in "out" > group of rules!) and incoming packet is jumped to outbound section :) So, don't do it that way. I've also always found skipto .. keep-state rules confusing, so I'll reinforce wishmaster's initial comment: : At first, i think you should move keep-state from skipto to explicit : allow rule. Use skipto to distinguish inbound from outbound packets, on both/all of inside and outside interfaces, then use keep-state in the appropriate sections to avoid confusion. > Other filtration is hypothetical now, but I don't like this "skip -> > nat with additional "redundant" check -> allow" pattern. Frankly the examples in the IPFW handbook section still suck, despite some recent good work in cleaning up that document. I would suggest basing a ruleset on one of those - probably 'simple' in this case - in /etc/rc.firewall, adding whatever stateful rules you want there. I failed in several attempts to get the newer kernel nat code used in 'client' and 'open' rulesets into 'simple', but it's straightforward. Even then, I extend the _structure_ of that example to split inbound from outbound flows as described below, rather than just nat everything. > > I always do what is done here and separate inwards and outwards > > packets for the external interface into two different sets of > > rules (and another set for other interfaces). > Yep, it is exactly what I do, these two groups of rules are not only > rules, of course. Something else I learned from Julian a long time ago regarding natd - though it applies equally well to kernel nat: "Don't waste natd's time with packets it doesn't care about". You need to nat all inbound packets from the outside - well, those to the $nat_if address anyway, if you have multiple IPs - but you only need to nat outbound packets on the outside interface that have earlier been accepted in from the inside interface from an internal address: $fwadd skipto $NATIN ip4 from any to ${ext_ip} in recv ${ext_if} [..] $fwadd skipto $NATOUT ip4 from any to any out xmit $ext_if recv $int_if [..] $fwadd $NATIN divert natd ip4 from any to any in recv ${nat_if} [..] $fwadd $NATOUT divert natd ip4 from any to any out xmit ${nat_if} Simply replacing 'divert natd' with 'nat N' of course. If you can't follow your own ruleset a year later, it's just not clear enough .. speaking from bitter experience :) cheers, Ian
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150130211405.Q66172>