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 above 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. Save the settings by clicking Save Settings button at the
bottom.
|
Optional DNS Server Protocols
|
Note: If you wish to only run DoH service, enable only the
DNS-over-HTTPS protocol in the settings.
Since, the DNS server requires the certificate in PKCS #12 (.pfx) format, we
need to convert the issued certificate using the openssl command. To do that,
we will create a small script file at
/etc/letsencrypt/renewal-hooks/post/pkcs12convert.sh
using
nano
editor.
sudo mkdir -p /etc/letsencrypt/renewal-hooks/post/
sudo nano /etc/letsencrypt/renewal-hooks/post/pkcs12convert.sh
Copy the commands as show below in the nano editor. 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.
#!/bin/sh
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
echo "pkcs#12 generated!"
Save the script by exiting the editor using CTRL+X
keys. We need
to make this script excutable by using the following command:
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/pkcs12convert.sh
This pkcs12convert.sh
script will be automatically executed by
certbot after renewing the certificate.
We also need to create a root directory for the DoH web server so that it can
be used with certbot as a web root:
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 certificate has been issued for the first time, we need to manually
executed our pkcs12convert.sh
script once to generate the pfx
certificate.
sudo /etc/letsencrypt/renewal-hooks/post/pkcs12convert.sh
We can now configure the DNS server with the pfx certificate file path in the
settings as shown below:
|
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 so
that the DNS server can start the DoT and DoH services using the newly
configured TLS certificate. 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
|
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
|
You can also configure your Firefox web browser directly with the custom DoH
URL. This will work only for Firefox and all other applications on your
computer will keep using the default DNS server configured in your network
settings.
To configure Firefox with custom DoH, go to Options > General and
scroll down to find Network Settings. Click on the
Settings button and find the DoH option at the bottom as shown below:
|
Firefox Custom DoH Option
|
Auto Renewing TLS Certificate
Since, the certificate obtained from Let's Encrypt expires in 90 days, certbot
automatically configures a cron job that renews the certificates before they
expire. Since we have already configured the
pkcs12convert.sh
script file earlier, it will get automatically
executed by certbot when the certificate is renewed. The Technitium DNS Server
will automatically reload the renewed certificate when it detects any changes
for the pfx file by looking at its date modified attribute.
To test the certbot renewal process, we can try 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
|
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 and bypass any network
restriction on DNS traffic. 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.