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-unsubscr...@freebsd.org"
_______________________________________________
freebsd-ipfw@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-ipfw
To unsubscribe, send any mail to "freebsd-ipfw-unsubscr...@freebsd.org"