Saturday, October 10, 2020

How To Host Your Own DNS-over-HTTPS And DNS-over-TLS Services

With Technitium DNS Server, you can not just consume DNS-over-HTTPS (DoH) or DNS-over-TLS (DoT) services using forwarders but you can also host these services yourself. There can be several reasons to host your own DoH or DoT service. You may wish to have better privacy by not sharing your data with public DNS providers. Or your network or ISP blocks popular DoT and DoH services and also interferes with unencrypted DNS traffic.

In this post, we will setup DoT and DoH services on a cloud server and configure a locally running Technitium DNS Server to use the DoH service as a forwarder bypassing any network restrictions that may be in place. 

Home Network

In the about home network diagram, the locally running Technitium DNS Server is installed on a desktop PC or a Raspberry Pi that is connected to your WiFi router. The Cloud Linux server will host the DoH service which will be configured as a forwarder in the locally running DNS server on your network.

Once the configuration is complete, all DNS traffic will be encrypted between your locally running DNS server and the DoH server running on the cloud server. This effectively means that all your local DNS traffic will exit from the cloud server and thus wont be visible to your network provider or your ISP.

Requirements

You need a domain name which you can get from any domain name registrar like Name.com (referral link). If you already own a domain name then you can use a sub domain on it for hosting these services. A domain name is required since both these services run over TLS protocol which uses SSL/TLS certificate to work. A domain name will usually cost around $13/yr which depends on the extension. You can check for the pricing here.

You need a Linux server which you can get from any cloud hosting provider like Digital Ocean (referral link). You can get a server for as low as $5/mo with 1GB RAM. I would recommend to create a server with Ubuntu Server as the OS since this blog post will be using the same.

Installation

We will be using Ubuntu server in this blog post but you can choose any distro of your choice and follow similar instructions.

You can install Technitium DNS Server using the single line installation command as shown:

curl -sSL https://download.technitium.com/dns/install.sh | sudo bash

If the above command fails since you do not have curl installed, install it as shown below and try the above command again:

sudo apt update
sudo apt install curl

You can also manually install the DNS server by following the install instructions.

We will be using Let's Encrypt TLS certificate and will be using certbot which does automatic certificate renewal for Let's Encrypt. Run the commands below to install certbot:

sudo apt update
sudo apt install certbot

Configuration

To proceed with the DNS configuration, login to the DNS server web console using the server's IP address and port 5380. For example, if your server's IP address is '1.2.3.4' open http://1.2.3.4:5380/ in your web browser. Chrome, Firefox and Edge web browsers are supported well.

The first configuration to be done is to enable Optional DNS Server Protocols i.e. DNS-over-HTTPS and DNS-over-TLS in the DNS server Settings as shown below:

Optional DNS Server Protocols
Optional DNS Server Protocols

Note: If you wish to only run DoH service, enable only the DNS-over-HTTPS protocol in the settings.

Save the settings by clicking Save Settings button at the bottom and restart the DNS server using this command:

sudo systemctl restart dns

Note: It is important to restart the DNS server after enabling DNS-over-HTTPS optional protocol to allow the server to start a web server on port 80 which is required when generating the TLS certificate using certbot.

We also need to create a root directory for the DoH web server:

sudo mkdir /etc/dns/dohwww

Now, we can run certbot command with the webroot plugin to issue the TLS certificate as shown below:

sudo certbot certonly --agree-tos --email admin@example.com --webroot -w /etc/dns/dohwww -d dns.example.com

Note: Here, replace 'example.com' with your domain name. In this example, we have used 'dns.example.com' in which the sub domain 'dns' gives a good idea that you may be running a DoH service. You may wish to avoid this by not using sub domain names like dns, doh or dot and instead use something which is very common like "mail", or "blog", etc. This will make it difficult for someone on your network to identify if you are using a DoH service by looking at the domain name.

Once the certbot command succeeds, you will see the path of the certificate that was generated in the output which should be in the /etc/letsencrypt/live/<your-domain>/ directory.

Below is the output that you should see if the certbot command succeeds.

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for dns.example.com
Using the webroot path /etc/dns/dohwww for all unmatched domains.
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/dns.example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/dns.example.com/privkey.pem
   Your cert will expire on 2021-01-08. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Since, the DNS server requires the certificate in PKCS #12 (.pfx) format, we need to convert the issued certificate using the openssl command. We will create a small script file at /etc/dns/pkcs12convert.sh which contains the openssl command so that the script can be reused later.

echo "openssl pkcs12 -export -out /etc/letsencrypt/live/example.com/example.com.pfx -inkey /etc/letsencrypt/live/example.com/privkey.pem -in /etc/letsencrypt/live/example.com/cert.pem -certfile /etc/letsencrypt/live/example.com/chain.pem -passout pass:mypassword" | sudo tee /etc/dns/pkcs12convert.sh > /dev/null

sudo chmod +x /etc/dns/pkcs12convert.sh

Here, replace 'example.com' with your domain name and 'mypassword' with a password of your choice or keep it blank to generate the pfx file with no password.

Lets run the script that we just created so that it generates the pfx certificate file.

/etc/dns/pkcs12convert.sh

Now, we can configure the DNS server with the pfx certificate file path in the settings as shown below:

Optional DNS Server Protocols With TLS Certificate
Optional DNS Server Protocols With TLS Certificate

Type in the same password that you had used while generating the pkcs12 certificate for the TLS Certificate Password option.

Save the settings by clicking the Save Settings button at the bottom and restart the DNS server again using the command below so that the DNS server can start the DoT and DoH services using the newly configured TLS certificate.

sudo systemctl restart dns

Once the DNS server starts, your DoT and DoH services are ready to be used. You may want to check the DNS Server logs from the web console to find out if there were any errors while starting these services.

Testing The Service

For DoT service, you need to use the domain name that was used to generate the certificate with port 853. Thus your DoT configuration for clients will be tls-certificate-domain:853.

For DoH service, you need to use the domain name that was used to generate the certificate in a URL format. Thus you DoH configuration for clients will be https://tls-certificate-domain/dns-query.

You can test both the DoH and DoT services using the DNS Client tool. Put in the DoT tls-certificate-domain:853 or the DoH url https://tls-certificate-domain/dns-query as the Server in the DNS Client, type in a domain name, select an appropriate protocol either TLS or HTTPS and click Resolve to test both the services.

Note: By default, the "Allow Recursion Only For Private Networks" recursive resolver option (as shown below) in the DNS server settings is enabled and thus the DNS server will refuse to respond with an answer (RCODE=Refused) when you test it with the DNS Client. You will need to disable this option to be able to use these services from the public Internet.

Recursive Resolver Options
Recursive Resolver Options

Once the tests are successful, you can configure your locally running Technitium DNS Server to use these services as a forwarder. Once you have configured the service as a forwarder your local DNS traffic will bypassing all your network or ISP restrictions.

Technitium DNS Server Forwarder Configuration
Technitium DNS Server Forwarder Configuration

Auto Renewing TLS Certificate

Since, the certificate obtained from Let's Encrypt expires in 90 days, we need to configure auto renewal mechanism so that we do not have to manually renew the certificate ever again. The certbot utility will automatically configure a cron job so that the TLS certificates are renewed. But since the DNS server requires a PKCS #12 certificate, we need to add the --renew-hook option and provide the openssl command that we used earlier to convert to PKCS #12 certificate.

The cron job file is located at /etc/cron.d/certbot. We need to edit the file to add the --renew-hook option as shown below. Here we will be using the pkcs12convert.sh script that we created earlier.

# /etc/cron.d/certbot: crontab entries for the certbot package
#
# Upstream recommends attempting renewal twice a day
#
# Eventually, this will be an opportunity to validate certificates
# haven't been revoked, etc.  Renewal will only occur if expiration
# is within 30 days.
#
# Important Note!  This cronjob will NOT be executed if you are
# running systemd as your init system.  If you are running systemd,
# the cronjob.timer function takes precedence over this cronjob.  For
# more details, see the systemd.timer manpage, or use systemctl show
# certbot.timer.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew --renew-hook "/etc/dns/pkcs12convert.sh"

To test the certbot renewal process, we can run the dry run command. If there are no errors reported then it means the renewal was successful.

sudo certbot renew --dry-run

Running DoH With Another Web Server

You may have a requirement to run both the DNS server with DoH service and another web server for hosting websites. In such cases since both the DoH service and the web server would require to use ports 80 and 443, it would create a conflict.

A solution in such a scenario is to use the web server as a reverse proxy to the DoH service. You will need to configure the web server with TLS certificate and virtual hosting to reverse proxy to http://127.0.0.1:8053/dns-query and enable only the DNS-over-HTTP optional DNS server protocol as shown below.

Optional DNS Server Protocols With TLS Certificate
Optional DNS Server Protocols With TLS Certificate

With this setup, your web server will terminate TLS and do reverse proxy allowing the DoH service through it. If your web server supports TLS termination for TCP streams then you can point it to 127.0.0.1:53 and also provide DoT service through it.

If you are using nginx as your web server, you can use the snippet below to configure a reverse proxy for the DoH service. For more details, you can refer to the blog post on using nginx as a DoT or DoH gateway.

server {
    listen 80;
    server_name dns.example.com;

    return 301 https://$http_host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name dns.example.com;

    ssl_certificate /etc/letsencrypt/live/dns.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/dns.example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/dns.example.com/chain.pem;

    access_log /var/log/nginx/dns.example.com-access.log;
    error_log /var/log/nginx/dns.example.com-error.log;

    location / {
        proxy_pass http://127.0.0.1:8053/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Host $http_host;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Nginx-Proxy true;

        proxy_redirect off;
    }
}

Conclusion

Using Technitium DNS Server combined with certbot, you can setup DoH and DoT services with automatic TLS certificate renewal. If you already have a web server like nginx running, you can use it for TLS termination and provide both DoH and DoT services on the same server.

If you have any queries do let me know in the comments below or send an email to support@technitium.com.

Sunday, July 19, 2020

How To Disable Firefox DNS-over-HTTPS On Your Network

Firefox includes a quite useful option since more than a year now that enables the web browser to use DNS-over-HTTPS (DoH) protocol to encrypt all the DNS requests on the network. This feature promises enhanced privacy to users such that anyone on your network path, like your ISP, wont be able to monitor or log your DNS traffic. The DoH protocol also protects your DNS requests from Man In The Middle (MITM) attacks which are possible with the default unencrypted UDP based DNS requests.

While, DoH is a really interesting feature to have from privacy perspective, it is Firefox's implementation that is a bit controversial. Firefox has deal with two public DNS providers, Cloudflare and NextDNS, in its Trusted Recursive Resolver (TRR) program which lists these providers directly into the web browser's DoH options. The controversy is Firefox enabling DoH for users automatically with an opt-out policy.

Not just Firefox but, Google Chrome and Microsoft Windows 10 is also implementing DoH support. Google Chrome's approach is a bit different from Firefox. Chrome will upgrade to use DoH protocol if you are already using a public DNS provider that supports DoH protocol. Microsoft is experimenting with a similar DoH upgrade approach with Windows 10 insider builds.

Firefox's opt-out policy bypasses the local network policies by not using the DNS servers provided by the network administrators. This creates headache for network administrators who wish to keep track or filter DNS traffic for security or other reasons. This is an issue even with people who use DNS based filtering software on their home network.

To help network administrators, Firefox has introduced a Canary domain to disable DoH on their networks. Using this canary domain (use-application-dns.net), a network administrator can signal Firefox on their networks to disable the automatic switch to DoH. However, its important to note that if a user configures DoH manually, then the canary domain signal is ignored by the web browser.
Note: The canary domain only applies to users who have DoH enabled as the default option. It does not apply for users who have made the choice to turn on DoH by themselves.
To disable DoH on your network, you need to either block the canary domain entirely such that the DNS server responds with a NXDOMAIN response code or that the server returns an empty response with no A or AAAA records.

You can do this configuration on your Technitium DNS Server setup by simply adding an empty zone for the canary domain. The zone once added must look like as shown in the screenshot below:

Firefox Canary Domain Zone Configuration
Firefox Canary Domain Zone Configuration
With this configuration, you can ensure that Firefox on your network wont automatically switch to using DoH protocol bypassing your local network DNS servers.

Let me know if you have any queries in the comments below or send an email to support@technitium.com.

Technitium DNS Server And Mesh Archived In Arctic Code Vault

I just discovered this exciting news that Technitium DNS Server and Technitium Mesh has been archived by the GitHub Archive Program in the Arctic Code Vault!

Arctic Code Vault
GitHub Arctic Code Vault

GitHub Archive Program's mission is to preserve open source software for future generations by storing public open source code repositories in an archive built to last a thousand of years.

GitHub took a snapshot of all active public open source repositories on 2nd Feb, 2020 to archive in the code vault. The total data of 21 TB was stored using digital photo sensitive archive film designed to last for a thousand years.

Arctic Code Vault Contributor Badge!

To recognize and celebrate the contributions of all the software developers, GitHub now shows a badge on the GitHub profile page. Hovering on the badge shows some of the repositories that were included in the archive.

I hope they do the archive again in coming years since the current archive contains old version with quite a few bugs!

Sunday, July 12, 2020

How To Enforce Google Safe Search And YouTube Restricted Mode On Your Network

With the release of Technitium DNS Server v5, a new feature called ANAME resource record has been introduced. ANAME resource record implementation is similar to the IETF draft with respect to its core functionality that allows adding a CNAME like functionality to the zone root. Essentially, ANAME is similar to CNAME except that the authoritative DNS server resolves the A or AAAA records by itself and returns them.

The new release also adds Conditional Forwarder feature that can be combined with the ANAME feature to enforce Google's Safe Search or YouTube's Restricted Mode.

To configure Google's Safe Search, you need to add a new "google.com" Conditional Forwarder zone with "Use This DNS Server" option enabled. The "Use This DNS Server" option tells the DNS Server to forward all the queries to itself so that you do not need to configure any other DNS server as a forwarder. This option is useful in scenarios like the current one where you just need to override a few records for a particular zone but still wish that the other records in the zone to be resolvable as usual.

Add New Conditional Forwarder Zone

Once you have added the zone, you need to add a CNAME record that points "www.google.com" to "google.com" and another ANAME record that points "google.com" to "forcesafesearch.google.com". Check the screenshot below to know how the records should look like.

Enforcing Google Safe Search

You can now test this by clicking on the DNS Client tab and querying for "www.google.com". Now open "www.google.com" in your web browser and try doing a search and notice the Safe Search option on the top right corner.

Similarly, to configure YouTube's restricted mode, you need to add a new "youtube.com" Conditional Forwarder zone with "Use This DNS Server" option enabled. Once the new zone is added, you need to add a CNAME record that points "www.youtube.com" to "youtube.com" and another ANAME record that points "youtube.com" to "restrict.youtube.com". This will enforce "Strict Restricted Mode".  To enforce "Moderate Restricted Mode" you need to point your ANAME record to "restrictmoderate.youtube.com" instead. Once you have configured the records, they should look as shown the screenshot below.

Enforcing YouTube Strict Restricted Mode

You can now test this too with the DNS Client tab by querying "www.youtube.com". You can open "www.youtube.com" in your web browser and check if the restricted mode is working by searching with any keyword.

The Conditional Forwarder zone is quite useful that not only you can forward queries to one or more DNS providers by adding one or more FWD records, you can override records that you wish and have the zone resolve as usual for other records.

If you have any queries, do let me know in the comments section below. For any feedback or support do send an email to support@technitium.com.

Sunday, July 5, 2020

Technitium DNS Server v5 Released!

I am really happy to announce the release of Technitium DNS Server v5. This version is a major upgrade with many new core features, a lot of memory and CPU optimizations, and multiple bug fixes done. Download the latest update now!

Technitium DNS Server v5

Technitium DNS Server is a free, open source software that can be used by anyone be it a novice or an expert user. The server aims to have a user friendly approach, providing an easy to use web based GUI, and with defaults that allow the server to run out-of-the-box.

The DNS server can be used to self host domain names, used as a local resolver on a desktop or laptop computer, or used as a DNS server for the entire local network. It supports many useful and powerful features like blocking domain names using block lists, overriding records for any domain, use forwarders or conditional forwarders with DNS-over-TLS or DNS-over-HTTPS, and host your own DNS-over-TLS or DNS-over-HTTPS service.

The DNS Server is cross platform and can run on Windows, Linux and macOS. It has small footprint and thus can run even on a Raspberry Pi.

Once you have used Technitium DNS Server, you will realize how powerful it is and how silly it is to rely on your ISP's DNS servers.

Conditional Forwarder Zone

Features that you may find interesting in this release:
  • QNAME minimization support in recursive resolver for privacy.
  • ANAME propriety record support to allow using CNAME like feature at zone root.
  • Primary and Secondary zone support with NOTIFY implementation and zone transfer support. 
  • Stub zone support that allows the DNS server to keep track of the name servers of the zone.
  • Conditional Forwarder zone support which allows to configure multiple forwarders for a specific domain name with all protocol support including DNS-over-HTTP or DNS-over-TLS protocols.
  • Ability to override records of a live domain name using conditional forwarder or stub zone. This allows you to easily implements things like forced Google safe search or YouTube's restricted mode.
  • Concurrent querying with more than one forwarder allows to get fastest response from multiple forwarders.
  • Option to change the DNS Server local ports for TCP and UDP protocols. 
Read the change log to know more in details about the latest release.

Conditional Forwarder Zone with Overridden Records For Google Force Safe Search

The DNS Server code has been optimized for CPU, memory and concurrency. The server now notably has a very small memory footprint which allows loading a couple of million blocked domain names easily via the blocks list URLs on a Raspberry Pi with just 1 GB RAM. The time it takes to load the blocked lists too has improved significantly.

The DNS server now internally uses a new ByteTree data structure which is a complete lock less implementation allowing concurrent threads to do read and write operations. This allows the DNS server to handle large amount of concurrent requests easily while also allowing it to update the cache data parallelly.

With the limited hardware that is available with me for testing, the DNS server was load tested on a machine with Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz on a 1 Gbps wired Ethernet network. The server could resolve more than 2 million requests per minute with an average 30% CPU utilization consistently for 3 hours. The client machine that was used to bombard requests however would peak out at 100% CPU preventing from adding any more load on the server for the load test. This update is supposed to fix issues in the previous version that caused the CPU to peak, failing to handle load more that couple of thousand requests per second.

Any comment or feedback is really appreciated and helps a lot in adding new features and fixing bugs. Do send your feedback or support requests to support@technitium.com. For any feature request or reporting bug, do create an issue on GitHub.

The DNS Server code is available under GNU General Public Licence (GPL) v3 on GitHub.

You can now make your contributions to Technitium by becoming a Patron and help in developing new software, updates and adding more features possible. Become a Patron now!