Jump to content

DNS-over-HTTPS

From ArchWiki

DNS-over-HTTPS is an implementation of DNS over HTTPS. It can act as a stub resolver.

Installation

Install the dns-over-https package.

Client startup

Disable any services bound to port 53

To see if any programs are using port 53, run:

$ ss -lp 'sport = :domain'

If the output contains more than the first line of column names, you need to disable whatever service is using port 53. You are ready to proceed once the above command outputs nothing more than the following line:

Netid State   Recv-Q  Send-Q   Local Address:Port     Peer Address:Port Process

Change system DNS server

Change your system's DNS server to an address in the listen = section of the configuration file. If you don't know what you're doing, 127.0.0.1 is recommended.

This can be accomplished either through your Network Manager or through editing /etc/resolv.conf.

Startup

Start or enable doh-client.service.

Test configuration

To test if your system's DNS works, type nslookup www.google.com into the command line. Note that this will work before DNS-over-HTTPS is configured, assuming you had a DNS configuration before installing this.

Client configuration

The client configuration file is /etc/dns-over-https/doh-client.conf by default

Select preferred upstream DNS server

To select a preferred DNS server, uncomment one of the profiles.

If your preferred server is not listed, you may use the following template in the [upstream] section.

/etc/dns-over-https/doh-client.conf
[[upstream.upstream_ietf]]
    url = "https://IP_or_web_address/dns-query"
    weight = 20
Note Choose a DNS resolver you trust. See Domain name resolution#Third-party DNS services.

Server configuration

The configuration file for doh-server is located at /etc/dns-over-https/doh-server.conf. The upstream section can set desired upstream resolvers and their used protocols. You can use doh-server as standalone service or together with a web server like nginx or apache.

For standalone use you need to set port to 443 and specify proper certificate and key:

/etc/dns-over-https/doh-server.conf
listen = [
    "127.0.0.1:443",
]
...
cert = ""
key = ""

If you want use HTTP server for caching or use it along with other HTTPS services, leave the cert and key strings in doh-server.conf empty and use the following examples for configuring the desired HTTP server.

nginx:

/etc/nginx/nginx/site-available/doh
server {
  listen       443 ssl http2 default_server;
  listen       [::]:443 ssl http2 default_server;
  server_name  MY_SERVER_NAME;

  ssl_certificate /path/to/your/server/certificates/fullchain.pem;
  ssl_certificate_key /path/to/your/server/certificates/privkey.pem;
  location /dns-query {
    proxy_pass       http://localhost:8053/dns-query;
    proxy_set_header Host      $host;
    proxy_set_header X-Real-IP $remote_addr;
  }
}

Caddy:

/etc/caddy/Caddyfile
MY_SERVER_NAME {
        reverse_proxy * localhost:8053
        tls my@email.example
        try_files {path} {path}/index.php /index.php?{query}
}

Apache HTTP Server:

/etc/httpd/conf/vhosts/doh.conf
<VirtualHost *:443>
    ServerName MY_SERVER_NAME
    Protocols h2 http/1.1
    ProxyPass /dns-query http://[::1]:8053/dns-query
    ProxyPassReverse /dns-query http://[::1]:8053/dns-query
</VirtualHost>

After configuring, start/enable doh-server.service.

Troubleshooting

Service does not start properly in wired connection

As explained by the developer:

ArchLinux doesn’t come with a default network management framework, thus systemd comes without online detection pre-configured.
If you are on Wi-Fi, I suggest making sure systemd’s online detection can function properly. I believe your system have already installed some network management framework such as NetworkManager to help you manage Wi-Fi passwords.
Or, if you are on wired network, simply modifying the .service file to disable online detection would be the easiest solution. Installing NetworkManager for a non-mobile machine might be against the K.I.S.S. principle, and we don’t want it.

Upstream suggests to use a drop-in snippet to your service file to:

/etc/systemd/system/doh-client.service.d/override.conf
[Unit]
After=multi-user.target

[Service]
Type=idle

doh-server cannot open TLS key

doh-server.service contains DynamicUser=yes which prevents giving it access to non-world-readable files, e.g. a key file. A solution is to create a drop-in file with a LoadCredential= directive and then use the /run/credentials/doh-server.service/ path in /etc/dns-over-https/doh-server.conf. For example:

/etc/systemd/system/doh-server.service.d/key.conf
[Service]
LoadCredential=server.key:/etc/dns-over-https/server.key
/etc/dns-over-https/doh-server.conf
...
cert = "/etc/dns-over-https/server.crt"
key = "/run/credentials/doh-server.service/server.key"
...