|
Two things: One is a question regarding scrub and
the other is a request for comments on my pf ruleset (If someone has actually
started using something like wiki then a pointer in that direction would be nice
too :)
First my goals and circumstances for my
ruleset:
I have an OpenBSD-current machine acting as my
gateway/firewall/NAT box. There are a few Windows (2000) boxes and one
OpenBSD-current box behind the NAT.
The gateway runs dhcpd on the internal interface,
and also acts as a caching name server and the internal authoriative name server
for my local domain. It runs ftp-proxy and tircproxy, and I've added entries to
/etc/services for the ports that both of these proxies use. I've also added a
_tirc user which tircproxy runs as. /dev/pf has been made group read/writeable
and I've added a pf group and chown'd it to root:pf, and added _tirc, proxy and
_identd to this group. I'm using oidentd instead of identd and it runs as user
_identd.
From the external interface point of view, I
run sshd and I have oidentd open to only the list of ips given from a table. I
currently connect via 28.8kbps modem (hopefully to change soon ;)
From the internal interface point of view, I run
the above mentioned services and ftpd, although the internal interface
protection is permissive enough to allow the internal machines to connect to any
other service listening on the internal interface. The internal interface is a
100Mbps rl card.
My goals (other than to help prevent being
hacked of course ;) are to stop spoofed packets (I looked at using antispoof but
it didn't meet my requirements) from entering or leaving, to implement some sort
of bandwidth priority and to otherwise to appear to not being running a firewall
and to if possible mask what OS I'm running from fingerprinting. Currently
I block icmp6.
My question regarding scrub is this: it would seem
that scrub is stopping FIN, NULL and XMAS scans cold, and not returning anything
at all. From my quick reading of the relevant RFC, an RST should be returned if
the port is closed and an ACK should be returned if the port is open (although a
number of OS's just return RSTs too). Either way, the scrub rule seems to drop
the packet entirely, not passing it on to the filter rules giving me a chance to
reply or not reply at my choosing. (I would prefer to reply with RST
personally). I don't want to remove the scrub statement because then I'd lose
the other benefits of scrub.
Also I've noticed when doing tcpdump's that when
packets go through scrub the tcpdump's sometimes tend to mention that the packet
has a bad IP checksum (well the TCP checksum was reported as ok, so I assume
they mean the IP checksum). Is this known behaviour?
Anyway, here's my ruleset:
==================================
#
Macros
int_if="rl1" ext_if="tun0" max_mss="1432" min_highport="49152" ext_bandwidth="28Kb" # Tables table <unrouteable> const { 0/8, 10/8, 127/8, 169.254/16, 172.16/12, 192.0.2/24, 192.168/16 } table <noircproxy> persist file "/etc/pf/noircproxy" { } table <allowedsmb> const { $int_if:network, 255.255.255.255 } table <int_ok> const { $int_if:network, 255.255.255.255 } table <bannedips> persist file "/etc/pf/bannedips" { } table <identservers> persist file "/etc/pf/identservers" { } # Options set timeout tcp.closed 1 # Normalisation scrub out on $ext_if all no-df max-mss $max_mss random-id scrub out on $int_if inet from ! $int_if max-mss $max_mss scrub log no-df # Queues altq on $ext_if cbq bandwidth $ext_bandwidth queue { std, bulk, medium, fast } queue std cbq(default) queue bulk priority 0 queue medium priority 4 queue fast priority 7 # Translation nat on $ext_if inet from $int_if:network to ! $int_if:network -> $ext_if rdr on $int_if inet proto tcp from $int_if:network to ! $int_if:network port 21 -> lo0 port ftpproxy no rdr on $int_if inet proto tcp from $int_if:network to <noircproxy> port 6667 no rdr on $int_if inet proto tcp from $int_if to any port 6667 rdr on $int_if inet proto tcp from $int_if:network to ! $int_if port 6667 -> lo0 port ircproxy # Filter Rules # Default action is to block with return and log block return log # Don't log inet6 block return inet6 # Allow through unfiltered interfaces pass quick on { lo0, lo1, enc0 } # antispoof unfiltered interfaces block in quick on ! lo0 inet from lo0:network # Block non routeable packets block log quick from no-route block return log quick to no-route # Block TCP connections with invalid flags block quick proto tcp flags R/R block return log quick proto tcp flags /S block return log quick proto tcp flags A/A # Internal Interface # Incoming Internal # Allow DHCP clients through to our DHCP server pass in quick on $int_if inet proto udp from port = bootpc to { 255.255.255.255, $int_if } port = bootps keep state # antispoof in for internal interfaces block in log quick on ! $int_if inet from $int_if:network block in quick on $int_if inet from { $int_if, ! $int_if:network } # Restrict SMB to the internal network block return in log quick on $int_if inet proto udp to ! <allowedsmb> port { 137, 138, 445 } block return in log quick on $int_if inet proto tcp to ! <allowedsmb> port { 137, 139, 445 } # Silently drop SMB packets for this machine (disable if using Samba) block return in quick on $int_if inet proto udp to port { 137, 138, 445 } block return in quick on $int_if inet proto tcp to port { 137, 139, 445 } # Allow through redirected proxies pass in quick on $int_if inet proto tcp to lo0 port = ftpproxy user = root keep state pass in quick on $int_if inet proto tcp to lo0 port = ircproxy user { _tirc, root } keep state # Allow TCP in pass in quick on $int_if inet proto tcp to $int_if user { >= 0 } keep state block return in log quick on $int_if inet proto tcp to $int_if pass in quick on $int_if inet proto tcp to ! <unrouteable> modulate state # Allow UDP in pass in quick on $int_if inet proto udp to $int_if user { >= 0 } keep state (udp.first 10, udp.single 10 ) block return-icmp in log quick on $int_if inet proto udp to $int_if pass in quick on $int_if inet proto udp to ! <unrouteable> keep state (udp.first 10, udp.single 10) # Allow ICMP in pass in quick on $int_if inet proto icmp to { $int_if, ! <unrouteable> } icmp-type 8 code 0 keep state # Outgoing Internal pass out quick on $int_if inet proto { tcp, udp, icmp } from $int_if to <int_ok> keep state block out log quick on $int_if from <unrouteable> pass out quick on $int_if inet proto tcp to <int_ok> modulate state pass out quick on $int_if inet to <int_ok> keep state # External Interface # antispoof for external interface block in log quick on $ext_if inet from { ($ext_if), <unrouteable>, 255.255.255.255 } # Insert pass rules for external interface redirected packets here... # Block packets sent to an invalid address block return in log quick on $ext_if inet to !($ext_if) # Silently block extra dns replies block return in on $ext_if inet proto udp from port = domain to port = domain # Allow incoming services # Block banned ips block return in log quick on $ext_if inet from <bannedips> label bannedips queue bulk # TCP Services pass in log quick on $ext_if inet proto tcp to port = ssh keep state label ssh queue(bulk, medium) # Allow certain ident servers pass in log quick on $ext_if inet proto tcp from <identservers> to port = auth label ident # Open up the high ports for active mode type connections # DCC traffic for tircproxy pass in quick on $ext_if inet proto tcp to port >= $min_highport user { _tirc } keep state label dcctraffic queue bulk # Active mode ftp traffic pass in quick on $ext_if inet proto tcp to port >= $min_highport user { root } keep state label ftptraffic queue bulk # Allow ping requests through pass in quick on $ext_if inet proto icmp icmp-type 8 code 0 keep state label in_ping # Outgoing External # Block out from spoofed ip's block out log quick on $ext_if inet from !($ext_if) # Block out to unrouteable addresses block return out log quick on $ext_if to <unrouteable> # Allow outgoing pass out quick on $ext_if inet proto tcp user = proxy keep state label ftptraffic queue bulk pass out quick on $ext_if inet proto tcp to port = ssh keep state label ssh queue(bulk, fast) pass out quick on $ext_if inet proto tcp to port = telnet keep state label telnet queue fast pass out quick on $ext_if inet proto tcp keep state pass out quick on $ext_if inet proto udp keep state label udp queue fast pass out quick on $ext_if inet proto icmp keep state label icmp queue fast ==============================================================
Cheers,
Alistair Kerr
|
