PF Block rule not working with NAT

I'm trying to install a blacklist to my Firewall with NAT to jails.
For some reason it's not working. I'm still able to connect to the web server in the jail with my blocked test machine (1.2.3.4 in this example).

# pfctl -t blacklist -T show
1.2.3.4


My simplified /etc/pf.conf
Code:
# Definition
ext_if = "vtnet0"
jail_net = $int_if:network
wwwjail = "172.16.1.1"
table <blacklist> persist file "/etc/pf.blacklist"

# Define NAT
nat on $ext_if from $jail_net to any -> ($ext_if)

#Redirect NAT
rdr pass on $ext_if inet proto tcp to port $wwwjail_tcp_ports -> $wwwjail
pass from { lo0, $jail_net } to any keep state

#Block when on Blacklist
block on $ext_if from <blacklist> to any

# All outgoing traffic is allowed
pass out all keep state
 
Remove the pass from the rdr pass rule. It automatically passes any traffic that hits the redirect.

Code:
     If the pass modifier is given, packets matching the translation rule are
     passed without inspecting the filter rules:
From pf.conf(4).
 
it's better those block rules to be at the beginning of the configuration with quick option. This will optimize the rule processing as there will be no need to evaluate the matching packet against the other rules.

block quick from <blacklist>

from pf.conf(5)

Code:
For example, the following    rules will protect the webserver against hosts
     making more than 100 connections in 10 seconds.  Any host which connects
     faster than this rate will    have its address added to the <bad_hosts> ta-
     ble and have all states originating from it flushed.  Any new packets
     arriving from this    host will be dropped unconditionally by    the block
     rule.

       block quick from <bad_hosts>
       pass    in on $ext_if proto tcp    to $webserver port www keep state \
           (max-src-conn-rate 100/10, overload <bad_hosts> flush global)
 
it's better those block rules to be at the beginning of the configuration with quick option. This will optimize the rule processing as there will be no need to evaluate the matching packet against the other rules.

block quick from <blacklist>

from pf.conf(5)

Code:
For example, the following    rules will protect the webserver against hosts
     making more than 100 connections in 10 seconds.  Any host which connects
     faster than this rate will    have its address added to the <bad_hosts> ta-
     ble and have all states originating from it flushed.  Any new packets
     arriving from this    host will be dropped unconditionally by    the block
     rule.

       block quick from <bad_hosts>
       pass    in on $ext_if proto tcp    to $webserver port www keep state \
           (max-src-conn-rate 100/10, overload <bad_hosts> flush global)

If I write the block quick from <blacklist> before the redirect, pfctl complains about my config:

Code:
# pfctl -nf /etc/pf.conf
/etc/pf.conf:37: Rules must be in order: options, normalization, queueing, translation, filtering
/etc/pf.conf:38: Rules must be in order: options, normalization, queueing, translation, filtering
/etc/pf.conf:39: Rules must be in order: options, normalization, queueing, translation, filtering
/etc/pf.conf:40: Rules must be in order: options, normalization, queueing, translation, filtering
 
Block or pass rules always need to come after NAT and redirections. Simply remove the pass from rdr pass and create a separate pass rule for it. Put that pass rule after the block quick.
 
Thank you! It seems to work.
/etc/pf.conf
Code:
# Definition
ext_if = "vtnet0"
jail_net = $int_if:network
wwwjail = "172.16.1.1"

table <blacklist> persist file "/etc/pf.blacklist"

# Define NAT
nat on $ext_if from $jail_net to any -> ($ext_if)

#Redirect NAT
rdr on $ext_if inet proto tcp to port $wwwjail_tcp_ports -> $wwwjail
pass from { lo0, $jail_net } to any keep state

#Block when on Blacklist
block quick from <blacklist>

# Pass to jails
pass in inet proto tcp to $wwwjail port $wwwjail_tcp_ports

# All outgoing traffic is allowed
pass out all keep state
 
Back
Top