I'm trying to create a simple ansible template for the packet filter on FreeBSD 11.1-RELEASE. I have vtnet0 (public), vtnet1 (private, 10.10 address) and tun0 (openvpn, fully working/tested from a client to nodes on my network).

My rc.conf looks like the following:

ifconfig_vtnet0_ipv6="inet6 accept_rtadv"
ifconfig_vtnet1="inet netmask"

My cloud provider gives me ipv4/ipv6 public addresses via DHCP.

I've looked at the FreeBSD docs and other ansible playbooks and came up with this basic pf.conf:

block all
set skip on lo0
set skip on tun0
pass out all keep state
tcp_services = "{ ssh }"
udp_services = "{ openvpn }"
pass in proto tcp to any port $tcp_services keep state
pass in proto udp to any port $udp_services keep state

However with this configuration, I block all ssh and openvpn access and have to login to my box via the VM web console.

My goal is for this box to only allow in openvpn (udp) and ssh from the public interface, allow all traffic over the vpn (tun0) and all traffic from internal.

1 Answer 1


Setting up pf may be a bit of a hassle. You need to understand that pf treats all interfaces absolutely equally and there is no concept of packets originating on the box itself as there is in iptables -- OUTPUT chain. I would start with something along these lines and build on that:

# allow all from host itself
pass out inet all keep state
pass out inet6 all keep state
# allow all from private
pass in quick on vtnet1 inet from any to any keep state
# openvpn
pass in quick proto udp to vtnet0 port openvpn keep state
pass in quick on tun0 inet from any to any keep state
# ssh
pass in quick proto tcp to vtnet0 port ssh flags S/SA keep state

Warning: Don't use standard openvpn and ssh ports.

  • I put in an edit to have the inet6 rules on the public services (the private interface only has an ipv4 address, so it was failing validation). However if I add block all, I lose all network connectivity. Without the block all, I can still run services on other ports. Does the rule order matter? Should blocking go at the end?
    – djsumdog
    Aug 23, 2017 at 5:13
  • One more thing, I'm not married to pf. I'm a little confused by FreeBSD's three firewall options. I'm fine with using another option if it makes more sense in this situation.
    – djsumdog
    Aug 23, 2017 at 5:26
  • The order matters: the last match wins. You have to keep block all at the top. Let's focus on making ssh work. Change my top three rules to: pass from { self, vtnet1 } to any keep state and replace bottom two with pass in proto tcp to vtnet0 port ssh. Also, is it a real gateway? If so, you need at the very top nat on vtnet0 inet from vtnet1:network to any -> (vtnet0). Aug 23, 2017 at 11:56
  • So I'm not using this box as a gateway (each box in the private network just has a static route back to it from the openvpn subnet). I put in another edit and this one seems to work perfectly. I only have two ports exposed on public, and everything private/openvpn(tun0) works correctly. What do you think?
    – djsumdog
    Aug 24, 2017 at 18:16
  • I am not a big fan of skips unless absolutely necessary. Check out the latest edit and let me know if it works like that. Aug 25, 2017 at 0:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.