PF use overload tables and NAT

I'm trying to figure out how to use overload to put certain abusive users in a table that I can use to make them less abusive. When NAT isn't involved, I think I have a handle on what to do since the IP address isn't changed. With NAT, all traffic on the internal network maps to the one external address before any of the pass/match rules are executed. Does this result in one user causing all traffic ending up in the table? If so, is there a way around it? Going to INET6 right now isn't an option, I need to use NAT.

Here is an example of the rules:
Code:
ext_if = em1
int_if = em0

TcpState = "flags S/SA modulate state"

WWWSTO = "(max 500,  source-track rule, max-src-states 50, max-src-nodes 75, max-src-conn-rate 1/300, overload <PITA> flush global)"

table <PITA> counters

nat on $ext_if inet from $int_if:network to any -> $ext_if

pass out log on $ext_if inet proto tcp from $ext_if to any port www \
     $TcpState $WWWSTO queue (q_hig, q_max)

#
# slow down the PITA users 
# 
pass out log on $ext_if inet proto probability 20% tcp from <PITA> to ($ext_if) \
     port www $TcpState $WWWSTO queue (q_low, q_def)

#

Thanks.
 
You should use parentheses in your NAT rule. The slow down rule for those PITA users should be similar to the the non-PITA users. Keep in mind that your firewall acts as a router. In your original rule the external NIC is the destination point of the connection, while it is not ;)

Code:
    # 
    nat on $ext_if inet from $int_if:network to any -> ($ext_if)

    pass out log on $ext_if inet proto tcp from $ext_if to any port www \
         $TcpState $WWWSTO queue (q_hig, q_max)

    # slow down the PITA users

    pass out log on $ext_if inet proto probability 20% tcp from <PITA> to any port www \
         $TcpState $WWWSTO queue (q_low, q_def)
Remember that in PF the last matching rule wins, So as it is now, the PITA slow down rule will be evaluated for the non-PITA users as well. You could speed up by making the slow down rule the first rule, and by adding quick in order to defeat the "last matching rule wins" strategy of pf.
 
J65nko said:
You should use parentheses in your NAT rule.

Thanks. IIRC, this is in case the IPv4 address changes. I "leveraged' this rule set initially from http://www.benzedrine.cx/pf.conf which doesn't have ($ext_if) in the nat rule either. So I left this nat rule as I found it.

The slow down rule for those PITA users should be similar to the the non-PITA users.
Keep in mind that your firewall acts as a router. In your original rule the external NIC is the destination point of the connection, while it is not ;)

Code:
    # 
    nat on $ext_if inet from $int_if:network to any -> ($ext_if)

    pass out log on $ext_if inet proto tcp from $ext_if to any port www \
         $TcpState $WWWSTO queue (q_hig, q_max)

    # slow down the PITA users

    pass out log on $ext_if inet proto probability 20% tcp from <PITA> to any port www \
         $TcpState $WWWSTO queue (q_low, q_def)

Remember that in pf the last matching rule wins, So as it is now, the PITA slow down rule will be evaluated for the non-PITA users as well.
You could speed up by making the slow down rule the first rule, and by adding quick in order to defeat the "last matching rule wins" strategy of pf.

I was counting on the last matching rule wins, but reversing the order and using quick makes sense. As does your fix to the rule itself. :r

Doesn't the nat rule change all users to the one external IPv4 address first, before running through the match/pass rules? I'm trying to avoid one user on the subnet causing everyone to be in the PITA table.

Also, for me it seems that probability 20% seems to only be allowed at the end of the line. Should I be able to use it as shown above?

Thanks for the help!
 
Back
Top