Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Mar 2014 16:31:11 -0700
From:      Julian Elischer <julian@freebsd.org>
To:        Michael Sierchio <kudzu@tenebras.com>
Cc:        "freebsd-ipfw@freebsd.org" <ipfw@freebsd.org>
Subject:   Re: ipfw dynamic rules
Message-ID:  <532F6EBF.9000802@freebsd.org>
In-Reply-To: <CAHu1Y726yvC7isq4mxKMWsot2MSt=QOe0Q8SPf9aCf3m_RAB3w@mail.gmail.com>
References:  <51546.1395432085@server1.tristatelogic.com> <20140322182402.Q83569@sola.nimnet.asn.au> <201403221454.IAA22021@mail.lariat.net> <20140322151155.184d5229@gumby.homeunix.com> <532E723C.2090109@freebsd.org> <532E7398.5090607@freebsd.org> <20140324000439.F87212@sola.nimnet.asn.au> <532EF401.80506@freebsd.org> <CAHu1Y726yvC7isq4mxKMWsot2MSt=QOe0Q8SPf9aCf3m_RAB3w@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On 3/23/14, 10:08 AM, Michael Sierchio wrote:
> Thanks, Julian, this is sort of independent confirmation of something
> I've been doing.  I've heard folks complain about efficiency of NAT
> (more so when using natd/DIVERT), and then saw that they matched every
> packet on a nat rule - 2 or 4 times.
>
> Some things I abstract from this:
>
> Use tables for lists of addresses where there's more than 5 or so.
I think tables are not as expensive as people think.. it's basically a 
single routing table lookup.
The funtionality added by allowing rule sets to stay, while changing 
behaviour makes
it worth using them even with 1 or 0 entries. We really should try 
profile ipfw..
I've never done that.. any profiling experts on the list?   :-)

I have not got my head fully around the lookup command yet or using 
interfaces
as table keys (I can't use that at work in 8.0 anyhow)
           ipfw add 100 ipfw skipto tablearg ip from any to any recv 
'table(10)' in
but we should see if it gives us any performance advantage over a 
simple hardcoded
filter like I used in my set.
I'd also like to have a number of local variables that you can set on 
each packet..
tags come close and maybe we should look to see what they can do for us,
but


>
> Use skipto (judiciously)
In static rulesets, skipto is fast since they are not 'computed' the 
destination is cached, and
the cache is only cleared when new rules are added or removed.
using a tablearg for a skipto is unfortunately not so good as it can not
cache the result and must therefore actually traverse the set looking 
for the target.
(unless someone has added a table for rules that I missed since I last 
loooked.)


>
> Use stateless and stateful rules appropriately
Basically in my experience, you can not use stateful behaviour on 
sessions that use NAT,
So you need to separate them out.
However you still get statefull behaviour because libalias uses a 
similar state table internally,
meaning that incoming packets must match some session already started 
in an outgoing direction,
or a specifically re-arranged translation.

I would really like to have multiple state tables as mentioned earlier..
another thing for the 'todo' file I guess, or maybe the ability to add 
an entry to a table dynamically..

  # stash away the address of our ntp servers in table 3
e.g. ipfw add 1000 table_add_dest 3 udp from me to any 123  out xmit xn0

>
> Stick to some convention for tables - 13 for bogons, 0 for whitelist
> RFC1918 addrs, 1 for whitelist public addrs, etc.

we could make such a standard doc.. and put it in the rc.firewall code 
speaks loudest.
>
> Separate processing of packets coming in versus going out
I really think this is important. rule requirements are very different 
for in and out.
I further divide each into "for us" or "for  other" on incoming, and 
"from us" or
"from other" on outgoing. these rulesets are also usually very different.
One difficulty I have thugh is handling alias addresses, and packets 
that have
been redirected to go out an interface that doesn't match the from address
it has, even though it was locally generated.  I haven't found a way 
to say "was locally generated"
other than "from me" which is expensive.. "me" is a fairly expensive 
lookup,
and depends on a field that could have come from externally, (unless 
one has good  anti-spoof
rules in place early in the set I guess.
> <my own opinions below>
>
> I have a function in the shell script that loads tables fro named
> files - the contents of tables change without changing the ruleset.
yes, a good reason to use tables.

>
> Packets not destined for "me" will be processed again when they're
> headed out - you can "allow ip from any to any in" after filtering for
> the things you do/don't want for "me" - which is the norm for a
> firewall router protecting internal nets.  This is, of course, after
> early drop for traffic that is obviously "bad"

I only do this on 'trusted' interfaces.  I tend to trust on outgoing 
and filter on incoming more.
but it's an interesting thought. I hadn't really considered that. 
another nice -to-have
would be a filter point for routed traffic, just as it is routed.. 
(see the diagram in the man page).
it's possible we could simulateit on output if we could see if packets 
have been routed or not,
sort of the inverse of the "locally generated" test.


>
> Use rulesets and matching tables to permit atomic table replacement
> with rule swap
I do this.. at $JOB I just wrote an ipfw set that is the same 
regardless of which configuration
teh device is put in but rules come and go using set enable/disable as 
options are turned on/off.
but disabled rules still have a cost I believe as hey still need to be 
traversed,
unless someone has been very smart..
>
> I also do policy-based routing with setfib and table arg, which means
> that as conditions change, I can send traffic from a particular net
> out a different interface.
It's a pitty that you need to do policy based routing only on input,
as output packets are already past their routing decision.
The 'fwd' rule can however sometimes be used later.
>
> /sbin/ipfw add set 1 05000 setfib tablearg ip from table\(1\) to any
> in lookup src-ip 1
yes there is a reason I added fibs, and the ipfw rules to manipulate 
packet fibs.
:-)

> NAT is something that should happen first on all packets incoming on
> an if and last on packets headed out an if - with few exceptions.
> "Last" except for a final decision to pass or deny the traffic.
I find that you can bypass NAT for all locally generated sessions by 
having local packet rules
before the NAT.  depending on whether the machine in question is a 
large user of the internet,
or just a router, that may be a big saving or not.

>
> - M
> _______________________________________________
> freebsd-ipfw@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-ipfw
> To unsubscribe, send any mail to "freebsd-ipfw-unsubscribe@freebsd.org"
>




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?532F6EBF.9000802>