Re: ipfw dynamic rules
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
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
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
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
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
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
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