# Ordering rulesets



## saznik (Nov 2, 2012)

Hi Guys,

I have a question about the correct ordering the rule set. I have an Firewall running in bridged mode with two interfaces. I started to order my old unsorted rules like the following criteria:

  1. interface ('on igb0')
  2. direction ('in', 'out')
  3. address family ('inet' or 'inet6')
  4. protocol ('proto tcp')
  5. source address ('from 10.1.2.3')
  6. source port ('from port < 1024')
  7. destination address ('to 10.2.3.4')
  8. destination port ('to port 80')

Here is a little example how it looks like in the pf.conf with some output omitted:

```
pass in quick on igb0 inet proto tcp  
pass in quick on igb0 inet proto tcp 
pass in quick on igb0 inet proto tcp 
pass in quick on igb0 inet proto udp 
pass in quick on igb0 inet proto udp 
pass in quick on igb0 inet proto icmp 
pass in quick on igb0 inet proto tcp 
pass in quick on igb1 inet proto tcp 
pass in quick on igb1 inet proto udp 
pass in quick on igb1 inet proto udp 

pass out quick on bridge0 inet proto tcp
pass out quick on bridge0 inet proto tcp 
pass out quick on bridge0 inet proto tcp 
pass out quick on bridge0 inet proto udp 
pass out quick on bridge0 inet proto udp 
pass out quick on bridge0 inet proto icmp
```

I let the default option "ruleset-optimization basic" turned on. When I check the "optimized" rule set with 
	
	



```
pfctl -vnf
```
 I get something like this:

```
1 pass in quick on igb0 inet proto tcp
2 pass in quick on igb0 inet proto tcp
3 pass out quick on bridge0 inet proto tcp
4 pass out quick on bridge0 inet proto tcp
[B]5 pass in quick on igb0 inet proto udp
6 pass in quick on igb0 inet proto icmp
7 pass in quick on igb1 inet proto udp
8 pass in quick on igb1 proto icmp[/B]
```


So at the end are the rules which pass in on igb0 and igb1 with protocol *udp *and *icmp*. I expect that these rules should have followed after line 2 like described in the rule evaluation.

Do I something wrong or is there an error in reasoning? Maybe someone have an idea.


----------



## SirDice (Nov 2, 2012)

Start by not using quick unless you have to.

This, is also pretty useless:

```
pass in quick on igb0 inet proto tcp  
pass in quick on igb0 inet proto tcp 
pass in quick on igb0 inet proto tcp
```
TCP traffic will hit the first rule and because of the quick keyword it'll never get to the other two. Which are useless anyway because they're the same as the first rule.


----------



## saznik (Nov 2, 2012)

As I wrote I omitted some information from my pf.conf Every rule allows different source IP Addresses and different source destinations. But I don't want to post my whole configuration. The rules are related to this example:

```
pass in quick on igb0 inet proto tcp from 192.168.178.45 to 192.168.178.235 port 80
pass in quick on igb0 inet proto tcp from 172.22.30.160 to 192.168.178.20 port 3389
pass in quick on igb1 inet proto udp from 192.168.178.30 to 192.168.178.10 port 13001

pass out quick on bridge0 inet proto tcp from 192.168.178.45 to 192.168.178.235 port 80
pass out quick on bridge0 inet proto tcp from 172.22.30.160 to 192.168.178.20 port 3389
pass out quick on bridge0 inet proto udp from 192.168.178.30 to 192.168.178.10 port 13001
```

So I cut off everything after proto!


----------



## SirDice (Nov 2, 2012)

Ah, yes, now it makes a lot more sense.


```
pass in quick on igb0 inet proto tcp from 192.168.178.45 to 192.168.178.235 port 80
...
pass out quick on bridge0 inet proto tcp from 192.168.178.45 to 192.168.178.235 port 80
```
This doesn't make sense though. If you allow traffic in and pass it through there's no need for the outgoing rule. It's implied.


----------



## saznik (Nov 2, 2012)

Sorry for incomplete wording.
Are you sure? When the pass out... rule is missing the packet gets blocked on bridge0 because no rule allows the packet to go out (only a pass in rule is defined). The working rules before changing looked like this:

```
pass proto tcp from a to b port 80 keep state
```

As you can see no interface is defined and so the packet is passed. Maybe you mean this?

But I only want to know or get a tip, why the rules are ordered like described. I had many rules in the style pass proto... on that machine. But the machine has many states and rules and so I decided to clean up and write the rules like described here OpenBSD journal to get optimal performance. The rules before that step were really disarranged even after the build in ruleset-optimization.


----------



## SirDice (Nov 2, 2012)

saznik said:
			
		

> Sorry for incomplete wording.
> Are you sure? When the pass out... rule is missing the packet gets blocked on bridge0 because no rule allows the packet to go out (only a pass in rule is defined).


Yes, I am quite sure.



> The working rules before changing looked like this:
> 
> ```
> pass proto tcp from a to b port 80 keep state
> ...



No, I have for example:

```
pass in on $ext_if proto tcp from any to $webserver port 80 keep state
```
Traffic comes in on the $ext_if interface and goes out on $int_if. I do not have a separate rule for it because it's not needed. I would only need an outgoing rule on $int_if if the firewall itself makes a connection to $webserver.

There is however a setting to force PF to process a packet on both the incoming and outgoing interfaces. Unfortunately I can't seem to find it anymore but it has to be specifically turned on.


----------



## saznik (Nov 2, 2012)

> There is however a setting to force PF to process a packet on both the incoming and outgoing interfaces. Unfortunately I can't seem to find it anymore but it has to be specifically turned on.



Made a quick test. The option is not enabled. The packets get blocked if the pass out rule is not defined.


----------

