Quick terminal-based DNS switching

This post was originally published on thecodecousins by StanleyNguyen. I add the Linux section for more details.
Motivation
Most of us, at some point of our lives, have used at least a custom DNS servers configurations for our computers. Be it for avoiding censorship, faster browsing, security, or bypassing content restriction, we’ve all tried setting our DNS servers to some public DNS servers like one from Google (remember 8.8.8.8 and 8.8.4.4?). I myself is also no exception as I have been using 1.1.1.1 for privacy and speed. Unfortunately, having custom DNS nameservers also comes with some setbacks for someone who uses their computer all the time in all the different places. With custom DNS servers, this is what you get on a network that tries to block them (together with VPN services etc.)
Another problem that we would have with custom DNS servers is that networks’ login pages just don’t show up as the default DNS is not being used to redirect us to local network login page. Of course it would be easy to just remove the configurations as you (most likely) was the one who set them up, how hard would it be to remove? But what if we need these alternate DNS servers again? I personally find this way of manually removing and adding them back too much of a hassle. Hence, I wrapped them in a bash function that does the job for me as all lazy programmers do.
1.1.1.1
Before starting with explaining what I did in the next section, I would like to do a big shout-out to this awesome project that’s a combined effort from Cloudflare and APNIC - 1.1.1.1. It’s an effort to provide Internet users with a faster and more secure DNS (it is more than 2x faster than Google Public DNS 🚀🚀🚀). But more than just that, it is a privacy-first DNS server. Did you think only these companies like Google, Facebook trying to track all of your activities online (which can be blocked with the awesome Privacy Badger)? Your ISP also eavesdrops on whichever site you are visiting and sell these data to target you with ads, and they do it through, guess what, DNS resolvers!
1.1.1.1 protects you from all of that for a price of $0 (yes, you read that right). A FREE, fast, secure DNS server that respects your privacy - sounds too good to be true, doesn’t it? But it’s an effort towards building a better Internet. You don’t have to take my words for that, read more about it on Cloudflare’s and APNIC’s blogs.
Switching DNS nameservers via bash
As I mentioned previously, it’s too much of a hassle for me to go manually update my DNS configurations via Network Settings UI whenever I jump back and forth between school’s and home’s networks.
Naturally, I would try to figure out how to do it via my terminal.
That’s when I found out about this awesome tool that comes in-built with macOS - networksetup
.
With networksetup, changing my DNS config is as simple as
Now I can easily configure my DNS resolvers to be the same as the instructions for 1.1.1.1 by
But this is quite lengthy to type as well, even though I would prefer this over Network Preferences UI any day. So I went another level of laziness by wrapping it inside a bash function
This seems to be pretty neat and does the job, but hold on a second. How about switching it back to empty? A flag/argument to this bash function would do the job fine but I want to use the least effort as possible and save myself the mental burden of remembering whether my alternate DNS config is empty. So I thought to myself: “Why not detect the current state and switch the DNS config based on that? Like a literal switch button - you don’t have to tell what state you want it to be, just the opposite of what comes before”. With that in mind, I found this option for networksetup that would tell me the current state
It would list all of my alternate DNS servers, or print out this string There aren't any DNS Servers set on Wi-Fi
if there isn’t any.
And now I can complete my function, with some cool emojis to signify whether the config has just been applied or removed
Now I can easily switch back and forth between 1.1.1.1 and default DNS configs with just a short command dns1111
Bonus: Linux based machine
Since networksetup
is not available not Linux based OSes, we would need to use a different package that helps handle DNS nameservers called dnsmasq
.
Install it using your distro’s package manager
Installing the package will come with a config file /etc/dnsmasq.conf
for us to update the nameservers.
I have included my implementation below.
If you have a better approach, don’t hesitate to reach out to me at hung.ngn.the@gmail.com
Test
To do a lookup speed test choose a website that has not been visited since dnsmasq has been started (drill
is part of the ldns
package):
Running the command again will use the cached DNS IP and result in a faster lookup time if dnsmasq is setup correctly: