Learning how-to pf "right"

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Learning how-to pf "right"

Dennis Steinkamp
Hey there,

i am a heavy pfsense user and i thought why not spend a little "free-time" and learn more about "pf" itself. :)
So i got myself a copy of the 3rd edition of "The book of Pf" and started to work with it.

I created my first rules to the point where pf can already act as an internet gateway for a few subnets on my local network.
Even though it works fine i have a question on how to achieve a certain configuration to which i am used to.
The problem is surely on my side so please bear with me if my question sounds naive or stupid. (which it surely will^^)

Let me show you my current ruleset first:

1.) block all
2.) set skip on lo
3.) match out on egress inet from $int_net nat-to egress
4.) pass in on $int_if from $int_net to any
5.) pass out on $ext_if from $ext_if to any

As far as i know, in order to grant my client machines in the local network access to the internet the keyword "any" in rule 4.) is neccessary for obvious reasons. But of course "any" would imply all other interfaces to where i maybe want to restrict accessx to.
My understanding was, i would just grant my clients access to the WAN interface (or the egress interface) so that they can surf the web etc. but at the same time are locked out to access other interfaces, until i create rules for it, thats the kind of configuration i am probably used to, due to my pfsense background.
My question therefor is, how can i achieve a similar configuration with "pf" or maybe i am just interested what the best/common practice for that scenario is.
Can, i for example combine any with != so that traffic destined for the internet passes but at the same time traffic destined to vlans (!=vlan100 .... 400) or physical networks does not?
The other approach would probaly be leave rule 4.) untouched and restrict the "any" later with block rules (e.g block in from $int_net to "{ vlan100, vlan200 ...}" because afaik with pf the last rule that fits the criteria, wins (until i use quick)

Thank you in advance for any help you are willing to provide. Progress comes slowly with me ^^

Regards

Dennis


Reply | Threaded
Open this post in threaded view
|

Re: Learning how-to pf "right"

Evaldas Auryla
Hi Dennis,

I used the last approach you mention: 4) untouched, then block rules, basically using these guidelines:

- avoid using "quick"

- firewall policy is managed on "in"

- start with default block all

block log all label "blocked"

- first block of "pass" rules is for traffic going outside to Internet (with any)

- second block that follows is "stealth block", this cancels "any" effect for lans protected by firewall

block in log from any to $lan1 label "blocked_perimeter"
block in log from any to $lan2 label "blocked_perimeter"
block in log from any to $lan3 label "blocked_perimeter"
...

- then follow "pass" blocks that enable access to specific services on protected lans

- final "pass out log all"


Best regards,
Evaldas

On 13/05/15 00:36, Dennis Steinkamp wrote:
Hey there,

i am a heavy pfsense user and i thought why not spend a little "free-time" and learn more about "pf" itself. :)
So i got myself a copy of the 3rd edition of "The book of Pf" and started to work with it.

I created my first rules to the point where pf can already act as an internet gateway for a few subnets on my local network.
Even though it works fine i have a question on how to achieve a certain configuration to which i am used to.
The problem is surely on my side so please bear with me if my question sounds naive or stupid. (which it surely will^^)

Let me show you my current ruleset first:

1.) block all
2.) set skip on lo
3.) match out on egress inet from $int_net nat-to egress
4.) pass in on $int_if from $int_net to any
5.) pass out on $ext_if from $ext_if to any

As far as i know, in order to grant my client machines in the local network access to the internet the keyword "any" in rule 4.) is neccessary for obvious reasons. But of course "any" would imply all other interfaces to where i maybe want to restrict accessx to.
My understanding was, i would just grant my clients access to the WAN interface (or the egress interface) so that they can surf the web etc. but at the same time are locked out to access other interfaces, until i create rules for it, thats the kind of configuration i am probably used to, due to my pfsense background.
My question therefor is, how can i achieve a similar configuration with "pf" or maybe i am just interested what the best/common practice for that scenario is.
Can, i for example combine any with != so that traffic destined for the internet passes but at the same time traffic destined to vlans (!=vlan100 .... 400) or physical networks does not?
The other approach would probaly be leave rule 4.) untouched and restrict the "any" later with block rules (e.g block in from $int_net to "{ vlan100, vlan200 ...}" because afaik with pf the last rule that fits the criteria, wins (until i use quick)

Thank you in advance for any help you are willing to provide. Progress comes slowly with me ^^

Regards

Dennis



Reply | Threaded
Open this post in threaded view
|

Re: Learning how-to pf "right"

Kenneth Gober
In reply to this post by Dennis Steinkamp
On Tue, May 12, 2015 at 6:36 PM, Dennis Steinkamp <[hidden email]> wrote:
As far as i know, in order to grant my client machines in the local network access to the internet the keyword "any" in rule 4.) is neccessary for obvious reasons. But of course "any" would imply all other interfaces to where i maybe want to restrict accessx to.
My understanding was, i would just grant my clients access to the WAN interface (or the egress interface) so that they can surf the web etc. but at the same time are locked out to access other interfaces, until i create rules for it, thats the kind of configuration i am probably used to, due to my pfsense background.
My question therefor is, how can i achieve a similar configuration with "pf" or maybe i am just interested what the best/common practice for that scenario is.

actually, the ruleset you have listed does exactly this.  the reason is, in order for client traffic to reach its destination, it has to make it past *two* pass rules, it must "pass in" to get into your pf router, and then it must "pass out" to go on to its destination.

your rules allow any traffic in, but then only allow traffic to the Internet to go out.  since you don't have any kind of "pass out on $private_if" rules, no traffic will be allowed to pass on to any other interfaces.  you could go to the trouble of adding block rules (e.g. block in quick on $int_if from $int_net to $private_net) but since you don't have any pass out on $private_if rules anyway, they would be spurious right now.

once you add pass out rules for your private interface(s), at that point you can decide whether you want to block client traffic on its way in, or on its way out.  either way works, as long as it gets blocked *somewhere*.

-ken
Reply | Threaded
Open this post in threaded view
|

Re: Learning how-to pf "right"

Dennis Steinkamp
Hi Ken,

thank you very much for explaining things a little bit more detailed.
I wasn`t aware of the fact that traffic has to pass two rules to reach its endpoint but after making a little drawing that illustrated how the packets flow it was pretty obvious.
Funny thing is that this is exactly the kind of misunderstanding the book mentions early on and thanks to your explanation i now understand what it means.

Thanks.

Dennis

Am 13.05.2015 um 15:29 schrieb Kenneth Gober:
On Tue, May 12, 2015 at 6:36 PM, Dennis Steinkamp <[hidden email]> wrote:
As far as i know, in order to grant my client machines in the local network access to the internet the keyword "any" in rule 4.) is neccessary for obvious reasons. But of course "any" would imply all other interfaces to where i maybe want to restrict accessx to.
My understanding was, i would just grant my clients access to the WAN interface (or the egress interface) so that they can surf the web etc. but at the same time are locked out to access other interfaces, until i create rules for it, thats the kind of configuration i am probably used to, due to my pfsense background.
My question therefor is, how can i achieve a similar configuration with "pf" or maybe i am just interested what the best/common practice for that scenario is.

actually, the ruleset you have listed does exactly this.  the reason is, in order for client traffic to reach its destination, it has to make it past *two* pass rules, it must "pass in" to get into your pf router, and then it must "pass out" to go on to its destination.

your rules allow any traffic in, but then only allow traffic to the Internet to go out.  since you don't have any kind of "pass out on $private_if" rules, no traffic will be allowed to pass on to any other interfaces.  you could go to the trouble of adding block rules (e.g. block in quick on $int_if from $int_net to $private_net) but since you don't have any pass out on $private_if rules anyway, they would be spurious right now.

once you add pass out rules for your private interface(s), at that point you can decide whether you want to block client traffic on its way in, or on its way out.  either way works, as long as it gets blocked *somewhere*.

-ken

Reply | Threaded
Open this post in threaded view
|

Re: Learning how-to pf "right"

Karl O. Pinc
In reply to this post by Dennis Steinkamp
On Wed, 13 May 2015 00:36:54 +0200
Dennis Steinkamp <[hidden email]> wrote:

>
> 1.) block all
> 2.) set skip on lo
> 3.) match out on egress inet from $int_net nat-to egress
> 4.) pass in on $int_if from $int_net to *any*
> 5.) pass out on $ext_if from $ext_if to any

It is also good practice to block spoofing
attacks, both from without and from anyone
within your own networks.

antispoof $int_if
antispoof $ext_if
block in on $int_if from !$int_net to any

There's an rfc for this but I don't recall the number.


Karl <[hidden email]>
Free Software:  "You don't pay back, you pay forward."
                 -- Robert A. Heinlein
Reply | Threaded
Open this post in threaded view
|

Re: Learning how-to pf "right"

Dennis Steinkamp
Hi,

thanks for giving a little extra advice on the anti-spoofing topic.
Maybe you can tell me if thats still neccessary in my scenario.
My $ext_if is a vlan interface connected to a ProCurve switch from where
i assign one port as tagged (thats the port where the OpenBSD machine is
connected to.)
and one untagged port which goes to the router.
My router is responsible for dialing the actual connection to my ISP so
my OpenBSD box is already behind the NAT firewall of my router.
In OpenBSD i then use Unbound as a caching nameserver which forwards any
dns queries to the DNS Servers of my ISP.
Of course i could set up PPPoE on OpenBsd directly but i thought letting
the router handle it might be the better approach.
Does antispoofing on $ext_if still makes sense for me?

Regards

Dennis

Am 13.05.2015 um 17:37 schrieb Karl O. Pinc:

> On Wed, 13 May 2015 00:36:54 +0200
> Dennis Steinkamp <[hidden email]> wrote:
>
>> 1.) block all
>> 2.) set skip on lo
>> 3.) match out on egress inet from $int_net nat-to egress
>> 4.) pass in on $int_if from $int_net to *any*
>> 5.) pass out on $ext_if from $ext_if to any
> It is also good practice to block spoofing
> attacks, both from without and from anyone
> within your own networks.
>
> antispoof $int_if
> antispoof $ext_if
> block in on $int_if from !$int_net to any
>
> There's an rfc for this but I don't recall the number.
>
>
> Karl <[hidden email]>
> Free Software:  "You don't pay back, you pay forward."
>                   -- Robert A. Heinlein
Reply | Threaded
Open this post in threaded view
|

Re: Learning how-to pf "right"

Karl O. Pinc
On Wed, 13 May 2015 20:50:26 +0200
Dennis Steinkamp <[hidden email]> wrote:

> thanks for giving a little extra advice on the anti-spoofing topic.
> Maybe you can tell me if thats still neccessary in my scenario.
> My $ext_if is a vlan interface connected to a ProCurve switch from
> where i assign one port as tagged (thats the port where the OpenBSD
> machine is connected to.)
> and one untagged port which goes to the router.
> My router is responsible for dialing the actual connection to my ISP
> so my OpenBSD box is already behind the NAT firewall of my router.
> In OpenBSD i then use Unbound as a caching nameserver which forwards
> any dns queries to the DNS Servers of my ISP.
> Of course i could set up PPPoE on OpenBsd directly but i thought
> letting the router handle it might be the better approach.
> Does antispoofing on $ext_if still makes sense for me?

If you trust your ISP or your $plasticrouter to
antispoof for you then no, you don't
need to do it yourself.  Otherwise you do.


Karl <[hidden email]>
Free Software:  "You don't pay back, you pay forward."
                 -- Robert A. Heinlein
Reply | Threaded
Open this post in threaded view
|

Re: Learning how-to pf "right"

Karl O. Pinc
In reply to this post by Dennis Steinkamp
On Wed, 13 May 2015 00:36:54 +0200
Dennis Steinkamp <[hidden email]> wrote:

> i am a heavy pfsense user and i thought why not spend a little
> "free-time" and learn more about "pf" itself. :)
> So i got myself a copy of the 3rd edition of "The book of Pf" and
> started to work with it.

> Let me show you my current ruleset first:
>
> 1.) block all
> 2.) set skip on lo
> 3.) match out on egress inet from $int_net nat-to egress
> 4.) pass in on $int_if from $int_net to *any*
> 5.) pass out on $ext_if from $ext_if to any

There is one more thing you can do to be a good neighbor.
The following rule foils people who would use you to mount
a sequence number spoofing attack on someone else.
(You would play the role of "A" in rfc1948.)

 block in on $ext_if proto tcp flags sa/sa return-rst

There are a number of caveats here.   I did not take
this from a working pf config, I made it up for this
email and it's not tested.  Further, for all I know
OpenBSD already does this by default unless you set
some sort of sysctl or something, because you should
never see a stateless packet with both syn and ack set.
(Or maybe this should be a setting built into pf?)
Finally, you'd hope that today's tcp stacks would behave
politely and send a rst when receiving a packet with
syn and ack set out of the blue.  But that's probably
too much to hope for.

Perhaps someone else can chime in and note whether
this rule is still appropriate.


Karl <[hidden email]>
Free Software:  "You don't pay back, you pay forward."
                 -- Robert A. Heinlein
Reply | Threaded
Open this post in threaded view
|

Re: Learning how-to pf "right"

Kenneth Gober
On Wed, May 13, 2015 at 10:29 PM, Karl O. Pinc <[hidden email]> wrote:
There is one more thing you can do to be a good neighbor.
The following rule foils people who would use you to mount
a sequence number spoofing attack on someone else.
(You would play the role of "A" in rfc1948.)

 block in on $ext_if proto tcp flags sa/sa return-rst

unless you're an Internet Service Provider, or you are
participating in some kind of peering arrangement, you
should not be accepting any unsolicited packets from
$ext_if, never mind forwarding them back out on $ext_if.

for a typical home or business gateway, this is a sensible
default to use:

    block in on $ext_if all

then follow that with pass rules for the specific traffic
you want to accept.

-ken
Reply | Threaded
Open this post in threaded view
|

Re: Learning how-to pf "right"

Karl O. Pinc
On Thu, 14 May 2015 08:51:50 -0400
Kenneth Gober <[hidden email]> wrote:

> unless you're an Internet Service Provider, or you are
> participating in some kind of peering arrangement, you
> should not be accepting any unsolicited packets from
> $ext_if, never mind forwarding them back out on $ext_if.
>
> for a typical home or business gateway, this is a sensible
> default to use:
>
>     block in on $ext_if all
>
> then follow that with pass rules for the specific traffic
> you want to accept.

Very good point.

I would say that there are legitimate reasons to
accept inbound traffic.  Small businesses can have
voice over IP phones, individuals often tinker with
a personal webserver, etc.





Karl <[hidden email]>
Free Software:  "You don't pay back, you pay forward."
                 -- Robert A. Heinlein