PF pf + rdr + fail2ban does not block as expected

A relevant excerpt from my current firewall setup:

Code:
[...]
MAIL_INT="192.168.x.x"
MAIL_EXT="148.x.x.x"
[...]
rdr pass log on $ext_if proto tcp from any to $MAIL_EXT port { 25 80 443 465 587 993 995 } -> $MAIL_INT
nat pass log on $ext_if from $MAIL_INT to any -> $MAIL_EXT
[...]
### Deny rogue redirection
no rdr

# Anchor for fail2ban
anchor "f2b/*"

### Default blocking
block drop in log on $ext_if
pass out

I have a mail server running in a jail which has a dedicated IP I added as an alias in rc.conf. The redirection works as expected. However, the blocking, once fail2ban adds IPs, does not. Searching for similar issues, I came across Thread 52893, pointing me toward the fact that the pass keyword bypasses other rules, which makes sense. When I remove the keyword, the redirection stops working altogether.

I don't understand why. Could someone enlighten me?
 
Remove the pass from the rdr pass lines.

Code:
     If the pass modifier is given, packets matching the translation rule are
     passed without inspecting the filter rules:
See pf.conf(5).

When I remove the keyword, the redirection stops working altogether.
There's no pass in on ... rule that allows the traffic. Redirection works but the traffic is not allowed and hits the block drop in ... rule.
 
Thanks for the hint. This does not work as well. I've changed the config according to your suggestion as follows:

Code:
[...]
MAIL_INT="192.168.x.x"
MAIL_EXT="148.x.x.x"
[...]
rdr log on $ext_if proto tcp from any to $MAIL_EXT port { 25 80 443 465 587 993 995 } -> $MAIL_INT
nat pass log on $ext_if from $MAIL_INT to any -> $MAIL_EXT
[...]
### Deny rogue redirection
no rdr

# Anchor for fail2ban
anchor "f2b/*"

### Default blocking
block drop in log on $ext_if
pass out

pass in on $ext_if proto tcp from any to $MAIL_EXT port { 25 80 443 465 587 993 995 }

When activated, the traffic still gets blocked.
 
NAT (including redirection) happens before the rules. So your rule has to be:
Code:
pass in on $ext_if proto tcp from any to $MAIL_INT port { 25 80 443 465 587 993 995 }
 
Indeed, that does the trick. Now that you stated it, it is completely logical to me that it would behave in this way. Thanks again!
 
Now that you stated it, it is completely logical to me that it would behave in this way.
Yeah, just remember that a rdr pass creates an impliet pass ... rule that allows the traffic and ignores all other rules you may have. Useful but not always what you want do. And a normal pass or block rule has to use the translated addresses because the (NAT/redirection) translations are done before the rules are processed.
 
Back
Top