Some quick observations (disclaimer: I only just got my morning coffee,
so there's too much blood in my caffeine)
On Fri, Jul 31, 2009 at 08:18:28PM +0200, Laurent CARON wrote:
> Here is my pf config:
> LO="lo"
> EXTIF001="bge0"
> EXTIF002="em0"
> INTIF="em1"
> PFSYNCIF="em2"
>
> set skip on {$LO, $PFSYNCIF}
A macro for lo is a bit redundant; but that's a matter of taste.
> PFSYNCALLOW="{172.16.1.1, 172.16.1.2}"
>
> CARPALLOW="{Router internal IPs}"
>
> SSHALLOW="{Trusted admin IPs}"
>
> EBGPALLOW="ISP BGP Peer"
>
> IBGPALLOW="{Internal BGP sessions}"
>
> ROUTERSINTIFACES="{Internal IPs of routers (including carp)}"
>
> DECLAREDHOSTS="{Active hosts on the internal interface}"
Use tables to avoid your macros expanding into huge amounts of similar
rules. That way you can even put the IP lists in files if they grow too large.
> BAD_UDP_PORTS="{epmap, netbios-ns, netbios-dgm, netbios-ssn, microsoft-ds}"
> BAD_TCP_PORTS="{telnet, finger, epmap, netbios-ns, netbios-dgm,
> netbios-ssn, microsoft-ds}"
"Default pass" is a bad idea; if you understand this and just want to
silence crap from logs, this is good. A default block would be even
better but might not be possible, that's understandable.
> ROUTER_ALLOW_OUT="{www, ftp, telnet, ssh, domain, https, imaps, smtp,
> smtps}"
>
>
> SYNSTATE="flags S/SAFR synproxy state"
> TCPSTATE="flags S/SAFR modulate state"
> UDPSTATE="keep state"
>
> ### Stateful Options ###
> EXTIFSTO="(max 9000, source-track rule, max-src-conn 2000,
> max-src-nodes 254)"
> INTIFSTO="(max 250, source-track rule, max-src-conn 100,
> max-src-nodes 254, max-src-conn-rate 75/20)"
> POSTFIXSTO="(max 100, source-track rule, max-src-states 5,
> max-src-nodes 30, max-src-conn-rate 10/300, overload <BLACKLIST> flush
> global, tcp.established 45)"
> SPAMDSTO="(max 500, source-track rule, max-src-conn 10, max-src-nodes
> 300, max-src-conn-rate 2/300, tcp.established 10)"
> SSHSTO="(max 10, source-track rule, max-src-states 10, max-src-nodes
> 5, max-src-conn-rate 20/60, overload <OVERLOAD_SSH> flush global)"
> PORTSCANSTO="(max 60, source-track rule, max-src-conn 1, max-src-nodes
> 60, max-src-conn-rate 1/60, overload <BLACKLIST> flush global)"
>
> ### Tables ###
> table <BLACKLIST> persist file "/etc/blacklist"
> table <SLOWQUEUE> persist file "/etc/slowqueue"
> table <OVERLOAD_SSH> persist
>
> ### Options ###
> set debug urgent
> set require-order yes
> set block-policy drop
> set loginterface $EXTIF001
> set fingerprints "/etc/pf.os"
> set ruleset-optimization none
>
>
> ### Timeout Options ###
> set optimization aggressive
Are you sure you need this?
> set timeout { frag 10, tcp.established 3600 }
this can annoyingly kill live ssh sessions if your coffee break takes
too long; but it can also be necessary.
> set timeout { tcp.first 30, tcp.closing 10, tcp.closed 10, tcp.finwait 10 }
> set timeout { udp.first 30, udp.single 30, udp.multiple 30 }
> set timeout { other.first 30, other.single 30, other.multiple 30 }
> set timeout { adaptive.start 5000, adaptive.end 10000 }
Again, if you've thought about these and need them they're fine, if
you're just twisting knobs because they're there you might want to
re-think.
> ### Queueing ###
> altq on $EXTIF001 bandwidth 30000Kb hfsc queue { ack, voip, dns, ssh,
> web, mail, bulk, spamd }
> queue ack bandwidth 60% priority 9 qlimit 500 hfsc
> (realtime 40%)
> queue voip bandwidth 10% priority 8 qlimit 500 hfsc
> (realtime 1%)
> queue dns bandwidth 6% priority 7 qlimit 500 hfsc
> (realtime 5%)
> queue ssh bandwidth 9% priority 6 qlimit 500 hfsc
> (realtime 5%) {ssh_login, ssh_bulk}
> queue ssh_login bandwidth 90% priority 6 qlimit 500 hfsc
> queue ssh_bulk bandwidth 10% priority 5 qlimit 500 hfsc
> queue web bandwidth 10% priority 5 qlimit 500 hfsc
> (realtime 10%)
> queue mail bandwidth 3% priority 4 qlimit 500 hfsc
> (realtime 5%)
> queue bulk bandwidth 1% priority 3 qlimit 500 hfsc
> (realtime 5% default)
> queue spamd bandwidth 1% priority 1 qlimit 500 hfsc
> (upperlimit 3Kb)
>
>
> antispoof log quick for { lo0 $EXTIF001 $INTIF }
>
>
> block log on $EXTIF001
>
>
> pass quick on $PFSYNCIF inet proto pfsync from $PFSYNCALLOW keep state
> pass quick on $INTIF inet proto carp from $CARPALLOW keep state
IIRC you should use keep state (no-sync) here since these aren't very
meaningful on the other fw
>
> block in quick on $EXTIF001 inet proto tcp from any to port $BAD_TCP_PORTS
> block in quick on $EXTIF001 inet proto udp from any to port $BAD_UDP_PORTS
>
>
> block in log quick from no-route to any
> block in log quick on $EXTIF001 from <SLOWQUEUE> to any
> probability 97%
> block in quick on $EXTIF001 from <BLACKLIST> to any
> block in quick on $EXTIF001 inet proto tcp from
> <OVERLOAD_SSH> to any port ssh
> block in quick on $EXTIF001 from any to 255.255.255.255
> block return in quick on $INTIF from any to <BLACKLIST>
> block return in quick on $INTIF from any to 224.0.0.1
>
>
> block in log on $EXTIF001 inet from any to $ROUTERSINTIFACES
>
>
> pass in quick log on $EXTIF001 inet proto icmp from any to $EXTIF001
> icmp-type 8 code 0 $UDPSTATE
> pass in log quick on $EXTIF001 inet proto icmp from any to
> $ROUTERSINTIFACES icmp-type 8 code 0 $UDPSTATE
> pass out log quick on $INTIF inet proto icmp from any to $DECLAREDHOSTS
> icmp-type 8 code 0 $UDPSTATE
>
>
> pass in log quick inet proto udp from any to $EXTIF001 port 33433 ><
> 33626 keep state
> pass in log quick on $EXTIF001 inet proto udp from any to
> $ROUTERSINTIFACES port 33433 >< 33626 keep state
> pass out log quick on $INTIF inet proto udp from any to $DECLAREDHOSTS
> port 33433 >< 33626 keep state
>
> pass in log quick inet proto {tcp, udp} from $EBGPALLOW to $EXTIF001
> port bgp
>
>
> pass in quick log on $EXTIF001 inet proto tcp from $SSHALLOW to
> $EXTIF001 port ssh $SYNSTATE $SSHSTO queue (ssh_bulk, ssh_login) tag
> OPENSSH
>
> pass in quick log on $EXTIF001 inet proto tcp from $SSHALLOW to
> $ROUTERSINTIFACES port ssh $SYNSTATE $SSHSTO queue (ssh_bulk, ssh_login)
> tag OPENSSH
> pass out quick log on $INTIF inet proto tcp from $SSHALLOW to
> $DECLAREDHOSTS port ssh $SYNSTATE $SSHSTO queue (ssh_bulk, ssh_login)
> tag OPENSSH
>
>
>
> pass in log quick on $EXTIF001 from any to $DECLAREDHOSTS
>
>
> pass out log quick on $INTIF from any to $DECLAREDHOSTS
>
>
> pass in log on $INTIF proto {tcp,udp} from $IBGPALLOW to $INTIF port
> bgp $TCPSTATE $INTIFSTO
>
>
> pass in log on $INTIF inet proto tcp from $DECLAREDHOSTS to $INTIF
> port ssh $TCPSTATE $INTIFSTO
> pass in log on $INTIF proto icmp from $DECLAREDHOSTS to $INTIF
>
> pass in log on $INTIF inet proto icmp from $DECLAREDHOSTS to $INTIF
> icmp-type 8 code 0 $UDPSTATE $INTIFSTO
>
> pass out log on $EXTIF001 proto {tcp, udp} from $DECLAREDHOSTS to any
> port $ROUTER_ALLOW_OUT
>
>
> pass out log on $EXTIF001 proto icmp from
> {$ROUTERSINTIFACES,$IBGPALLOW,$DECLAREDHOSTS} to any
> pass out log on $EXTIF001 proto {tcp, udp} from
> {$ROUTERSINTIFACES,$IBGPALLOW} to any port $ROUTER_ALLOW_OUT
>
> # IPv6 config not yet completed, will do once v4 fully done
> pass quick inet6
>
I'm not sure if I see a typical border filtering scheme (maybe I didn't
read carefully enough), you'll want to drop:
* Packets not from you (your advertised prefix) to your ISP, probably
also log these (even though your ISP should drop them, they might
not[1] and you really want to know about them)
* Packets from you from your ISP, they are not you. Logging these should
be interesting, too.
* Probably also: packets not addressed to you from your ISP
[1] I once managed to send packets from an RFC1918 address through two
AS's to my home DSL line. Don't trust your ISP, do your own
filtering.
--
Jussi Peltola