How to get generic interface names and IPs in OpenBSD PF
Over on Twitter, I had a grump that led to me learning some things:
Since OpenBSD Ethernet interface names are tied to the physical hardware, I wish OpenBSD pf.conf syntax had an abstract name that meant 'the interface with the default route, whatever that is'.
We have straightforward OpenBSD systems with a single active interface that get installed on various hardware, with various interface names, and I would really like to not have to change their pf.conf for every different piece of hardware they get put on (physical or virtual).
Thanks to @oclsc I've now learned about OpenBSD interface group names, and reading the manpage pointed me to the predefined 'egress' group name, which means 'all interfaces with the default route'. You can use 'egress:0' to mean the (first) egress IP address.
We're not savages, so of course we use pf.conf macros in our pf.confs:
server_if = "bnx0" server_ip = 192.168.100.100 [...] pass in on $server_if from any to $server_ip port = 22
But this still means that we have to define the name of the interface
and the server's IP once. When we have two OpenBSD machines that are
clones of each other, for example two OpenVPN servers for redundancy,
this historically means that we've had to have two copies of
that are supposed to differ only in server IP.
(Usually we put the two servers on identical hardware, so the interface names are the same. If we used sufficiently different hardware that the interface names changed, we'd have to vary that too.)
However, it turns out that you can get what I want and, for simple configurations, reduce this to a completely generic version. First and well documented in the manpage for pf.conf is that you can use an interface name in PF rules in place of an IP address (cf). If you do, it means all of the IP addresses associated with that interface. If you want to not accept aliases, you can add :0 on the end to get the first one (cf). Combined with macros, we can write:
server_ip = $server_if:0
Written this way, the address is looked up once when the PF ruleset
is loaded and then substituted in. If you dump the installed rules
pfctl -s rules', you'll see the actual IPs, and the resulting
rules are exactly the same as if you'd specified the IP directly.
To get generic names for interfaces, we need to use the name of
interface groups, which
are documented in the ifconfig
manpage. Conveniently there is a predefined group that does what I
want, the '
- The interfaces the default routes point to are members of the “egress” interface group.
(There can be more than one default route pointing out more than one interface, but in normal use on our servers there is exactly one interface with a default route.)
If you don't want to rely on where the default route is pointing
you can explicitly specify a custom group in
and then use it in a macro in the PF rules. I'm not sure how to
best write this in the file, but sort of following information from
the hostname.if(5) manpage,
I found that it worked to write it on two lines:
inet 192.168.100.100 0xffffff00 group net-sandbox
All of this sounds great but it has a tiny little drawback, which is that it makes your PF configuration a bit more magical. Explicitly writing out the interface name and IP may be annoying some of the time, but it's always extremely obvious what is going on. You don't have to try to remember what 'egress' or 'net-sandbox' means when used as an interface name (or an IP address); it's always right there. Also, you're absolutely guaranteed that your rules are matching only a single IP address or a single interface. With interface group names, you're relying on the rest of your configuration to insure that there is only ever one 'egress' or 'net-sandbox' interface, no matter what you do to the machine.
A related issue is that the meaning of 'egress', 'net-sandbox', and the
like can change between PF ruleset loads (and the associated IPs along
with them), without any direct changes to pf.conf. This means that you
can boot with the system in one setup, change it for some reason, do a
pfctl -f /etc/pf.conf' with an unchanged pf.conf, and wind up with
a different set of rules. In some environments this is a feature; in
others it is a drawback, or at least a potential unpleasant surprise.
(What triggered this otday was testing out a version of our OpenBSD VPN
servers on the current OpenBSD in a virtual machine. Of course I needed
pf.conf, but my virtual machine had both a different IP
address and a different interface than the current real servers.)
Some thoughts about low power loads and power supply efficiency
I was recently reading another guide to power supply units (PSUs), which repeated the common advice that you shouldn't over-size your PC's power supply because its efficiency drops significantly at low loads. The general guideline I've read is that a PSU needs to operate at around half load for optimal performance, and it's common for a power supply's efficiency to plummet below 15% or 10% of its load. This time around, reading all of that made me suddenly twitch.
Both my home machine and my office machine have 550 watt PSUs, and they often draw only 40 to 60 watts. My home machine has to work hard to get about 150 watts of power draw, which is under 30% load. This means that I am definitely on the comparatively not great portion of the PSU loading curve.
(How bad it is is an interesting question. Both machines have the same PSU, certified as an '80 Plus Gold' efficient unit. Via Wikipedia, I discovered that certification reports are online here. This contains a test down to an input of 66 watts (giving 56 watts of output), at 84.6% efficiency. This seems not all that terrible to me.)
Does this matter? On the large scale of things, I think probably not. Almost all of the reported power draw from these machines gets turned into heat in the end (some of it turns into noise and air motion from fans). More or less PSU efficiency only changes where the heat is generated, and it may be better to generate the heat in the PSU if the PSU is better ventilated.
On the small scale of things, I would rather generate less heat in total while getting the same amount of work done as fast as before (at least during the summer). But at the same time, low power PSUs are apparently not a very popular market segment, so there aren't many options that are highly efficient (especially if you don't want to spend an arm and a leg). It's possible that my current PSU, oversized as it is, is still my most efficient option for machines that idle around 50 watts of power draw.
The corollary to this low load issue is that this means my power consumption numbers are not quite measuring what it looks like. When I measure an idle power draw of 66 watts for my work machine, that's the PSU's input power; it's actually outputting 56 watts to the motherboard, the CPU, and other components. If I changed the PSU to a higher efficiency one, the input power draw would drop although the power consumption of the components hasn't changed (and similarly for a lower efficiency PSU).
The measurement is fair and accurate in the sense that it's measuring the power usage of the entire system, including the PSU. But it means that I mostly can't make confident declarations about the relative power usage of various components of my machines, because the measured power draws are affected by both differences between PSUs and differences in PSU efficiency at various load levels.
(Since my home and office machines have the same PSU, one of these factors is eliminated in that comparison. But if I compare these machines to my previous set of numbers, the PSU is definitely a factor. My 2011 machines used the PSU supplied with the case, an Antec Neo Eco 620C, which was likely only 80 Plus Bronze and 82.7% efficient at a 10% load draw of 77 watts or so.)