Set up DNS-over-HTTPS Server + DNSCrypt + Nginx

The following post will quickly guide you to setup your own DoH (DNS-over-HTTPS) server along with DNSCrypt. Adguard DNS will be used to block ads and malwares. I’ll be using a KVM-based instance that runs an up-to-date Debian Bullseye (11) installation. Thanks Web Horizon for providing reliable VPS instances, get yours here.

Step 1: Installing & Configuring DNSCrypt

After upgrading your OS installation, install DNSCrypt and additional utilities by executing:

apt install curl dnscrypt-proxy build-essential certbot python3-certbot-nginx git nginx-full dnsutils jq wget nano -y

By default, DNSCrypt use the local IP address: to pass-through all the web traffic from the ethernet network interface. Let’s force DNSCrypt to be available on all network interfaces by executing:

sed -i "s|||g" /lib/systemd/system/dnscrypt-proxy.socket; cat /lib/systemd/system/dnscrypt-proxy.socket

Now let’s lock the resolv.conf file to connect through DNSCrypt permanently, even after reboots, do that by executing:

Due a WordPress protection, the next command line is available here:

Once that’s completed, restart your system by executing:

shutdown -r now

Let’s find out if this is working, first, you can use dig to see if requests are made from DNSCrypt, do that by executing:


There are hundreds of DNS resolvers compatible with DNSCrypt, one of them is Adguard, they claim to: “Remove ads and protect your computer from malware”. Let’s replace the default resolver (Cloudflare) with Adguard, do that by executing:

sed -i "s|cloudflare|adguard-dns|g" /etc/dnscrypt-proxy/dnscrypt-proxy.toml; cat /etc/dnscrypt-proxy/dnscrypt-proxy.toml; systemctl restart dnscrypt-proxy

Step 2: Compiling DNS-over-HTTPS Server

To compile DNS-over-HTTPS Server you need Go. Install Go by executing:

wget; tar -C /usr/local -xzf go1*; echo "export PATH=$PATH:/usr/local/go/bin" >> $HOME/.profile; source ~/.profile; go version

Now it’s time to compile, do that by executing:

git clone dns-over-https; cd dns-over-https; make; make install

Now will be using DNSCrypt as DNS-over-HTTPS main upstream, do that by executing:

sed -i '/8.8/d' /etc/dns-over-https/doh-server.conf; sed -i '/' /etc/dns-over-https/doh-server.conf; sed -i "s|||g" /etc/dns-over-https/doh-server.conf; cat /etc/dns-over-https/doh-server.conf | grep ''

You should see “udp:” in the output

Enable & restart the service by executing:

systemctl enable doh-server; systemctl restart doh-server

Step 3: Configuring Nginx

Let’s generate an example configuration file by executing:

cat <<\EOF2 > /etc/nginx/sites-available/dns-over-https
upstream dns-backend {
server {
listen 80;
root /var/www/html/dns;
access_log /var/log/nginx/dns.access.log;
location /dns-query {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400;
proxy_pass http://dns-backend/dns-query ;

You should replace: “” with your current domain name, I’ll use: “”, so:

sed -i "s|||g" /etc/nginx/sites-available/dns-over-https; ln -s /etc/nginx/sites-available/dns-over-https /etc/nginx/sites-enabled/dns-over-https; cat /etc/nginx/sites-available/dns-over-https

Let’s generate the staplin file, do that by executing:

cat <<\EOF2 > /etc/nginx/conf.d/stapling.conf
ssl_stapling on;
ssl_stapling_verify on;

Now let’s create a SSL certificate to our domain name, do that by executing:

certbot --register-unsafely-without-email --nginx -d

Let’s tweak the SSL configuration file by executing:

sed -i "s|10m|1m|g" /etc/letsencrypt/options-ssl-nginx.conf; sed -i "s|ciphers off|ciphers on|g" /etc/letsencrypt/options-ssl-nginx.conf; echo 'add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;' >> /etc/letsencrypt/options-ssl-nginx.conf; cat /etc/letsencrypt/options-ssl-nginx.conf

Restart & reload Nginx by executing:

systemctl reload nginx; systemctl restart nginx

Step 4: Using DNS-over-HTTPS Servers in Web Browsers

Now you can use your new DNS-over-HTTPS server. Modern web browsers allows connect to websites through a: “Secure DNS” , in Chromium, go to: Settings > Privacy and Security > Security > Use secure DNS. Type your domain name in the “Custom” field.



As one of my previous posts describe: DNSCrypt can turn your VPS instance to a DNS server, and now, along with a DNS-over-HTTPS server, you can user your VPS to navigate securely on internet. The main advantage of this, is to avoid DNS changes in several devices, by changing the upstream in the DNSCrypt config file will be enough.

Don’t forget to check Web Horizon amazing deals here.