Hacker News new | more | comments | ask | show | jobs | submit login
A Beginner's Guide to Firewalling with pf (srobb.net)
206 points by hrbf 8 months ago | hide | past | web | favorite | 40 comments

The PF User's Guide [0] covers most of what one needs to know for basic firewalling and includes full examples of rulesets.

[0]: https://www.openbsd.org/faq/pf/

And Peter Hansteen's PF tutorial is top notch too:


he also has a book that I've heard is great, but don't own (yet)

Thanks for mentioning it. If this is it, it's in O'Reilly's Safari catalog (I've no association, just a Safari account):

    The Book of PF, 3rd Edition
    By: Peter N.M. Hansteen
    Publisher: No Starch Press
    Pub. Date: October 8, 2014
    Print ISBN-13: 978-1-59327-589-1
    Pages in Print Edition: 248

The book is amazing, and mostly a reprint of the site.

"man pf.conf" is also very useful.

Well, it's BSD:) Good manpages are one of the things they seem to really win at.

I am just going to point out how much slack I got 20 years ago -- oh god it was 20 years ago -- from all my friends for running OpenBSD because I thought PF was amazing, also their release art is bad ass too.

I think it is odd that of lately, that it seems to becoming popular -- as if it is something new. Either way I m happy, something old that is new again and I can spend my time learning something else, maybe k8s? nah, I will pass, some things are just fads.

When I had to do some pf work, googling around rendered this project which uses pf to provide network segmentation for jails and edge firewalling. Was quite useful learning reference:


This is for a very old version of pf. The "scrub in all" construct hasn't worked since OpenBSD 4.6, which was about 8 years ago.

The guide touches on how "quick" can speed up rule evaluation. But I think this misses the big picture. I write all the rules I can using "quick", and only omit it when the language constructs provided force me to. E.g. sometimes you need to "match" and so "quick" doesn't apply.

I'd sure like someone to explain to me why "quick" isn't the preferred way or even the only way to do things. As best as I can figure, this awkwardness was inherited from the rules for ipf. But ipf was thrown out of OpenBSD about 15 years ago. I guess it made it easier to convert ipf rules to pf rules if "non-quick" remained the default behavior?

It's for FreeBSD's version of pf, which is basically a fork. Differently from the one in OpenBSD it uses the old syntax. On the other hand, it scales.

Correct. However, I'd argue that more people use FreeBSD in production than OpenBSD. Also, it's a beginner's guide.

First "tip" is to regularly disable the firewall. This is stupid and dangerous.

I do the following on my machines:

  # cp /etc/pf.conf /etc/pf.conf.good
  # crontab -e
  */5 * * * * /sbin/pfctl -f /etc/pf.conf.good
  # #now vi /etc/pf.conf; pfctl -f /etc/pf.conf; and if OK: cp /etc/pf.conf /etc/pf.conf.good

... especially since the tip is immediately followed by an explanation of how the author backs up a known good configuration file. The recovery mechanism should surely be to restore that known good version, as you say.

It also seems overcomplex to use sudo from an unprivileged user's crontab rather than just straight execution of the target command from the superuser's crontab. I infer that your # prompt is implying this, too. (-:

That tip is supposed to apply just while you are learning how to use pf so you don't block yourself from your machine.

Seems like a better tip would have been "Don't muck with global network settings over a ssh pipe. Use a local console, dummy".

All physical hardware has them. All hosting companies offer them via various tricks. This is why.

Just like suggesting `chmod 777` to have your php app work once.

Just don't recommend stupid things: make them right once and the stupid thing won't ever have to go through your mind.

The configuration syntax of pf reads like a poem, pure, clean, perfect. I really prefer PF. It is just mind-compatible. OpenBSD did a really good job here (albeit I use PF with FreeBSD only).

A lot of OpenBSD's other subprojects (like OpenSMTPd and relayd/httpd) use a similar syntax. Really makes OpenBSD configuration a breeze.

I wonder if macOS is still using an older version of pf. Last time I looked it was old enough that a lot of the examples and discussions about pf were of limited value or required translation to the older version.

How does pf compare to bpf /ipsets in terms of throughput ?

Are there any differences when dealing with MacOS?

An important tip for people migrating from iptables: rules are not applied on a first match basis, but rather last match! I've made several mistakes due to that before..

Pf always seemed so insanely over complicated for simple usage. It's been my one single annoyance with BSD. Are there not any good alternatives with a UFW-esque interface?

Comparing UFW to pf is apples and oranges.

Using a more apples to apples comparison, pf is way simpler than iptables.

By bringing up UFW which is an iptables wrapper, you're not looking for a pf alternative so much as a pf wrapper. But it was the complexity of iptables that drove development of wrappers like UFW in the first place - pf doesn't really have the same level of need that iptables did.

Personally having used iptables and ipfilter I always thought pf was pretty simple.

> By bringing up UFW which is an iptables wrapper, you're not looking for a pf alternative so much as a pf wrapper. But it was the complexity of iptables that drove development of wrappers like UFW in the first place - pf doesn't really have the same level of need that iptables did.

I fully understand that Pf is equivalent to iptables, and is a lower level abstraction than UFW. But the question stands; Is there a simple foolproof utility for blocking ports on BSD with a single command? I just don't feel like whitelisting port 80 should require authoring a config file.

>Is there a simple foolproof utility for blocking ports on BSD with a single command?

Yes. It is called pf.

    block in  on fxp0  proto tcp  to any  port { 25 80 }
... blocks incoming email and http connections on the fxp0 interface. That is all you need to put in pf.conf to do that.

I recommend using `egress` in a simple setup like that, it'll still work if you ever change your network device.

    block in on egress proto tcp to port { 25, 80 }

I agree. The syntax is very readable and easy to understand. With consumer firewalls being pwned all the time, OpenBSD with PF could be a good option for some people.

I’m going to have to get it set up again... ahh the simplicity and robustness of OpenBSD...

yes, you can, the command is called 'vi' :)

    block all
    pass proto tcp to port www

I have always found Linux's iptables particularly baroque when compared with OpenBSD's pf -- the different chains (INPUT, FORWARD, OUTPUT), the different tables ("Oh, it's the _NAT_ table you're looking for"), they seemed unnecessary complexities.

My current firewall [0] has two physical interfaces, 3 additional "virtual" (VLAN-tagged) interfaces, three RFC-1918 subnets, four IPv6 subnets (dual-stack of course, except for an IPv6-only subnet) with varying degrees of security between the subnets -- and I could not imagine maintaining it with anything but pf.

[0] https://github.com/cunnie/vain.nono.io-etc/blob/master/pf.co...

I am incredulous on reading this.....

Are you really saying this[0] is more complex than this?[1][2]

If _anything_ I'm annoyed that linux doesn't have this.

[0]: https://git.drk.sc/darkscience/ds-salt/blob/master/security/...

[1]: https://git.drk.sc/darkscience/ds-salt/blob/master/security/...

[2]: https://git.drk.sc/darkscience/ds-salt/blob/master/security/...

I always loved pf’s declarative syntax.

I do not remember the name[0], unfortunately, but I vaguely recall reading about a tool that gives you a high-level interface to define firewall rules and than emits a script/config file for various packet filters.

It was a long time ago, though, and my memory may trick me. And if that tool really did exist, it might be unmaintained and outdated.

[0] I though it was called Firestarter, but that tool appears to be Linux/iptables-specific.

Well, try to use iptables by hand and not via wrappers like ufw and you will quickly realize that it's the other way around. pf's syntax is already very much like ufw's command line arguments. I guess what arguably may be missing if anything is a good, simple, thoroughly commented template to work from when first starting off.

Do I need queuing on my OpenBSD home router or should I just use "prio" if I want my downloads to stop making my internet barely usable?

Step 1: Install OPNSense/PFSense?

Aren't both pfSense and FreeNAS running their php-backed webinterfaces as root?

Yeah, though opnsense is trying to fix that.

It's dead link.

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact