PF PF firewall pf.conf Review

Hi all,

Could somebody with some knowledge and experience have a look at my pf.conf before I start using it, to make sure I'm not doing anything stupid with it?

I am using FreeBSD 12.2 on a laptop connected via wifi to my ISP router and the VPN provided for work.
I am using OpenVPN and UDP-based ovpn files.
Ideally, I would like to force all traffic through the VPN or otherwise block it (in the future).
But I have started with a basic pf.conf which I hope will work with or without the VPN.

Is my current set up OK for use with or without the VPN?

My /etc/rc.conf:
Code:
pf_enable="YES"
pf_flags=""
pf_log="YES"
pf_rules="/etc/pf.conf"
pflog_enable=yes
pflog_flags=""
pflog_logfile="/var/log/pflog
gateway_enable="NO"

PF seems to load OK, doesn't complain about syntax when I run:
pfctl -nf /etc/pf.conf

Here is my basic / standard pf.conf that I have cobbled together from man pages and what not:
Code:
### Macros

# Interface names
ext_if = "wlan0"
vpn_if = "tun0"

# Macro name for non-routables
martians = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, 0.0.0.0/8, 240.0.0.0/4 }"

### Settings

# Set optimization rules
set ruleset-optimization basic
set optimization normal

# Silently drop blocked packets
set block-policy drop

# Silently drop failed packets
set fail-policy drop

# Bind states to interfaces
set state-policy if-bound

# set fingerprints file
set fingerprints "/etc/pf.os"

# Pass loopback
set skip on lo0

# Generate debug messages only for serious errors
set debug urgent

# Reassemble fragmented packets
scrub in all fragment reassemble

### Rules

# Default deny everything
block log all

# Block all IPv6
block quick inet6 all

# Block spooks
antispoof for lo0
antispoof for $ext_if
block in quick from no-route to any
block in quick from urpf-failed to any
block in quick on $ext_if from any to 255.255.255.255

# Block to and from port 0
block quick proto { tcp, udp } from any port = 0 to any
block quick proto { tcp, udp } from any to any port = 0

# Block RFC 1918 addresses
block in quick on $ext_if from $martians to any
block out quick on $ext_if from any to $martians

# Allow everything else
pass out all keep state

EDIT: Obviously I have tested it, and it seems to work:
- I have "full" connectivity, as far as I can tell, with or without VPN
- Our VPN leak test page reports no IP leaks
- No DNS leaks reported
- Online "firewall testers" seem OK (without VPN)

Any and all feedback is very much appreciated.
Thank you.
 
So first things first... you obviously want security, I get that, but why would you trust the words of an Internet stranger? ;)

First I'd drop the martians macro; it's ugly, doesn't do anything and why bother? Especially because it's not used. There's no need, that can't work anyway. I'd also drop port 0, I'd be very interested to see why that would be blocked but you're denying yourself that info.

I also fail to understand the need to block 255.255.255.255.

Other than that, I guess it works ;)
 
These are defaults, you don't have to set those:
Code:
pf_flags=""
pf_rules="/etc/pf.conf"
pflog_flags=""
pflog_logfile="/var/log/pflog
gateway_enable="NO"
You typically want gateway_enable="YES" or there will be no routing between interfaces. And thus nothing passes between tun0 and wlan0. A firewall is not a router. Routing is done by the OS, not the firewall.

That pf_log="YES" doesn't do anything. It's pflog_enable="YES"

Code:
block in quick on $ext_if from any to 255.255.255.255
May result in DHCP and/or ARP not working correctly. Not sure why you are blocking this, broadcasts aren't routed.

Code:
# Block RFC 1918 addresses
block in quick on $ext_if from $martians to any
block out quick on $ext_if from any to $martians
Not sure what address you got on your wireless interface or tun0 but it's typically an RFC-1918 address, which would get blocked here.
 
Thank you all.

As you can tell, I'm a networking novice and so your help is greatly appreciated.

So first things first... you obviously want security, I get that, but why would you trust the words of an Internet stranger?

Correct! I don't! But, I need help, and rightly or wrongly, I assume forum members who spend so many hours of their lives helping out others have good intentions, or at least don't want to ruin their internet reputations by giving out bad advice. Secondly, that is why I've asked others elsewhere to look at it too - and I'm comparing notes ;)

First I'd drop the martians macro; it's ugly, doesn't do anything and why bother?

There are those "martians" again. I would use https://calomel.org/pf_config.html and this forum thread to get started with a well structured pf.conf file instead of where ever it was you found that sample pf.conf.

As I said, I don't know much about networking (I know, I know... Why am I even here, right?) I didn't use a sample pf.conf. I wrote it line by line following the manual and what I found in the following guides:

Both of which have the "martians" thing in there. :/


So I understand that as it stands, based on the use-case I gave above, the "martians" stuff is useless, right? But if in the future I wanted to use my laptop as a gateway for some other device which I may or may not have lying around, would I need the "martians" stuff? That was my impression based on the manual and the guides I have linked.

These are defaults, you don't have to set those.

You typically want gateway_enable="YES" or there will be no routing between interfaces. And thus nothing passes between tun0 and wlan0.

That's why those options are in there; for later, when I will want to change them.
Thank you for the reminder about routing between interfaces!

That pf_log="YES" doesn't do anything. It's pflog_enable="YES"

Yeah, my mistake. Wrote it out wrong. My /etc/rc.conf has pflog_enable="YES"

Also, thank you SirDice for that little script you posted in another thread for testing changes to pf.conf. Very handy!

About the 255.255.255.255 rule:
Code:
block in quick on $ext_if from any to 255.255.255.255
I took it from the guide recommended by Datapanic:
https://calomel.org/pf_config.html

I saw that it was commented out, but so were the next two lines that were recommended in other sources. That's why I included it. If it does nothing, why is it there in the first place?

OK, so taking your collective suggestions into account (about martians, 255.255.255.255, port 0, enabling/disabling gateway, etc.), how does this look?

Code:
### Macros

# Interface names
ext_if = "wlan0"
vpn_if = "tun0"

### Settings

# Set optimization rules
set ruleset-optimization basic
set optimization normal

# Silently drop blocked packets
set block-policy drop

# Silently drop failed packets
set fail-policy drop

# Bind states to interfaces
set state-policy if-bound

# set fingerprints file
set fingerprints "/etc/pf.os"

# Pass loopback
set skip on lo0

# Generate debug messages only for serious errors
set debug urgent

# Reassemble fragmented packets
scrub in all fragment reassemble

### Rules

# Default deny everything
block log all

# Block all IPv6
block quick inet6 all

# Block spooks
antispoof for lo0
antispoof for $ext_if
block in quick from no-route to any
block in quick from urpf-failed to any

# Allow everything else
pass out all keep state
 
Back
Top