Re: ipfw dynamic rules

2014-03-23 Thread Julian Elischer

On 3/23/14, 6:16 AM, Ian Smith wrote:

On Sat, 22 Mar 2014 22:39:36 -0700, Julian Elischer wrote:
reposting with a useful subject line and more comments
  
   On 3/22/14, 10:33 PM, Julian Elischer wrote:
   
in ipfw that's up to you..
but I usually put the check-state quite early in my rule sets.
   
   On 3/22/14, 1:34 AM, Ian Smith wrote:
Firstly, that's the one page in the handbook (that I know of) that needs
completely nuking.  It contains many factual errors as well as weird
notions, and will only tend to mislead you; consult ipfw(8) and prosper.
I'd say refer to the examples in rc.firewall but it too is in disrepair.

Firstly, I owe an apology to the doc crew, one of whom contacted me
privately to point out that the ipfw page has had quite a massaging
lately, and work is ongoing.  I'm sorry for not checking again first.

   I am working on a new rc.firewall that is much more efficient.
   the trouble is that the script to make it do what I want is a bit more
   complicated.
   I'll put it out for discussion later. maybe tonight.

Great.  Maybe my failed rc.firewall patch from '11 can still be useful.

rather than show the script (for now)
here's the generated output for a machine with 2 interfaces performing 
NAT on behalf of its

bretheren inside.

inside nets are covered in table1
table 2 specifies your DNS secondaries if you are serving dns as a 
primary.

table 13 is all the addresses you should never put out.. or get.
I run a very similar firewall on my machines but I'm generalising it.
curious to see what people make of it :-)
I haven't run this since I started rewriting the script so it may have 
errors.

count the following:
1/ the number of rules any given packet traverses
2/ the number of tests done on each packet
('from any to any ' is no tests, from me to any is 1 test, 'from me to 
you' is 2 tests.)
One if the things that drives me crazy with the current firewalls is 
that incoming and
outgoing packets from multiple interfaces traverse the same rules, in 
the same direction.
In this set each interface gets its own rules.. in the scripts they 
actually have their own files,

which are included to give this aggregate ruleset.

comments welcome (bugs expected)


/sbin/ipfw table add 13 0.0.0.0/8
/sbin/ipfw table add 13 10.0.0.0/8
/sbin/ipfw table add 13 169.254.0.0/16
/sbin/ipfw table add 13 172.16.0.0/12
/sbin/ipfw table add 13 192.0.2.0/24
/sbin/ipfw table add 13 192.168.0.0/16
/sbin/ipfw table add 13 224.0.0.0/4
/sbin/ipfw table add 13 240.0.0.0/4

/sbin/sysctl net.inet.ip.fw.autoinc_step=2
/sbin/sysctl net.inet.ip.fw.default_to_accept=0
/sbin/sysctl net.inet.ip.fw.one_pass=0

/sbin/ipfw add 0 set 0 add pass ipv6-icmp from :: to ff02::/16
/sbin/ipfw add 2 set 0 add pass ipv6-icmp from fe80::/10 to fe80::/10
/sbin/ipfw add 4 set 0 add pass ipv6-icmp from fe80::/10 to ff02::/16
/sbin/ipfw add 6 set 0 add pass ipv6-icmp from any to any icmp6types 1
/sbin/ipfw add 8 set 0 add pass ipv6-icmp from any to any icmp6types 
2,135,136

/sbin/ipfw add 500 set 0 skipto 1000 ip from any to any in recv lo0
/sbin/ipfw add 502 set 0 skipto 1500 ip from any to any out xmit lo0
/sbin/ipfw add 504 set 0 deny all from 127.0.0.1 to any
/sbin/ipfw add 506 set 0 deny all from any to 127.0.0.1
/sbin/ipfw add 508 set deny all from any to ::1
/sbin/ipfw add 510 set deny all from ::1 to any
/sbin/ipfw add 512 set 0 skipto 2000 ip from any to any in recv xn0
/sbin/ipfw add 514 set 0 skipto 2500 ip from any to any out xmit xn0
/sbin/ipfw add 516 set 0 skipto 3000 ip from any to any in recv xn1
/sbin/ipfw add 518 set 0 skipto 3500 ip from any to any out xmit xn1
/sbin/ipfw add 520 set 0 deny ip from any to any
#lo0 rules
/sbin/ipfw add 1000 set 0 allow all from any to any
/sbin/ipfw add 1500 set 0 allow all from any to any

#xn0 input packets
/sbin/ipfw add 2000 set 0 skipto 2200 ip from any to MY_ADDR
/sbin/ipfw add 2002 set 0 reject ip from any to table(13)
/sbin/ipfw add 2004 set 0 allow udp from any to 255.255.255.255
/sbin/ipfw add 2006 set 0 allow udp from MY_NET to MY_BCASTADDR
/sbin/ipfw add 2008 set 0 drop ip from any to any
/sbin/ipfw add 2200 set 0 check-state
/sbin/ipfw add 2202 set 0 reject ip from table(13) to any
/sbin/ipfw add 2204 set 0 allow udp from any to any 53 keep-state
/sbin/ipfw add 2206 set 0 allow tcp from table(2) to any setup 53 
keep_state
/sbin/ipfw add 2208 set 1 allow tcp from any to any 
25,993,995,597,514,80,443 setup keep-state

/sbin/ipfw add 2210 set 0 allow udp from any to any frag
/sbin/ipfw add 2212 set 0 allow icmp from any to any keep-state
/sbin/ipfw add 2214 set 3 nat 1 ip from any to any
/sbin/ipfw add 2216 set 3 accept ip from any to table(1)
/sbin/ipfw add 2218 set 0 drop ip from any to any

#xn0 output packets
/sbin/ipfw add 2500 set 0 skipto 2700 ip from MY_ADDR to any
/sbin/ipfw add 2502 set 0 drop ip from not table(1) to any
/sbin/ipfw add 2504 set 0 reject ip from any to table(13)
/sbin/ipfw add 2506 set 3 nat 1 all from table(1) to any

Re: ipfw dynamic rules

2014-03-23 Thread Matthew D. Fuller
On Sun, Mar 23, 2014 at 07:47:29AM -0700 I heard the voice of
Julian Elischer, and lo! it spake thus:
 
 comments welcome (bugs expected)
 
 
 /sbin/ipfw table add 13 0.0.0.0/8
 /sbin/ipfw table add 13 10.0.0.0/8
 /sbin/ipfw table add 13 169.254.0.0/16
 /sbin/ipfw table add 13 172.16.0.0/12
 /sbin/ipfw table add 13 192.0.2.0/24
 /sbin/ipfw table add 13 192.168.0.0/16
 /sbin/ipfw table add 13 224.0.0.0/4
 /sbin/ipfw table add 13 240.0.0.0/4
 
 /sbin/ipfw add 2002 set 0 reject ip from any to table(13)

Missing a couple martians, and this is a bit automatable.  It's sh,
after all.  Out of the script on one of my servers:


--
# A table for ipv4 martians
# Source: http://www.team-cymru.org/Services/Bogons/bogon-bn-agg.txt
# NOTE: Source file doesn't have terminating newline; be sure to add one!
mtable=100
bogfile=${mydir}/bogon-bn-agg.txt
if [ -r $bogfile ]; then
${ipfw} table ${mtable} flush
cat $bogfile | while read block ; do
${ipfw} table ${mtable} add ${block} ;
done
fi

# ... lots of stuff elided

# Ignore
${ipfw} add 1010 drop ip4 from table\(${mtable}\) to any
--


Handy to just be able to randomly fetch(1) a new file and let the fw
keep up.  Though watch out for that lacking trailing newline; I've
been left without 224.0.0.0/3 (save a slot, escew /4!) once or twice
from forgetting.


-- 
Matthew Fuller (MF4839)   |  fulle...@over-yonder.net
Systems/Network Administrator |  http://www.over-yonder.net/~fullermd/
   On the Internet, nobody can hear you scream.
___
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


Re: ipfw dynamic rules

2014-03-23 Thread Julian Elischer

On 3/23/14, 8:00 AM, Matthew D. Fuller wrote:

On Sun, Mar 23, 2014 at 07:47:29AM -0700 I heard the voice of
Julian Elischer, and lo! it spake thus:

comments welcome (bugs expected)


/sbin/ipfw table add 13 0.0.0.0/8
/sbin/ipfw table add 13 10.0.0.0/8
/sbin/ipfw table add 13 169.254.0.0/16
/sbin/ipfw table add 13 172.16.0.0/12
/sbin/ipfw table add 13 192.0.2.0/24
/sbin/ipfw table add 13 192.168.0.0/16
/sbin/ipfw table add 13 224.0.0.0/4
/sbin/ipfw table add 13 240.0.0.0/4

/sbin/ipfw add 2002 set 0 reject ip from any to table(13)

Missing a couple martians, and this is a bit automatable.  It's sh,
after all.  Out of the script on one of my servers:


yeah though remember this is the output stream of the script, not the 
script itself..
it was loading it up from the small table I had in a here file in 
the script.. could easily be done from a separate file...


What I'm hoping for is to make a script set where you specify a 'type' 
for each interface, and the script builds itself..

e.g.

interfaces=xn0 xn1 tun0 tun1 lo0
fw_xn0_type=hostile nat
fw_xn1_type=trusted local
fw_tun0_type=trusted remote
fw_tun1_type=hostile nat_in

(lo0 need not be given a type)
this would firewall xn0 and tun1 and just do sanity testing on tun0 
and xn1


Julian






--
# A table for ipv4 martians
# Source: http://www.team-cymru.org/Services/Bogons/bogon-bn-agg.txt
# NOTE: Source file doesn't have terminating newline; be sure to add one!
mtable=100
bogfile=${mydir}/bogon-bn-agg.txt
if [ -r $bogfile ]; then
${ipfw} table ${mtable} flush
cat $bogfile | while read block ; do
${ipfw} table ${mtable} add ${block} ;
done
fi

# ... lots of stuff elided

# Ignore
${ipfw} add 1010 drop ip4 from table\(${mtable}\) to any
--


Handy to just be able to randomly fetch(1) a new file and let the fw
keep up.  Though watch out for that lacking trailing newline; I've
been left without 224.0.0.0/3 (save a slot, escew /4!) once or twice
from forgetting.




___
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


Re: ipfw dynamic rules

2014-03-23 Thread Michael Sierchio
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.

Use skipto (judiciously)

Use stateless and stateful rules appropriately

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

Separate processing of packets coming in versus going out

my own opinions below

I have a function in the shell script that loads tables from named
files - the contents of tables change without changing the ruleset

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

Use rulesets and matching tables to permit atomic table replacement
with rule swap

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.

/sbin/ipfw add set 1 05000 setfib tablearg ip from table\(1\) to any
in lookup src-ip 1

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.

- 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


Re: ipfw dynamic rules

2014-03-23 Thread Julian Elischer

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 

Re: ipfw dynamic rules

2014-03-23 Thread Michael Sierchio
On Sun, Mar 23, 2014 at 4:31 PM, Julian Elischer jul...@freebsd.org wrote:

 but disabled rules still have a cost I believe as hey still need to be
 traversed,
 unless someone has been very smart..

This I did not know. I don't have many, but it's a small
disappointment, if true.

 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.

Agreed.
___
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


Re: ipfw dynamic rules

2014-03-22 Thread Julian Elischer


 reposting with a useful subject line and more comments

On 3/22/14, 10:33 PM, Julian Elischer wrote:


in ipfw that's up to you..
but I usually put the check-state quite early in my rule sets.


On 3/22/14, 1:34 AM, Ian Smith wrote:

Firstly, that's the one page in the handbook (that I know of) that needs
completely nuking.  It contains many factual errors as well as weird
notions, and will only tend to mislead you; consult ipfw(8) and prosper.
I'd say refer to the examples in rc.firewall but it too is in disrepair.


I am working on a new rc.firewall that is much more efficient.
the trouble is that the script to make it do what I want is a bit more 
complicated.

I'll put it out for discussion later. maybe tonight.

as for the handbook pages.. after we see how the new firewall rules work
we can see about rewriting the page.

___
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