# Noob (PF) Question



## markfisher (Jan 12, 2011)

Hi

I'm using FreeBSD 8.1 with 2 NIC cards (fxp0 and fxp1).
Packet Filter as a Firewall

The network setup:

```
InternetCloud +-----+fxp0 [FreeBSD Gateway] fxp1+-----+CiscoRouter+-----+CiscoSwitch+-----SSHServer
```
Now does this rule pass the packet from fxp0 to fxp1?

```
ext_if="fxp0"
int_if="fxp1"
ext_ssh_ports="2222"

pass in inet proto tcp on $int_if \
        from $ext_if to $int_if:network port $ext_ssh_ports keep state
```

And after the above rule do I need another rule to pass the packet from fxp1 to CiscoRouter?


Thanks
Mark


----------



## Qaz (Jan 13, 2011)

You need to add rule:

```
pass in on $ext_if inet proto tcp from any to $ext_if port $ext_ssh_ports
```


----------



## SirDice (Jan 13, 2011)

Both rules are wrong.


```
pass in on $ext_if inet proto tcp from any to $int_if:network port $ext_ssh_ports keep state
```


----------



## markfisher (Jan 13, 2011)

SirDice, thanks for your reply.

your rule,

```
pass in on $ext_if inet proto tcp from any to $int_if:network port $ext_ssh_ports keep state
```
passes packets from $ext_if to $int_if (Am I right?), so do I need another rule to pass out those packets from $int_if to my CiscoRouter?


--
Mark


----------



## SirDice (Jan 13, 2011)

The rule allows traffic from everywhere destined to the network of $int_if. So if it's IP address is something like 192.168.1.12; netmask 255.255.255.0, the rule will become something like:

```
from any to 192.168.1.0/24
```

If the IP address of the Cisco router falls in that range (it probably does) you can connect to that too.

There's no need to specify rules going back out the router. They are implied. You can turn off those implied rules but that will only make things more complicated. Complicated usually means that mistakes are made quite easily too.


----------



## quintessence (Jan 14, 2011)

Hello, 

There is no need to add keep state in the end of the given rule by SirDice because by defaults PF keep states in your FreeBSD version.


----------



## plamaiziere (Jan 16, 2011)

markfisher said:
			
		

> SirDice, thanks for your reply.
> 
> your rule,
> 
> ...


More precisely, it passes packets incoming from the ext_if interface to the network addresses owned by the interface int_if.



> so do I need another rule to pass out those packets from $int_if to my CiscoRouter?



I don't know if the PF default policy is to pass or block packet. Anyway it is a good idea to block all by default.


```
# default
block all
... other rules ...
```

So in this case, yes you need a rule to allow the packet to go out.


----------



## markfisher (Jan 16, 2011)

Thank you all for the help

so

```
int_if = "fxp1"
ext_if = "fxp0"
$ext_ssh_ports = "2222"
$ssh_server = "192.168.1.23"

block all
pass in on $ext_if inet proto tcp from any to $int_if:network port $ext_ssh_ports keep state
pass out on $int_if proto tcp from any to $ssh_server port 22
```
would pass the packet from $ext_if to $int_if and then passes that packet from $int_if to $ssh_server, Am I right?


Now

```
pass in on $ext_if inet proto tcp from $ext_if to $int_if port $ext_ssh_ports
```
Should just pass the packet from $ext_if to $int_if (NOT $int_if network), Am I right?


Thanks again


----------



## SirDice (Jan 17, 2011)

markfisher said:
			
		

> ```
> int_if = "fxp1"
> ext_if = "fxp0"
> $ext_ssh_ports = "2222"
> ...


The last rule isn't needed. You'll only need it if you ssh from this box to $ssh_server. You don't need it for data coming in on $ext_if to $ssh_server.



> Now
> 
> ```
> pass in on $ext_if inet proto tcp from $ext_if to $int_if port $ext_ssh_ports
> ...


Stop thinking about passing data from one interface to another. It just doesn't work that way.

Data comes in on $ext_if with the source address '*any*' destined for $ssh_server. Which translates to something like:

```
pass in on $ext_if proto tcp from any to $ssh_server port 22 keep state
```

How or where this traffic gets sent, which interfaces it uses etc. is all completely irrelevant with regards to PF.


----------



## markfisher (Jan 17, 2011)

SirDice, thanks for your reply.

another question, if I want to redirect and port forwarding on SSH, is this rule okay?

```
int_if = "fxp1"
ext_if = "fxp0"
ext_ssh_ports = "2222"
ssh_server = "192.168.1.23"

block all
pass in on $ext_if inet proto tcp from any to $int_if:network port $ext_ssh_ports \ 
                               rdr-to $ssh_server port 22 keep state
```

Thanks


----------



## SirDice (Jan 18, 2011)

Looks good to me.


----------



## kisscool-fr (Jan 18, 2011)

This syntax is from latest versions of pf available in OpenBSD 4.6 4.7 4.8. I don't know if this apply to FreeBSD pf version. 

From what i remember, appropriate syntax would be something like that. 


```
int_if = "fxp1"
ext_if = "fxp0"
ext_ssh_ports = "2222"
ssh_server = "192.168.1.23"

rdr on $ext_if inet proto tcp from any to $ext_if port $ext_ssh_ports -> $ssh_server port 22

block all
pass in on $ext_if inet proto tcp from any to $ssh_server port 22
```

And probably


```
pass out on $int_if inet proto tcp from any to $ssh_server port 22
```

I don't see any nat rules in your pf.conf file. Don't you need it ? Is your external adresse public or private ?


----------



## SirDice (Jan 18, 2011)

kisscool-fr said:
			
		

> This syntax is from latest versions of pf available in OpenBSD 4.6 4.7 4.8. I don't know if this apply to FreeBSD pf version.


Good point! Hadn't realized that :r 



> From what i remember, appropriate syntax would be something like that.
> 
> 
> ```
> ...


Spot on!



> And probably
> 
> ```
> pass out on $int_if inet proto tcp from any to $ssh_server port 22
> ```


Not needed as it is implied by the first pass rule.


----------



## kisscool-fr (Jan 18, 2011)

SirDice said:
			
		

> Not needed as it is implied by the first pass rule.



Pf has a per interface packet inspection, so there need to be per interface rule for each packet, so is only implied the state for a packet on the specified interface (here $ext_if). Every thing else is blocked by 'block all' rule.

What will happen, packets will pass the external if (pass in on $ext_if ...) but not the internal if (because of block all).

I usually write rules with 'quick' keyword, may be my interpretation is specific to this.


Nevertheless, markfisher you could try without and/or with the 'pass out on $int_if ...' to see what works and what don't.


----------



## SirDice (Jan 18, 2011)

kisscool-fr said:
			
		

> Pf has a per interface packet inspection,


Yes, but it's turned off by default. See pf.conf(5):


> *set state-policy*
> The state-policy option sets the default behaviour for states:
> 
> if-bound     States are bound to interface.
> floating     States can match packets on any interfaces (the default).



And I advise to keep it off, it'll only make the rule set more complex. That's good if you need it but most of the time you don't. It's certainly not needed with a relatively 'simple' set up like this.


----------



## kisscool-fr (Jan 18, 2011)

Ah, don't know this option and never changed it but I always had to write rules for each interface a packet passes through (in OpenBSD and FreeBSD too).

Maybe i skipped something interesting, I will look at that. Thanks


----------



## markfisher (Jan 18, 2011)

Thank you all for the help.

SirDice and kisscool-fr, I'm using if-bound instead of floating, so I believe kisscool-fr is right, I need a rule for each interface.


Again thank you all


----------



## markfisher (Jan 18, 2011)

Sorry for double post.

Question: Since im using if-bound my rules should be

```
int_if = "fxp1"
ext_if = "fxp0"
ext_ssh_ports = "2222"
ssh_server = "192.168.1.23"

rdr on $ext_if inet proto tcp from any to $ext_if port $ext_ssh_ports -> $ssh_server port 22

block all
pass in on $ext_if inet proto tcp from any to $ssh_server port 22
pass out on $int_if inet proto tcp from any to $ssh_server port 22
```
kisscool-fr mentioned.

Now here is the question: connecting from outside to my SSH box, does port 22 and 2222 both works or only 2222?
The way that I'm seeing these rules, if I try to connect from outside to my SSH box using port "22" (NOT 2222), this rule won't do anything:

```
rdr on $ext_if inet proto tcp from any to $ext_if port $ext_ssh_ports -> $ssh_server port 22
```
and these two rules

```
pass in on $ext_if inet proto tcp from any to $ssh_server port 22
pass out on $int_if inet proto tcp from any to $ssh_server port 22
```
passes. Am I right? If I am, how can I fix it to only uses port 2222, and redirect it to 22 internally?

Thanks


----------



## kisscool-fr (Jan 18, 2011)

With this simple ruleset, only the port 2222 is open (from the external point of view) and is redirected (by pf's internat mechanism) to your ssh_server on port 22.

The two pass rules allow traffic to go to your ssh_server but not to your FreeBSD box.


----------

