Skip to content

Instantly share code, notes, and snippets.

@dferg
Last active April 10, 2024 11:12
Show Gist options
  • Star 49 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save dferg/0472269333be4aca6aaa21cf3b165c02 to your computer and use it in GitHub Desktop.
Save dferg/0472269333be4aca6aaa21cf3b165c02 to your computer and use it in GitHub Desktop.

Introduction

Sometimes you may want to use a DNS server for specific domain requests and another DNS server for all other requests. This is helpful, for instance, when connected to a VPN. For hosts behind that VPN you want to use the VPN's DNS server but all other hosts you want to use Google's public DNS. This is called "DNS splitting."

Here, we run dnsmasq as a background service on macOS. The dnsmasq configuration described below implements DNS splitting.

Install

brew install dnsmasq

Don't have Homebrew? Follow the instructions here: https://brew.sh

Setup

Add the following lines to $(brew --prefix)/etc/dnsmasq.conf:

# Ignore /etc/resolv.conf
no-resolv

# For queries *.domain.com and *.domain.net, forward to the specified DNS server
# Servers are queried in order (if the previous fails)
# -- Note: These are EXAMPLES. Replace with your desired config.
server=/domain.com/domain.net/IP_ADDR_OF_SERVER1
server=/domain.com/domain.net/IP_ADDR_OF_SERVER2

# Forward all other requests to Google's public DNS server
server=8.8.8.8

# Only listen for DNS queries on localhost
listen-address=127.0.0.1

# Required due to macOS limitations
bind-interfaces

Start dnsmasq

Run the following command to start dnsmasq immediately and have it start on reboot.

sudo brew services start dnsmasq

Point macOS to the new server

Via GUI

To point to the new split DNS server, follow these steps:

  1. Open up "System Preferences," click on "Network."
  2. The first interface with a green ball is your default interface. Click on it and then "Advanced."
  3. Click on the "DNS" tab.
  4. Click on "+" and type in "127.0.0.1"
  5. Click on "OK"
  6. Click on "Apply"

Via Scripting

To point to the new DNS server via scripting, run the following command (replacing "Wi-Fi" with whatever your interface name is):

sudo networksetup -setdnsservers "Wi-Fi" 127.0.0.1

To clear the DNS server change:

sudo networksetup -setdnsservers "Wi-Fi" empty

Test

Check that hosts within each of your "server=" directives resolves as expected.

dig somehost.domain.com

Check that hosts that do not match any "server=" directive go out to the default DNS server.

dig www.google.com

Troubleshooting

Flush DNS caches

If DNS queries are not behaving as expected, flush macOS's DNS cache.

sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
@adrianharabula
Copy link

Excelent snippet! I've been searching for something like this past 2 weeks. Thanks for sharing.

@xsreality
Copy link

Thanks, this worked nicely! Is there a way to configure the dynamic default DNS IP (provided by the default gateway) instead of static IP like 8.8.8.8?

@ClaytonOlleyITN
Copy link

My mac keeps reverting to the DHCP provided DNS servers even though I've set it to 127.0.0.1 in the VPN config. Anyone know of a fix?

@DGavrilets
Copy link

What should I do with this problem:

Error: Running Homebrew as root is extremely dangerous and no longer supported.
As Homebrew does not drop privileges on installation you would be giving all build scripts full access to your system.

Error: Failure while executing;
'/opt /homebrew/bin/brew tap homebrew/services' exited with 1.

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