My research shows that there's no pf.conf
clause that will get you this level of one-to-one expansion of rules.
I was hoping that you could do this with macros, which in your case would be something like:
vhost_ips = "{ 198.51.100.4, 198.51.100.5 }"
rdr pass on $ext_if proto tcp from any to $vhost_ips port 80 -> $ext_ip port 8080
rdr pass on $ext_if proto tcp from any to $vhost_ips port 443 -> $ext_ip port 8443
... but if the macro is used more than once on the same line, it actually expands the latter ones to the entire macro, and invokes round-robin:
rdr pass on int0 proto tcp from any to 198.51.100.4 port 80 -> { 198.51.100.4, 198.51.100.5 } port 8080 round-robin
rdr pass on int0 proto tcp from any to 198.51.100.5 port 443 -> { 198.51.100.4, 198.51.100.5 } port 8443 round-robin
... which I'm pretty sure was not what you intended. :-) Tables also appear to be out. The man page explicitly says:
"Tables can also be used for the redirect address of nat and rdr rules and in the routing options of filter rules, but only for round-robin pools."
So unfortunately, it looks as though your only option is to either manually maintain the list, or generate it as a separate file and include it.
Also unfortunately, the include
clause is not mentioned in the pf.conf
man pages on my 7.4, 8.2 or 9.0-RC2 systems, so if you are running the stock PF that comes with FreeBSD, I believe that they are running the PF imported from OpenBSD 4.5, which doesn't appear to support include
... but just in case, here's a way to generate the include:
$ cat vhost.list
198.51.100.4
198.51.100.5
$ cat gen-vhosts-pf.sh
#!/bin/sh
for ip in `egrep -v ^# /etc/vhost.list`; do
echo "rdr pass on \$ext_if proto tcp from any to $ip port 80 -> $ip port 8080"
echo "rdr pass on \$ext_if proto tcp from any to $ip port 443 -> $ip port 8443"
done
$ ./gen-vhosts-pf.sh | sudo tee /etc/pf.conf.vhosts
rdr pass on $ext_if proto tcp from any to 198.51.100.4 port 80 -> 198.51.100.4 port 8080
rdr pass on $ext_if proto tcp from any to 198.51.100.4 port 443 -> 198.51.100.4 port 8443
rdr pass on $ext_if proto tcp from any to 198.51.100.5 port 80 -> 198.51.100.5 port 8080
rdr pass on $ext_if proto tcp from any to 198.51.100.5 port 443 -> 198.51.100.5 port 8443
... which would be imported into pf.conf with:
include "/etc/pf.conf.vhosts"
If you're not running a PF that supports includes, it'll be a little trickier, but you get the idea.
Sorry for the slightly scattered research; I also couldn't find a canonical way to ask PF for its version information, so had to flail around a bit.
EDIT: You may be able to do the including with the load anchor
clause, though it appears you will have to repeat your $ext_if
macro within the anchor.