Table of Contents

PFSense - DNS - Force DNS over TLS

DNS requests are normally not encrypted, and therefore visible to your ISP to record, use for research / marketing purposes, or even (in the case of some nefarious actors) manipulate or change.

Running DNS over TLS prevents that, by encrypting your DNS traffic so that it cannot be manipulated or collected.

WARNING: DNS over TLS will increase latency for DNS lookups due to SSL handshakes.

However this is only for the first query. After that the session is reused due to caching.

Reason for this is that TLS takes longer.

To prevent this increase in latency, switch to standard port 53.


Navigate to Services → DNS Resolver.

Add the following to the Custom Options.

server:
    access-control-view: 192.168.10.0/24 bypass
    access-control-view: 192.168.20.0/24 dnsbl
    access-control-view: 192.168.30.0/24 forward
    access-control-view: 192.168.40.0/24 tls
view:
    name: "bypass"
    view-first: yes
view:
    name: "dnsbl"
    view-first: yes
    include: /var/unbound/pfb_dnsbl.*conf
view:
    name: "forward"
    view-first: yes
    forward-addr: 1.1.1.1
    forward-addr: 8.8.8.8
view:
    name: "tls"
    view-first: yes
    tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
    forward-tls-upstream: yes
    forward-addr: 1.1.1.1@853#cloudflare-dns.com
    forward-addr: 1.1.1.1

NOTE: To use DNS over TLS, you will need:

  • to specify tls-cert-bundle option that points to the local system's root certificate authority bundle.
  • allow unbound to forward TLS requests; forward-tls-upstream: yes.
  • specify any number of servers that allow DNS over TLS.

For each server you will need to specify that the connection port using @, and you will also need to indicate which is its domain name with #.

  • Even though it looks like an comment the hashtag name allows for the TLS authentication name to be set for stub-zones and with unbound-control forward control command.
  • There should not be any spaces between the @ and # markups.

Another Example

Navigate to Services → DNS Resolver

NOTE: See https://nlnetlabs.nl/documentation/unbound/unbound.conf/ for info on these options.

It is OK to set the resolver to listen on all interfaces, since the firewall rules on the WAN will prevent Internet hosts from using your resolver anyway.

WARNING: This will increase latency for DNS lookups due to SSL handshakes.

However this is only for the first query. After that the session is reused due to caching.

Reason for this is that CloudFlare's 1.1.1.1 DNS service supports TLS on port 853. TLS takes longer. Same goes for Quad9's 9.9.9.9 DNS service.

To prevent this increase in latency, switch to standard port 53, or to an alternative DNS provider that does not use TLS for example:

server:
  #ssl-upstream: yes
  #do-tcp: yes
  forward-zone:
    name: "."
    # Below 4 addresses are Cloudflare DNS SSL.
#    forward-addr: 1.1.1.1@853
#    forward-addr: 1.0.0.1@853
#    forward-addr: 2606:4700:4700::1111@853
#    forward-addr: 2606:4700:4700::1001@853
    # Non TLS.
    forward-addr: 1.1.1.1@53
    forward-addr: 1.0.0.1@53
    forward-addr: 2606:4700:4700::1111@53
    forward-addr: 2606:4700:4700::1001@53

Try other settings as needed, for instance:

server:
  do-tcp: yes
  # Speed and privacy
  minimal-responses: yes
  prefetch: yes
  qname-minimisation: yes
  rrset-roundrobin: yes
  forward-zone:
    name: "."
    # To keep local overrides and avoid slow downs.
    forward-ssl-upstream: yes
    # Below addresses are Cloudflare DNS
    forward-addr: 1.1.1.1@853
    forward-addr: 1.0.0.1@853
    # forward-addr: 2606:4700:4700::1111@853
    # forward-addr: 2606:4700:4700::1001@853

NOTE: Using ssl-upstream will cause all outgoing queries to use TLS, not just forwards, which could break Domain Overrides.

So using forward-tls-upstream instead inside the '.' zone which will only apply the TLS setting to that forwarding zone.

Testing with Google Chrome was a bit upset at first, but a chrome://net-internals/#dns and clear fixed it.

Measured a few lookups with Chrome and the network inspector, and it looks like uncached lookups are taking about 50ms. Without TLS the lookups run about 10ms.


Test

Test using an internal DNS:

dig www.google.com @pfSense.localdomain

NOTE: This should resolve against the DNS resolver on the router.

You can use use Diagnostics → Packet Capture, and capture port 853 to verify that requests are being triggered.


Test using an external DNS

Try and dig something against an IP that you know is not internal and is not a DNS server. It should work, since the request will be NATted. Something like;

dig www.google.com @8.8.8.8

Assuming that’s all fine, you should now be able to configure a broad block rule to bar all outbound port 53.


Block all outbound non-encrypted DNS

Navigate to Firewall → Rules

On the WAN interface, define a new rule at the top of the list. This rule should use these settings;

Verify that you can still resolve against the local resolver (your router’s IP), and that you can still resolve against what seems to be external resolver (e.g, 8.8.8.8).

You should also check that when you do so that nothing passes on the WAN interface on port 53.


References

https://docs.netgate.com/pfsense/en/latest/recipes/dns-redirect.html

https://nlnetlabs.nl/documentation/unbound/

https://nlnetlabs.nl/documentation/unbound/unbound.conf/

https://www.reddit.com/r/PFSENSE/comments/897boi/dns_over_tls_for_1111/

https://redmine.pfsense.org/issues/8388