DNS over HTTPS (DoH) est un protocole permettant d'effectuer une résolution DNS (Domain Name System) à distance via le protocole HTTPS1. L'un des objectifs de la méthode est d'accroître la confidentialité et la sécurité des utilisateurs en empêchant les écoutes clandestines et la manipulation des données DNS par des attaques de type man-in-the-middle.
En plus d'améliorer la sécurité, DNS over HTTPS a également pour objectif d'améliorer les performances: les tests de résolution DNS des fournisseurs de services Internet ont montré que de nombreux temps de réponse étaient souvent très lents. Ce problème est exacerbé par la nécessité de devoir résoudre plusieurs noms d'hôtes lors du chargement d'une seule page Web.
Tiré en partie de : https://www.yaleax.com/posts/doh/
On récupère le paquet deb :
wget https://github.com/yaleax/yaleax/releases/download/doh-server/doh-server_2.0.1_amd64.deb sudo dpkg -i doh-server_2.0.1_amd64.deb
On édite /etc/dns-over-https/doh-server.conf :
# HTTP listen port listen = [ "127.0.0.1:8053", ] # TLS certification file # If left empty, plain-text HTTP will be used. # You are recommended to leave empty and to use a server load balancer (e.g. # Caddy, Nginx) and set up TLS there, because this program does not do OCSP # Stapling, which is necessary for client bootstrapping in a network # environment with completely no traditional DNS service. cert = "" # TLS private key file key = "" # HTTP path for resolve application path = "/query" # Upstream DNS resolver # If multiple servers are specified, a random one will be chosen each time. upstream = [ "127.0.0.1:53", ] # Upstream timeout timeout = 60 # Number of tries if upstream DNS fails tries = 10 # Only use TCP for DNS query tcp_only = false # Enable logging verbose = false # Enable log IP from HTTPS-reverse proxy header: X-Forwarded-For or X-Real-IP # Note: http uri/useragent log cannot be controlled by this config log_guessed_client_ip = false
listen : Le serveur doh écoute sur le port 8053
upstream : Le serveur DNS sur lequel se baser. Ici dans mon cas, j'ai un résolveur local, donc 127.0.0.1:53
C'est déjà en place :
systemctl restart doh-server systemctl status doh-server
On créé /etc/init.d/doh-server :
#! /bin/sh ### BEGIN INIT INFO # Provides: doh-server # Required-Start: $network $remote_fs $syslog # Required-Stop: $network $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: DNS-over-HTTPS Server # Description: This daemon will start the DNS-over-HTTPS Daemon ### END INIT INFO # Do NOT "set -e" PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin DESC="DNS-over-HTTPS Server" NAME=doh-server USERNAME=root DAEMON=/usr/local/bin/$NAME DAEMON_ARGS="-conf /etc/dns-over-https/doh-server.conf" PIDFILE=/var/run/$NAME.pid SCRIPTNAME=/etc/init.d/$NAME # Exit if the package is not installed [ -x "$DAEMON" ] || exit 0 # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.2-14) to ensure that this file is present # and status_of_proc is working. . /lib/lsb/init-functions # # Function that starts the daemon/service # do_start() { # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started start-stop-daemon -b --chuid $USERNAME --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ || return 1 start-stop-daemon -b --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ $DAEMON_ARGS \ || return 2 } # # Function that stops the daemon/service # do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 # Wait for children to finish too if this is a daemon that forks # and if the daemon is only ever run from this initscript. # If the above conditions are not satisfied then add some other code # that waits for the process to drop all resources that could be # needed by services started subsequently. A last resort is to # sleep for some time. start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON [ "$?" = 2 ] && return 2 # Many daemons don't delete their pidfiles when they exit. rm -f $PIDFILE return "$RETVAL" } case "$1" in start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" do_start case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; stop) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" do_stop case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; status) status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? ;; restart) log_daemon_msg "Restarting $DESC" "$NAME" do_stop case "$?" in 0|1) do_start case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; # Old process is still running *) log_end_msg 1 ;; # Failed to start esac ;; *) # Failed to stop log_end_msg 1 ;; esac ;; *) echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2 exit 3 ;; esac :
et puis :
update-rc.d -f doh-server defaults
D'abord il faut créer la clé SSL : Let's Encrypt / certbot
Ensuite on fait le vhost qui va bien dans /etc/apache2/sites-available :
<VirtualHost *:443> ServerName monserveurdoh.domain.tld RequestHeader set X-Forwarded-Proto "https" Header always set Strict-Transport-Security "max-age=31536000;" SSLEngine on SSLCertificateFile /etc/letsencrypt/live/monserveurdoh.domain.tld/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/monserveurdoh.domain.tld/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/monserveurdoh.domain.tld/chain.pem SSLProtocol -all +TLSv1.3 SSLHonorCipherOrder on SSLCipherSuite EECDH+AESGCM:AES256+EECDH:AES128+EECDH SSLCompression off SSLUseStapling on ProxyPass /query http://127.0.0.1:8053/query ProxyPassReverse /query http://127.0.0.1:8053/query </VirtualHost>
Et puis évidemment :
a2ensite doh.conf && apache2ctl restart
Sur le navigateur à configurer, il faudra entrer l'URL : https://monserveurdoh.domain.tld/query
Si vous souhaitez garder le serveur pour votre usage personnel, tout en ayant besoin d'avoir un accès public, pensez à mettre quelque chose de moins évident que “/query” pour la requête