# PF doesn't check and block, doesn't run



## TheCompass (Sep 25, 2013)

Good morning,

I have a problem with PF. I made a pf.rules and I put in that

```
ext_if="em0"

services="{ 22, 3306 }"
ports_extra="{ 15000,15002,16000 }"
table <my_host> const {MyIp}
table <banned_host> persist

set block-policy drop
set loginterface $ext_if
set skip on lo
scrub on $ext_if reassemble tcp no-df random-id
antispoof quick for { lo0 $ext_if }
block in
pass out all keep state
pass out on $ext_if all modulate state
pass in quick from <my_host>
block in quick from <banned_host>
pass in inet proto icmp all icmp-type echoreq
pass in on $ext_if proto tcp to any port $services flags S/SA keep state \
 (max-src-conn 30, max-src-conn-rate 10/5, overload <banned_host> flush)
pass in on $ext_if proto {tcp,udp} to any port $ports_extra flags S/SA keep state \
 (max-src-conn 20, max-src-conn-rate 10/5, overload <banned_host> flush)
```

I'll put my IP (MyIP) to skip PF, but when I test that I do `pfctl -t banned_host -T add 31.23.448.77 (my IP for example)` and FreeBSD accepts the rule.


```
1/1 addresses added.
```

But when I login in FreeBSD, it doesn't kick me, I can log in. I test it and `reboot` the server and restart pf (`service pf restart`) but again, it doesn't work.

Any idea?

Kind regards.

PD: I have enabled PF in the rc.conf:

```
pf_enable="YES"
pf_rules="/etc/pf.rules"
```
Also in my kernel

```
device    pf                                                               
device    pflog                                             
device    pfsync
```


----------



## SirDice (Sep 25, 2013)

TheCompass said:
			
		

> ```
> [snip]
> table <my_host> const {MyIp}
> table <banned_host> persist
> ...



The first rule allows traffic from "MyIp" and because it uses the quick keyword the rest of the ruleset isn't processed. So adding that IP address to the banned_host table won't do anything, the rule will never be reached.


----------



## TheCompass (Sep 25, 2013)

SirDice said:
			
		

> The first rule allows traffic from "MyIp" and because it uses the quick keyword the rest of the ruleset isn't processed. So adding that IP address to the banned_host table won't do anything, the rule will never be reached.


It's an example, I remove the MyIp from table <my_host> const {}, and I block a friend, but we can log into the server.


----------



## J65nko (Sep 25, 2013)

Could you please post the output of `# pfctl -vvv -s rules` after you or your or friend have logged into the server?


----------



## TheCompass (Sep 25, 2013)

Here is

```
@0 scrub on em0 all no-df random-id reassemble tcp fragment reassemble
  [ Evaluations: 2548      Packets: 2548      Bytes: 217420      States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@0 block drop in quick on ! lo0 inet6 from ::1 to any
  [ Evaluations: 413       Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@1 block drop in quick on ! lo0 inet from 127.0.0.0/8 to any
  [ Evaluations: 40        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@2 block drop in quick on ! em0 inet from 94.23.63.0/24 to any
  [ Evaluations: 40        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@3 block drop in quick inet from 94.23.63.95 to any
  [ Evaluations: 40        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@4 block drop in all
  [ Evaluations: 40        Packets: 39        Bytes: 1336        States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@5 pass out all flags S/SA keep state
  [ Evaluations: 413       Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@6 pass out on em0 all flags S/SA modulate state
  [ Evaluations: 373       Packets: 585       Bytes: 105547      States: 93    ]
  [ Inserted: uid 0 pid 548 ]
@7 pass in quick from <host_propios:1> to any flags S/SA keep state
  [ Evaluations: 413       Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@8 block drop in quick from <host_baneado:0> to any
  [ Evaluations: 40        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@9 pass in inet proto icmp all icmp-type echoreq keep state
  [ Evaluations: 40        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@10 pass in on em0 proto tcp from any to any port = 22631 flags S/SA keep state                                                                               (source-track rule, max-src-conn 30, max-src-conn-rate 10/5, overload <host_bane                                                                              ado> flush, src.track 5)
  [ Evaluations: 40        Packets: 903       Bytes: 209639      States: 1     ]
  [ Inserted: uid 0 pid 548 ]
@11 pass in on em0 proto tcp from any to any port = 3306 flags S/SA keep state (                                                                              source-track rule, max-src-conn 30, max-src-conn-rate 10/5, overload <host_banea                                                                              do> flush, src.track 5)
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@12 pass in on em0 proto tcp from any to any port = 11002 flags S/SA keep state                                                                               (source-track rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_bane                                                                              ado> flush, src.track 5)
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@13 pass in on em0 proto tcp from any to any port = 13001 flags S/SA keep state                                                                               (source-track rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_bane                                                                              ado> flush, src.track 5)
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@14 pass in on em0 proto tcp from any to any port = 13002 flags S/SA keep state                                                                               (source-track rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_bane                                                                              ado> flush, src.track 5)
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@15 pass in on em0 proto tcp from any to any port = 13003 flags S/SA keep state                                                                               (source-track rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_bane                                                                              ado> flush, src.track 5)
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@16 pass in on em0 proto tcp from any to any port = 13004 flags S/SA keep state                                                                               (source-track rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_bane                                                                              ado> flush, src.track 5)
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@17 pass in on em0 proto tcp from any to any port = 13005 flags S/SA keep state                                                                               (source-track rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_bane                                                                              ado> flush, src.track 5)
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@18 pass in on em0 proto tcp from any to any port = 13006 flags S/SA keep state                                                                               (source-track rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_bane                                                                              ado> flush, src.track 5)
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@19 pass in on em0 proto tcp from any to any port = 13007 flags S/SA keep state                                                                               (source-track rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_bane                                                                              ado> flush, src.track 5)
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@20 pass in on em0 proto tcp from any to any port = 13008 flags S/SA keep state                                                                               (source-track rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_bane                                                                              ado> flush, src.track 5)
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@21 pass in on em0 proto tcp from any to any port = 13099 flags S/SA keep state                                                                               (source-track rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_bane                                                                              ado> flush, src.track 5)
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@22 pass in on em0 proto udp from any to any port = 11002 keep state (source-tra                                                                              ck rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_baneado> flush,                                                                               src.track 5)
  [ Evaluations: 40        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@23 pass in on em0 proto udp from any to any port = 13001 keep state (source-tra                                                                              ck rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_baneado> flush,                                                                               src.track 5)
  [ Evaluations: 38        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@24 pass in on em0 proto udp from any to any port = 13002 keep state (source-tra                                                                              ck rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_baneado> flush,                                                                               src.track 5)
  [ Evaluations: 38        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@25 pass in on em0 proto udp from any to any port = 13003 keep state (source-tra                                                                              ck rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_baneado> flush,                                                                               src.track 5)
  [ Evaluations: 38        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@26 pass in on em0 proto udp from any to any port = 13004 keep state (source-tra                                                                              ck rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_baneado> flush,                                                                               src.track 5)
  [ Evaluations: 38        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@27 pass in on em0 proto udp from any to any port = 13005 keep state (source-tra                                                                              ck rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_baneado> flush,                                                                               src.track 5)
  [ Evaluations: 38        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@28 pass in on em0 proto udp from any to any port = 13006 keep state (source-tra                                                                              ck rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_baneado> flush,                                                                               src.track 5)
  [ Evaluations: 38        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@29 pass in on em0 proto udp from any to any port = 13007 keep state (source-tra                                                                              ck rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_baneado> flush,                                                                               src.track 5)
  [ Evaluations: 38        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@30 pass in on em0 proto udp from any to any port = 13008 keep state (source-tra                                                                              ck rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_baneado> flush,                                                                               src.track 5)
  [ Evaluations: 38        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@31 pass in on em0 proto udp from any to any port = 13099 keep state (source-tra                                                                              ck rule, max-src-conn 20, max-src-conn-rate 10/5, overload <host_baneado> flush,                                                                               src.track 5)
  [ Evaluations: 38        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
```

Kind regards!.


----------



## J65nko (Sep 26, 2013)

```
@0 scrub on em0 all no-df random-id reassemble tcp fragment reassemble
  [ Evaluations: 2548      Packets: 2548      Bytes: 217420      States: 0     ]
  [ Inserted: uid 0 pid 548 ]

@6 pass out on em0 all flags S/SA modulate state
  [ Evaluations: 373       Packets: 585       Bytes: 105547      States: 93    ]
  [ Inserted: uid 0 pid 548 ]
```
Rule 0 has been evaluated 2548 times, and has been applied to 2548 packets or 217,420 bytes

Looking at the Evaluations, Packets and Bytes counters, rule 6 also has been effectuated for part of the traffic. Here the States counter indicates 93 states.

Now we get to the troublesome rules that are not working:

```
@7 pass in quick from <host_propios:1> to any flags S/SA keep state
  [ Evaluations: 413       Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
@8 block drop in quick from <host_baneado:0> to any
  [ Evaluations: 40        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 548 ]
```
Rule 7 has been evaluated 413 times, but none of the checked packets matched. Same thing goes for rule 8 with 40 evaluations.

If you study pfctl(8) you will discover some nice commands to display the tables and their statistics.

Please note that pf uses a "last matched rule wins" strategy. From pf.conf(5):


```
For each packet processed by the packet filter, the filter rules are
     evaluated in sequential order, from first to last.  The last matching
     rule decides what action is taken.  If no rule matches the packet, the
     default action is to pass the packet.

[snip]

     [u]quick[/u]
           If a packet matches a rule which has the [u]quick[/u] option set, this
           rule is considered the last matching rule, and evaluation of subse-
           quent rules is skipped.
```

So with the following rule set incoming traffic from host 10.1.1.2 will be allowed to pass. The second rule will never be evaluated because of the quick keyword in the pass rule:

```
pass in quick from { 10.1.1.1, 10.1.1.2 }
block in quick from  10.1.1.2
```

If you want to block 10.1.1.2 you will have to rearrange the rules so that the blocking rule is processed first:

```
block in quick from  10.1.1.2
pass in quick from { 10.1.1.1, 10.1.1.2 }
```
Alternative method:

```
pass in from { 10.1.1.1, 10.1.1.2 }
block in quick from  10.1.1.2
```
Here traffic from 10.1.1.2 will match the first rule, but because of the "last matching rule wins" strategy, the packet will be evaluated against the second rule, which matches. Because of the quick no more matching attempts will be performed.

Depending on the context you could even omit the last quick:
	
	



```
pass in from { 10.1.1.1, 10.1.1.2 }
block in from  10.1.1.2
```
Here both rules match and 10.1.1.2 will be blocked. At least if there is not any subsequent rule that would allow traffic from that host.


----------

