FreeBSD/PF include command hack
Published November 4th, 2006 in FreeBSDYesterday (or was it two days ago?), I was looking for a way to include a sub-ruleset in pf.conf from a different file and noticed that it wasn’t possible without a patch. I asked dhartmei (Daniel Hartmeier, the main developer of pf) if there was a chance to see it committed upstream (read: in the OpenBSD source tree). He answered that some people strongly disagreed with this patch, so I thought I would try to convince mlaier (Max Laier, pf maintainer for FreeBSD) to maintain the patch in our tree. He wasn’t too happy with the patch either, stating that the parser was already complicated enough as it is but told me I could probably use ‘pfctl -f -’ to do what I want. How did I miss that?
So I’m thinking of something like this in /etc/rc.conf:pf_program="/usr/bin/cpp -P -x c -I/etc -E /etc/pf.conf 2>/dev/null | /sbin/pfctl" pf_rules="-"This way I can use #include “foo.conf” in my pf.conf file \o/. Admittedly, this is hackish to say the least, and it won’t work if your /usr partition is a NFS, but still, this should be working, and you can even use #define if pf macros ain’t good enough for you
Edit: This actually doesn’t work, just add ‘eval’ in front of all $pf_program invocations in /etc/rc.d/pf. You can actually set pf_program to a shell script that calls cpp to avoid the mod in the rc script.
Edit2: < @Mavvie> that’s the worst usage for the C preprocessor I’ve seen in my life.
Edit3: As I said in Edit 1, you can use a script like this, and set pf_program to its path.
Another shortcoming of the pfctl(8) parser is the missing ability to parse tables with embedded comments:
table persist {
192.168.0.0/24, # Foo
192.168.1.0/24, # Bar
192.168.2.0/24, # Baz
}
The above syntax is illegal and so have all other table-with-embedded-comment syntax constructions I have tried been…
The only solution seems to be to load the table definition from an external file, which isn’t very flexible.
I have a script called “preprocess” I recently posted to the pf list; check for it on my
website or in the archives around today if you want to get ahold of it.
cpp tends to be somewhat specific to C, and expects C syntax more-or-less.
preprocess is freeform, line-based, and you can configure the comment character,
the if statement, implicit end-if’s, and so on.