In case this helps anyone, I discovered the issue with this. Since the IP I am trying to ban has state entries, PF tries very hard to not disturb existing connections and thus doesn't kill the connection even though it is listed in the table that is associate with the block quick rule in pf.conf.
So after I update the blocked_ip list with the desired IP I run this: pfctl -k ip_address before reloading the rules and tables with the -f switch. Kills the state entries and leaves the user high and dry on the public side of the firewall. -Geoff Sweet -----Original Message----- From: owner-m...@openbsd.org [mailto:owner-m...@openbsd.org] On Behalf Of Geoff Sweet Sent: Friday, July 31, 2009 11:34 AM To: misc@openbsd.org Subject: PF rule problems using tables Greetings all, I have very successfully been using OpenBSD 4.5 to manage both our corporate firewall as well as the firewall in our production gaming environment. However recently I have been given the task from the home office to do some basic regional IP blocking. Great thinks I, I will create a table and at the same time create an extra table for the IP's of spammers and users whom we want to keep out of our game. So in my pf.conf I created two tables: table <blocked_ip> persist file "/etc/blocked_ip" table <asian_ip> persist file "/etc/blocked_asian_ip" blocked_ip is the table for the occasional user we want to boot, and blocked_asian_ip is a list of ip nets in select asian countries that we want to disallow. Right now blocked_asian_ip is empty and blocked_ip looks like this: 220.249.167.192 208.43.3.90 123.128.151.190 60.217.150.82 98.126.4.99 74.222.14.10 60.217.153.214 222.135.105.242 114.108.128.220 71.137.134.82 174.139.11.22 121.156.65.187 210.118.194.65 Nothing looks wrong so far to me. So then I added a block in quick rule in my pf.conf to blackhole these tables of ip's. Here is my complete pf.conf: # macros ext_if="vlan2" int_if="vlan5" slbnet_if="vlan3" adminnet_if="vlan4" # service groups priv_tcp_services="{ 8020 }" sql_port="{ 1433 }" rdp_services="{ 3389 }" icmp_types="echoreq" crm_ports="{80 443 8080}" # These are IP's that are allowed full access trusted_hosts="{24.16.115.5 203.238.151.208 203.238.151.216 203.238.151.210 203.238.151.217 67.18.69.66 222.110.172.248 76.121.252.154 71.121.162.98 98.117.116.77}" payment_gateway="{66.211.168.126 217.22.128.136 217.22.128.227 207.46.232.182 128.30.52.170 128.30.52.38 128.30.52.51 128.30.52.52 128.30.52.53 128.30.52.54 128.30.52.166 128.30.52.168 216.167.121.109}" # internal private hosts ad1="10.1.0.10" sql1="10.1.1.1" sql2="10.1.1.2" sql3="10.1.1.3" sql4="10.1.1.4" mirsrv1="10.3.2.1" mirsrv2="10.3.2.2" mirsrv3="10.3.2.3" mirsrv4="10.3.2.4" webbill="10.3.2.20" webbillms="10.1.2.20" billtest="10.3.2.21" crm="10.1.2.21" billadmin="10.3.2.22" web1="10.3.1.1" web2="10.3.1.2" sql5="10.1.1.5" web3="10.3.1.3" monitor1="10.1.0.20" # banned IP addresses table <testgeoff> persist table <blocked_ip> persist file "/etc/blocked_ip" table <asian_ip> persist file "/etc/blocked_asian_ip" # options set block-policy return set loginterface $ext_if set skip on lo # scrub scrub in # nat/rdr nat on $ext_if from !($ext_if) -> ($ext_if:0) nat on $slbnet_if from $trusted_hosts -> ($slbnet_if:0) nat-anchor "ftp-proxy/*" rdr-anchor "ftp-proxy/*" rdr pass on $int_if proto tcp to port ftp -> 127.0.0.1 port 8021 # Temporary remote connections for RDP from the Korean offices rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4100 -> $sql1 port 3389 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4101 -> $sql2 port 3389 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4102 -> $sql3 port 3389 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4103 -> $sql4 port 3389 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4104 -> $mirsrv1 port 3389 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4105 -> $mirsrv2 port 3389 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4106 -> $mirsrv3 port 3389 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4107 -> $mirsrv4 port 3389 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4108 -> $webbill port 3389 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4109 -> $webbillms port 3389 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4110 -> $billtest port 3389 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4111 -> $crm port 3389 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4112 -> $billadmin port 3389 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4113 -> $web1 port 3389 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4114 -> $web2 port 3389 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4115 -> $sql5 port 3389 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 4116 -> $web3 port 3389 # Temporary remote connections for SQL from the Korean offices rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 5100 -> $sql1 port 1433 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 5101 -> $sql2 port 1433 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 5102 -> $sql3 port 1433 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 5103 -> $sql4 port 1433 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 5104 -> $billtest port 1433 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.5 port 5105 -> $sql5 port 1433 # Redirects for the MIR game apps rdr on $ext_if proto tcp from any to 66.150.173.6 port 7000 -> $mirsrv1 rdr on $ext_if proto tcp from any to 66.150.173.6 port 7100 -> $mirsrv4 rdr on $ext_if proto tcp from any to 66.150.173.6 port {7200 7201 7202 7203 7204 7205} -> $mirsrv4 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.10 port 80 -> $crm port 80 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.10 port 443 -> $crm port 443 rdr on $ext_if proto tcp from $trusted_hosts to 66.150.173.10 port 8080 -> $crm port 8080 # filter rules block in log block in log quick from <blocked_ip> to any block in log quick from <asian_ip> to any block in log quick from <testgeoff> to any pass out keep state anchor "ftp-proxy/*" antispoof quick for { lo $int_if } # Rules to pass in on the external interface for local services pass in on $ext_if inet proto tcp from any to ($ext_if) port $priv_tcp_services flags S/SA keep state # # Rules to pass in for rdr rules # pass in on $ext_if inet proto tcp from $trusted_hosts to $crm port $crm_ports flags S/SA keep state pass in on $ext_if inet proto tcp from $trusted_hosts to {$sql1 $sql2 $sql3 $sql4 $mirsrv1 $mirsrv2 $mirsrv3 $mirsrv4 $webbill $webbillms $billtest $crm $billadmin $web1 $web2 $sql5 $web3} port 3389 keep state pass in on $ext_if inet proto tcp from $trusted_hosts to {$sql1 $sql2 $sql3 $sql4 $billtest $sql5} port 1433 keep state pass in on $ext_if inet proto {tcp udp} from any to $mirsrv1 port 7000 flags S/SA keep state pass in on $ext_if inet proto {tcp udp} from any to $mirsrv4 port {7100 7200 7201 7202 7203 7204 7205} flags S/SA keep state # # Rules inbound for the slbnet # pass in on $slbnet_if from 10.3.0.0/16 to {$ad1 $monitor1} keep state pass in on $slbnet_if inet proto tcp from 10.3.0.0/16 to {$sql1 $sql2 $sql3 $sql4 $sql5 $billtest} port $sql_port keep state pass in on $slbnet_if inet proto {tcp udp} from 10.3.0.0/16 to $webbillms port {21001 21011} keep state pass in on $slbnet_if inet proto udp from $mirsrv3 to $sql2 port 10001 keep state pass in on $slbnet_if inet proto tcp from $billtest to 192.168.16.46 port 1433 keep state # Allow in certain ICMP traffic pass in inet proto icmp all icmp-type $icmp_types keep state # Allow traffic from the internal network to make any connection to the outside world. # this rule needs to be deleted in next change request as redundant pass in on $int_if from 10.1.0.0/16 to 10.3.0.0/16 keep state pass in quick on $int_if However when I go to add an additional IP to the table, nothing happens. I append the address to the blocked_ip file, then I issue "pfctl -f /etc/pf.conf". I can see via tcpdump quite clearly that a given user, in this case 114.108.128.220, is allowed in through the firewall. And if I test for the the IP: sudo pfctl -t blocked_ip -T test 114.108.128.220 1/1 addresses match. So what gives? Do I need to do something additional to get it to reload all the table information? Thanks everyone. Geoff Sweet Operations Engineer WeMade Entertainment USA.