Skip to content

Instantly share code, notes, and snippets.

@uraimo
Last active March 22, 2024 20:55
Show Gist options
  • Star 86 You must be signed in to star a gist
  • Fork 18 You must be signed in to fork a gist
  • Save uraimo/c651cbf3477994f95d8dbc7c60031697 to your computer and use it in GitHub Desktop.
Save uraimo/c651cbf3477994f95d8dbc7c60031697 to your computer and use it in GitHub Desktop.
Configure your Mac to use DNS over TLS

Switching to DNS over TLS on macOS

How to configure your Mac to use DNS over TLS in five easy steps:

  1. Install Stubby with Homebrew (https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Daemon+-+Stubby):

     brew install stubby
    
  2. Edit the configuration file:

     vim /usr/local/etc/stubby/stubby.yml
    
  3. Remove the default DNSes an replace them with Quad9 and Cloudflare:

     upstream_recursive_servers:
     # IPv4 addresses
     # Quad9 with EDNS
     - address_data: 9.9.9.11
       tls_auth_name: "dns.quad9.net"
       tls_pubkey_pinset:
       - digest: "sha256"
         value: /SlsviBkb05Y/8XiKF9+CZsgCtrqPQk5bh47o0R3/Cg=
     # Cloudflare
     - address_data: 1.1.1.1
       tls_auth_name: "cloudflare-dns.com"
       tls_pubkey_pinset:
       - digest: "sha256"
         value: V6zes8hHBVwUECsHf7uV5xGM7dj3uMXIS9//7qC8+jU=
     # Quad9 with EDNS
     - address_data: 149.112.112.11
       tls_auth_name: "dns.quad9.net"
       tls_pubkey_pinset:
       - digest: "sha256"
         value: /SlsviBkb05Y/8XiKF9+CZsgCtrqPQk5bh47o0R3/Cg=
     # Cloudflare
     - address_data: 1.0.0.1
       tls_auth_name: "cloudflare-dns.com"
       tls_pubkey_pinset:
       - digest: "sha256"
         value: V6zes8hHBVwUECsHf7uV5xGM7dj3uMXIS9//7qC8+jU=
    

    And also verify that Stubby is configured to use DNS over TLS:

     dns_transport_list:
       - GETDNS_TRANSPORT_TLS
       
     tls_authentication: GETDNS_AUTHENTICATION_REQUIRED  
    
  4. Start the stubby service using the daemon plist provided by Homebrew:

     sudo brew services start stubby
    
  5. Replace the current DNS configuration to use 127.0.0.1:

     sudo /usr/local/opt/stubby/sbin/stubby-setdns-macos.sh
    
  6. Verify that everything is working as expected (use dig or nslookup):

    dig www.google.com
    
@jim-obrien-orig
Copy link

The digest value under tls_pubkey_pinset may be out of date. To get the latest run:

echo | openssl s_client -connect '1.1.1.1:853' 2>/dev/null | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

@4cm4k1
Copy link

4cm4k1 commented Jan 27, 2020

Thank you for this.

I successfully set up my Mac with the following edits to stubby.yml if anyone else finds it useful. The redacted entries are from my personal DNS resolver (https://github.com/AdguardTeam/AdGuardHome). I also updated tls_pubkey_pinset for the third-party DNS resolvers using @jim-obrien-orig's one-liner.

upstream_recursive_servers:
############################ DEFAULT UPSTREAMS  ################################
####### IPv4 addresses ######
# [REDACTED]
  - address_data: [REDACTED]
    tls_auth_name: "[REDACTED]"
    tls_pubkey_pinset:
      - digest: "sha256"
        value: [REDACTED]
# cloudflare-dns.com
  - address_data: 1.1.1.1
    tls_auth_name: "cloudflare-dns.com"
    tls_pubkey_pinset:
      - digest: "sha256"
        value: V6zes8hHBVwUECsHf7uV5xGM7dj3uMXIS9//7qC8+jU=
  - address_data: 1.0.0.1
    tls_auth_name: "cloudflare-dns.com"
    tls_pubkey_pinset:
      - digest: "sha256"
        value: V6zes8hHBVwUECsHf7uV5xGM7dj3uMXIS9//7qC8+jU=
# dns.quad9.net - WITH EDNS
  - address_data: 9.9.9.11
    tls_auth_name: "dns.quad9.net"
    tls_pubkey_pinset:
      - digest: "sha256"
        value: /SlsviBkb05Y/8XiKF9+CZsgCtrqPQk5bh47o0R3/Cg=
  - address_data: 149.112.112.11
    tls_auth_name: "dns.quad9.net"
    tls_pubkey_pinset:
      - digest: "sha256"
        value: /SlsviBkb05Y/8XiKF9+CZsgCtrqPQk5bh47o0R3/Cg=
# dns.google
  - address_data: 8.8.8.8
    tls_auth_name: "dns.google"
    tls_pubkey_pinset:
      - digest: "sha256"
        value: PM7USAhsrJaQ3xnJXeNhowEikV81nBRJnVjAvIMXC3M=
  - address_data: 8.8.4.4
    tls_auth_name: "dns.google"
    tls_pubkey_pinset:
      - digest: "sha256"
        value: PM7USAhsrJaQ3xnJXeNhowEikV81nBRJnVjAvIMXC3M=
####### IPv6 addresses ######
# [REDACTED]
  - address_data: [REDACTED]
    tls_auth_name: "[REDACTED]"
    tls_pubkey_pinset:
      - digest: "sha256"
        value: [REDACTED]
# cloudflare-dns.com
  - address_data: 2606:4700:4700::1111
    tls_auth_name: "cloudflare-dns.com"
    tls_pubkey_pinset:
      - digest: "sha256"
        value: V6zes8hHBVwUECsHf7uV5xGM7dj3uMXIS9//7qC8+jU=
  - address_data: 2606:4700:4700::1001
    tls_auth_name: "cloudflare-dns.com"
    tls_pubkey_pinset:
      - digest: "sha256"
        value: V6zes8hHBVwUECsHf7uV5xGM7dj3uMXIS9//7qC8+jU=
# dns.quad9.net - WITH EDNS
  - address_data: 2620:fe::11
    tls_auth_name: "dns.quad9.net"
    tls_pubkey_pinset:
      - digest: "sha256"
        value: /SlsviBkb05Y/8XiKF9+CZsgCtrqPQk5bh47o0R3/Cg=
  - address_data: 2620:fe::fe:11
    tls_auth_name: "dns.quad9.net"
    tls_pubkey_pinset:
      - digest: "sha256"
        value: /SlsviBkb05Y/8XiKF9+CZsgCtrqPQk5bh47o0R3/Cg=
# dns.google
  - address_data: 2001:4860:4860::8888
    tls_auth_name: "dns.google"
    tls_pubkey_pinset:
      - digest: "sha256"
        value: PM7USAhsrJaQ3xnJXeNhowEikV81nBRJnVjAvIMXC3M=
  - address_data: 2001:4860:4860::8844
    tls_auth_name: "dns.google"
    tls_pubkey_pinset:
      - digest: "sha256"
        value: PM7USAhsrJaQ3xnJXeNhowEikV81nBRJnVjAvIMXC3M=

@uraimo
Copy link
Author

uraimo commented Jan 27, 2020

Thanks @4cm4k1, I've updated my basic setup with the new pinsets and EDNS variants.

@mrcotter
Copy link

One question. When using Google DNS, it seems that the tls_pubkey_pinset value frequently changes. At home, or at work, or in another day, the value is different. How to solve this? Currently what I do to Google DNS is removing the tls config.

@4cm4k1
Copy link

4cm4k1 commented Feb 14, 2020

@mrcotter I thought about this as well, because my personal resolver uses LetsEncrypt to renew certificates automatically every 90 days; currently, I update it manually. Eventually, I may write a script to automate this every 24 hours or so, or upon each network reconnection. When I write it, I can post a link to it here.

@archelium
Copy link

Hi, I am trying to get this to work with MacOS Big Sur, but no luck. I used to use the GUI with Catalina but that doesn't work anymore on Big Sur (it freezes the entire system when service is started). The command line version service is able to be started but internet stops working when DNS is configured in network settings. Any ideas on how to fix this problem?

@uraimo
Copy link
Author

uraimo commented Nov 27, 2020

Hey, I've upgraded to BigSur (x86 mac, stubby 0.3.0) too and it kept working for me, can you spot any errors in the log? (/usr/local/var/log/stubby/stubby.log, will have a lot of tls protocol noise)

@archelium
Copy link

Hey, I've upgraded to BigSur (x86 mac, stubby 0.3.0) too and it kept working for me, can you spot any errors in the log? (/usr/local/var/log/stubby/stubby.log, will have a lot of tls protocol noise)

Hey Uraimo thanks for the response.

StubbyManager GUI (i think 0.2.6, where did you get 0.3.0?) would freeze my entire system into an unusable state (beachballing) after login. Had to uninstall via safe mode. I did try reinstalling twice with no luck. Unfortunately I don't have the logs anymore. I'm on a 2019 MBP 16 base model. Today I just discovered that Cloudflare actually has their own client for MacOS (silly me) so I am using that now. But still doesn't explain why Stubby failed to work.

I wonder if the issue has something to do with my upgrade failing a few times (due to server congestion). By any chance are you experiencing other network problems with Big Sur? There has been something weird about my network ever since the Big Sur upgrade. If my ISP is down while I'm connected to WiFi or LAN, every app that uses the internet will launch but won't load its window until I disconnect my ethernet cable or disable WiFi (Brave, Safari, Spotify, VLC, etc.) I did block Apple's OCPS server with Little Snitch but that did not help.

@uraimo
Copy link
Author

uraimo commented Nov 27, 2020

I've installed stubby directly via homebrew and configured it as shown above, I didn't even knew that a GUI existed until today. :)
The only networking issue I've seen is that sometimes it can't connect back to wifi networks when you switch between two of them.
Note that since BigSur, LittleSnitch CAN'T block ocsp anymore afaik, you'll have to manually redirect the hostname: https://gist.github.com/uraimo/49eb390ed78b3b5b5ed2a9ea8fff99ff

@archelium
Copy link

Yeah, the problem I was having was from the GUI client, I tried but haven't quite figured out how to get it to work with command line. Pretty much all ISPs in my country forces their own DNS (government regulation aka censorship). For OCSP I see trustd blinking red on little snitch and thought it must already be blocked, but you're right, doing it via hosts file will certainly block it for sure, thanks for this!

@daturadev
Copy link

If I'm not mistaken - this is a custom configuration replicating CloudFare's WARP + functionality - but no bandwidth or VPN restrictions?

@uraimo
Copy link
Author

uraimo commented Apr 17, 2021

Hi @girlscoutfather, this is basically just the secure dns part (using cloudflare, quad9,etc...) of warp+, other kinds of traffic are not being encrypted in any way. To roll your own quasi-VPN I recommend looking into WireGuard.

@daturadev
Copy link

daturadev commented Apr 17, 2021

Hi @girlscoutfather, this is basically just the secure DNS part (using Cloudflare, quad9, etc...) of warp+, other kinds of traffic are not being encrypted in any way. To roll your own quasi-VPN I recommend looking into WireGuard.

No, this is exactly what I am looking for actually. Cloudflare WARP's GUI software does just that - they use some adapted form of WireGuard (I believe) which effectively converts this DNS config into a VPN config - rendering it impossible to use in conjunction with VPN set-ups. I was trying to figure out a way around this and this method is extremely clever. The only issue in regards to their WARP service is that their paid service, WARP+ is stated that

[They] route your internet requests to avoid Internet traffic jams, making it even better.

I'm wondering how significant or valid this claim is. Unrelated and not a huge issue, more of a personal, curious pursuit.

Little edit: doing a quick search leads me to the impression that WARP + is mobile-specific, rendering this the exact alternative I was seeking. Props to you, brother!

@tianhuil
Copy link

In case this helps anyone, my stubby is at /opt/homebrew/bin/stubby and so step 5 of the gist becomes

sudo /opt/homebrew/sbin/stubby-setdns-macos.sh

Also, the following will tell you about which configuration files are being read

stubby -h

while the following will tell you if any parsing errors came up:

sudo stubby -i

Thank you @4cm4k1 and @uraimo!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment