The function of a DNS resolver is plain and simple: convert a domain-name into an ip-address. It starts by requesting your local operating system for an answer, which in turn forwards it to a router. The DNS resolvers configured there, which are probably some public or those of your ISP, do the rest of the work (this is overly simplified). A lot (probably all), resolvers log these request and accompanied meta-data (Google, for example, is very clear about what they log).
This means that these providers know exactly when you're visiting which websites from which IP. Apart from the fact I simply don't like this info to be logged, because we know a lot of these companies see the value of our data, setting up your own DNS resolver might also provide a nice speed improvement.
Setting up your DNS resolver using Bind9
To get this going you'll need:
- A client machine (All OS'es are allowed);
- A server machine running a Linux distribution (Ubuntu or Debian for example), on which you've got root access.
If that's the case, just follow the steps below.
1. Preparation on server
First of all, make sure to create a back-up of the following files/folders (if they exist):
Also, make sure the required packages are installed:
2. Setting up bind9 on server
Avoid DNS amplification attacks: Avoid open DNS-resolver!
Please keep in mind an open DNS resolver can be used for DDOS attacks. Therefore, you have to close your resolver either by:
- Follow the example below, define a list of trusted IPs only allow these for the
allow-query
,allow-query-cache
andallow-recursion
options; - Setup firewall rules to only allow a list of IPs you trust, we'll show
iptables
examples below.
To set up the config, first we'll comment out the /etc/bind/named.conf.options
in /etc/bind/named.conf
:
Then in /etc/bind/named.conf.local
, we'll add our own setup:
As you can see, we've defined a list of "trusted" IPs, which we allow to query or server. Please make sure you either define a list here or set up firewall rules.
Optionally, you might want to relay (forward) your queries to other public DNS servers you trust by adding the lines below into the options section. If you must use forwarding servers, I'd suggest you to use 1.1.1.1 since they (seem to) not log any info.
Then manually set up the logging directory:
To make sure you didn't make any mistakes while setting up, you can manually check the configuration files:
If you see no errors, it's finally a matter of enabling and starting (or restarting) the service:
3. Testing on server
To test if your DNS resolver is working properly, simply request a domain locally:
Inspect the output to see if there are no errors and if one or more IP's are returned.
4. Block access (avoid open resolver) on server
As stated above, you have to avoid being an open resolver, since open resolvers can be used in attacks. Therefore there are two methods to only allow one or more IP's.
a. Using iptables
If you're using an iptables-firewall, I highly recommend setting the permissions there. Simply add a rule for each of your trusted IPs:
b. Using bind configuration
If you're not using iptables, you can allow access defining your IPs in an Access Control List:
5. Set your server as primary DNS resolver on client
If you're running a desktop environment, you probably have to use steps b and c, on servers or machines with unmanaged connections, only step c will be enough.
a. DHCP Client configuration file (probably not needed)
In /etc/dhcp/dhclient.conf
change the following line:
Instead of prepend
, use supersede
to use the configured DNS exclusively.
b. NetworkManager
If you're running NetworkManager
(I belief most Linux releases with a desktop environment do), you'll need to keep it from getting the DNS servers from your connection (e.g. using your router/default gateway) instead of what you've set up locally (e.g. in your dhclient.conf
).
The best wat i.m.h.o. is to create a new file to disable the DNS resolving:
Finally restart network using systemctl restart network-manager
or /etc/init.d/network-manager restart
to apply the new settings.
c. resolv.conf
Finally, once you've kept NetworkManager
from screwing with your changes, or when your system doesn't run any network-manager at al (likely for server setups), you can set the DNS server(s) you want in /etc/resolv.conf
.
The commands above create a backup to /etc/resolv.backup
and create a new file with the ip of your DNS, change that IP accordingly.
Finally restart network using systemctl restart networking
or /etc/init.d/networking restart
to apply the new settings.
6. Testing on client
Finally, to test if your DNS server is accepting the connection and returns a proper answer, request a domain using your client. Don't forget to change the 127.0.0.2 with the IP of your DNS server:
Again, everything works, when the output has no errors and returns one ore more IP's.
Using the DNS resolver
As a starter I suggest to change the DNS settings of your router. Your router's manual probably has this covered, otherwise Google has. When your router requires a secondary DNS, just use your resolver's IP again or, if that doesn't work, use some public provider which you trust most (again 1.1.1.1). This covers all requests made from your home network. Keep in mind, any resolver you use will probably log your queries.
I suggest manually setting the DNS servers on Wifi-based clients (e.g. laptop) if you're using them at other locations than your home network. Please avoid using any apps that claim to set the DNS-records for you, since they're probably just a VPN service that log even more of your activity. So, just use the built-in settings where possible.
A note on Google Chrome
Chrome as sort of a built in DNS resolver, which you manually need to disable. To do so, go to Settings → Advanced → "Use a prediction service to load pages more quickly" and disable the checkbox.
Conclusion
Using your own DNS adds a bit more privacy to your internet activity, since DNS-requests can no longer be logged by your ISP or the public DNS service you were using. They will however still be logged by the website or service you're visiting.
A downside on DNS servers in general is that the requests are in plain text, which means they're susceptible to 'man in the middle'-attacks (MITM). In theory, your ISP could still be sniffing the packets (and even modify them to route requests trough their own servers, but if that's the case you have much larger trust issues) to find out the domain's you're visiting. Also, the response contains the domain you're visiting, thus will only be unreadable for others on the line if the response is using TLS (e.g. https).
Other solutions like "DNS-over-TLS" or "DNS-over-HTTPS" might be a solution to entirely prevent MITM-attacks, but this needs to be investigated first.
Meanwhile, just remember privacy doesn't really exist on the web.
Sources
- https://opensource.com/article/17/4/introduction-domain-name-system-dns
- https://serverfault.com/questions/761364/allow-dns-queries-to-bind-in-iptables
- https://opensource.com/article/17/4/build-your-own-name-server
- https://unix.stackexchange.com/questions/62222/how-to-test-dns-speed
- https://stackoverflow.com/questions/11153958/how-to-enable-named-bind-dns-full-logging
- https://askubuntu.com/questions/157154/how-do-i-include-lines-in-resolv-conf-that-wont-get-lost-on-reboot/685428#685428
- http://www.aitechsolutions.net/dnsservertips.html
- https://www.digitalocean.com/community/tutorials/how-to-configure-bind-as-a-caching-or-forwarding-dns-server-on-ubuntu-14-04
Changelog
- 2023-05-24
- Added
directory "/var/cache/bind";
to enable local cache, this significanly speeds up requests; - Added
auth-nxdomain no;
to confirm to RFC1035; - Added
dnssec-validation auto;
to avoid DNS Cache Poisoning.
- Added
- 2022-07-25
- Instead of defining IPs inside
allow-
options, we'll use an ACL; - Moved entire config to
named.conf.local
.
- Instead of defining IPs inside
- 2021-08-10
- Removed "
any
" keyword from example configuration, made not being / creating an open resolver even more obvious; - Added "
allow-transfer
" entry to avoid unwanted DOS-attacks, as per given example; - Use "
localnets
" configration option for listen-on entries.
- Removed "
- 2021-11-17
- Added more elaborate instructions to override DNS server with managed network connections, e.g.
NetworkManager
, falling back to good ol'resolv.conf
.
- Added more elaborate instructions to override DNS server with managed network connections, e.g.