PF Is this pf.conf ok?

Could you tell me if this /etc/pf.conf looks ok and secure? I have a machine I call GENESIS, with 2 jails labeled PRODUCTION and STAGING. I match ports 22222 with SSH on GENESIS, 33333 with SSH on PRODUCTION, and 44444 with SSH on STAGING. I match ports 80 and 443 to HTTP and HTTPS on PRODUCTION, and 8000 and 44300 to HTTP and HTTPS on STAGING. pfctl -sn seems ok, and I've verified that the ports forward as expected. However, do I need to add something else to tell it to block all other ports?

Code:
IP_GENESIS="My_Site_IPv4"  # IPv4 of my website
IP6_GENESIS="My_Site_IPv6" # IPv6 of my website
INTERFACE="vtnet0" # public interface e.g. em0
SSH="22"
WWW="{80,443}"

NETWORK_JAILS="192.168.0.0/24"
NETWORK6_JAILS="fd12:3456:789a::/112"

IP_PRODUCTION="192.168.0.1"
IP6_PRODUCTION="fd12:3456:789a::1"
SSH_PRODUCTION="33333"

IP_STAGING="192.168.0.2"
IP6_STAGING="fd12:3456:789a::2"
SSH_STAGING="44444"
HTTP_STAGING="8000"
HTTPS_STAGING="44300"

scrub in all

# IPv4
nat pass on $INTERFACE from $NETWORK_JAILS to any -> $IP_GENESIS

rdr pass on $INTERFACE proto tcp from any to $IP_GENESIS port $SSH_PRODUCTION -> $IP_PRODUCTION port $SSH
rdr pass on $INTERFACE proto tcp from any to $IP_GENESIS port $SSH_STAGING    -> $IP_STAGING port $SSH

rdr pass on $INTERFACE proto tcp from any to $IP_GENESIS port $WWW            -> $IP_PRODUCTION
rdr pass on $INTERFACE proto tcp from any to $IP_GENESIS port $HTTP_STAGING   -> $IP_STAGING port 80
rdr pass on $INTERFACE proto tcp from any to $IP_GENESIS port $HTTPS_STAGING  -> $IP_STAGING port 443

# IPv6
nat pass on $INTERFACE from $NETWORK6_JAILS to any -> $IP6_GENESIS

rdr pass on $INTERFACE proto tcp from any to $IP6_GENESIS port $SSH_PRODUCTION -> $IP6_PRODUCTION port $SSH
rdr pass on $INTERFACE proto tcp from any to $IP6_GENESIS port $SSH_STAGING    -> $IP6_STAGING port $SSH

rdr pass on $INTERFACE proto tcp from any to $IP6_GENESIS port $WWW            -> $IP6_PRODUCTION
rdr pass on $INTERFACE proto tcp from any to $IP6_GENESIS port $HTTP_STAGING   -> $IP6_STAGING port 80
rdr pass on $INTERFACE proto tcp from any to $IP6_GENESIS port $HTTPS_STAGING  -> $IP6_STAGING port 443
 
It would be a good idea to define a default blocking policy, such as:
set block-policy drop

Also skip your loopback interface:
set skip on { lo0 }

Your NAT rules could be improved, since the NAT is being done for a fixed IP. I would change to the rule below, so the address is obtained directly from the interface:
nat on $INTERFACE from $NETWORK_JAILS to any -> ($INTERFACE)

The same for rdr rules.

Note that in most cases IPv6 doesn't need NAT. Each jail can have its own external IPv6 address.
Generally, the provider give you an entire IPv6 block /64
So inside jail block, you can put something like:
ip6.addr = vtnet0|2a01:4e8:120:342e::2;
interface = vtnet0;

And for last, pass out if you want to allow all outgoing packets.

But I don't know your needs, or if you have an IPv6 block prefix-len 64 , or if you want to block other ports.
 
set block-policy drop
I thought default policy for block was to drop anyway? Wouldn't I still need a block in all?

set skip on { lo0 }
Can I do set skip on lo (without the 0)? I have group lo, which includes both lo0 and lo1 (the internal IP addresses of the Jails). Is it ok to set skip on the Jails' internal IPs?

nat on $INTERFACE from $NETWORK_JAILS to any -> ($INTERFACE)
What's the difference between this and what I have? I'm not too familiar with pf syntax.

Note that in most cases IPv6 doesn't need NAT. Each jail can have its own external IPv6 address.
I don't want the Jails to have any external address, for security reasons. I want everything to go through the host machine first.
 
Back
Top