Setting up Zero Trust on pfSense

The Zero Trust Model is the most secure way to control egress. For clarity, here are the elements of our zero trust model:

  • Operating in whitelist mode (block all, allow some)
  • Feature enabled (with appropriate plan): Don’t Talk To Strangers
  • Default LAN Allow All rule removed , or at least disabled

This approach ensures that no device can make an outbound connection of any kind, no matter the protocol, destination, or port. If you try to make a connection to say to one of Google’s IPs on TCP port 443, here’s what you’ll get:

curl https://216.239.38.120 … this connection fails with:
curl: (7) Failed to connect to 216.239.38.120 port 443: Connection refused
However, compare with this one:
curl https://www.google.com … this connection succeeds!
Another example:
PING 8.8.8.8 (8.8.8.8): 56 data bytes92 bytes from google-public-dns-a.google.com (8.8.8.8): Destination Host Unreachable
And yet this one…
$ ping google-public-dns-a.google.comPING google-public-dns-a.google.com (8.8.8.8): 56 data bytes64 bytes from 8.8.8.8: icmp_seq=0 ttl=59 time=16.982 ms

The difference is that when a successful (non-blocked) DNS query is answered, a temporary outbound firewall hole is opened for the period of the TTL.

Assuming you are starting from a default installation of mostly-default pfSense settings, here are your steps:

  1. Contact support to change your plan to allow for DTTS (Don’t Talk To Strangers) feature set
  2. Log into your dashboard -> Advanced -> Enable DTTS as shown here:
  3. Create (and enable) a LAN Firewall Rule to allow LAN DNS queries
  4. Create (and enable) a LAN Firewall Rule to allow LAN port 80 access for the block page to function
  5. Turn off your pfSense default LAN Allow All rule (shown here as disabled as they are unbolded) or, alternatively check “Automatically manage DTTS rules in firewall” in Services -> adam:ONE
    :
  6. Create any required Firewall Rules

Most environments that choose the Zero Trust Model end up with at least a few “misbehaving” apps that require special permission to make Internet-bound connections without preceding DNS queries. In cases like this, Enablers are needed as outlined here: Enablers on pfSense

All attempted (but dropped) dns-less traffic can also be observed following the troubleshooting article here: Troubleshooting services behind DTTS® in pfSense

A few comments i like to add from my experience:

  1. If you use DTTS on pfsense, don’t use the enablers on the dashboard, as they will lock up the pfsense, rather use the rules in the firewall.
  2. Disable IPv6 or IPv4 prior to enabling DTTS, as DTTS doesn’t support Dual Stack. (this can cause disruptions with the internet, if both are enabled with DTTS)

Where exactly do you disable ipv6?

All you need to do is ensure that no IPv6 address (either via tracked interface or static) is on the LAN interface and IPv6 will be effectively disabled.

For anyone concerned that we are recommending to disable IPv6, the issue is primarily with dual-stack. If a client is able to run IPv6-only on their internal network by using NAT64 then instead we would recommend disabling IPv4 on the LAN interface.