DoH Server auf CentOS 8 mit nginx, doh-proxy und unbound einrichten

von Thomas


Erstellt am 27.10.2020


Code programming

Einführung

In diesem Tutorial möchte ich euch nahelegen, wie ihr einen eigenen DoH Server aufsetzten könnt. Folgende Software wird verwendet:

  • CentOS 8 als OS Grundlage
  • nginx als Proxy
  • doh-proxy als DoH-Resolver
  • Let‘s Encrypt für gültige SSL Zertifikate
  • unbound als DNS-Resolver

Grundsystem installieren

DNS over HTTPS ist ein neues Protokoll und erst seit dem Oktober 2018 im RFC 8484 Standard. Zunächst müssen wir grundsätzliche Softwarepakete installieren, damit wir doh-proxy verwenden können. Wir müssen folgende Schritte im Terminal durchführen:

yum -y install git bind-utils gcc nginx python3-devel

doh-proxy Installation

Die Software doh-proxy ist in Python geschrieben und kann direkt aus dem Repository mit pip bezogen werden.

pip3.6 install doh-proxy

Sollte der Dienst aus diversen Gründen kompromittiert werden, ist es immer schlecht, wenn er als root ausgeführt wird. Aus diesem Grund legen wir einen zusätzlichen Nutzer an, unter dem der doh-proxy Dienst gestartet wird. Zusätzlich werden die benötigten Ordner für den Server-Dienst angelegt und Berechtigungen angepasst.

adduser -r doh-proxy \
-d /var/lib/doh-proxy \
-c 'DOH Proxy server' \
-s /sbin/nologin \
-U

mkdir /var/lib/doh-proxy \
&& chown doh-proxy: /var/lib/doh-proxy \
&& chown 700 /var/lib/doh-proxy

Wir wollen, dass doh-proxy bei jedem Systemneustart voll automatisch gestartet wird und an ansprechende Ports gebunden ist. Dafür nutzen wir systemd. Unter /etc/systemd/system/ legen wir einen Service an, welchen wir im Anschluss mit einer for Schleife scharf schalten.

cat <<EOF > /etc/systemd/system/doh-httpproxy\@.service
[Unit]
Description=DOH HTTP Proxy on %I
After=syslog.target network.target
Before=nginx.target

[Service]
Type=simple
ExecStart=doh-httpproxy --upstream-resolver ::1 --level DEBUG --listen-address=::1 --port %I
Restart=always
User=doh-proxy
Group=doh-proxy

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
for i in 8080 8081
do
    cp /etc/systemd/system/doh-httpproxy\@.service \
    /etc/systemd/system/doh-httpproxy\@${i}.service
    systemctl enable doh-httpproxy@${i}
    systemctl start doh-httpproxy@${i}
done

unbound installieren

Im nächsten Schritt installieren wir unbound, um DNS Anfragen auflösen zu können:

yum -y install unbound
systemctl enable unbound
systemctl start unbound

Die erfolgreiche Einrichtung kann mit folgendem Befehl getestet werden:

dig @::1 example.com

nginx und SSL Zertifikat einrichten

Ich persönlich versorge meine TLS geschützten Dienste mit Hilfe des Certbots. Der muss zunächst installiert werden:

curl -O https://dl.eff.org/certbot-auto
mv certbot-auto /usr/local/bin/certbot-auto
chmod 0755 /usr/local/bin/certbot-auto

Anschließend kann ein Zertifikat erstellt werden. Certbot legt dazu Einträge direkt in die nginx Konfiguration.

certbot-auto --nginx -d dns.beispiel.de

Nginx konfigurieren wir in der /etc/nginx/nginx.conf. Der Certbot hat schon Einträge hinterlegt, wir passen wie folgt an:

## upstream to our doh backend
upstream dohproxy_backend {
    server [::1]:8080;
    server [::1]:8081;
}

server {
    listen       80 ;
    listen       [::]:80 ;
    server_name your.domain.com;
    if ($host = your.domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    return 404; # managed by Certbot
}

server {
    server_name your.domain.com; # managed by Certbot

    listen [::]:443 ssl http2 ipv6only=on; # managed by Certbot
    listen 443 ssl http2; # managed by Certbot

    root         /usr/share/nginx/html;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;
    location /dns-query {
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;
        proxy_buffering off;
        proxy_pass http://dohproxy_backend;
    }
    location / {
	deny all;
    }

    ssl_certificate /etc/letsencrypt/live/your.domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/your.domain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

Testen können wir die Funktion mit einem curl Befehl. Bitte beachtet, dass curl DoH erst ab Version 7.62.0 unterstützt. Der Befehl sieht wie folgt aus:

curl --doh-url https://your.domain.com/dns-query https://www.beispiel.de

Logrotate kann anpassen werden, sodass wir keine Logs speichern. Dazu die Datei /etc/logrotate.d/nginx anzupassen. Hier muss eine Zeile (rotate) verändert werden:

/var/log/nginx/*log {
    create 0664 nginx root
    daily
    rotate 0
    missingok
    notifempty
    compress
    sharedscripts
    postrotate
        /bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
    endscript
}

Somit ist die Grundlage für einen DoH Server gelegt. Ich empfehle jedem noch weitere Software zu installieren, welche z. B. Sicherheitsupdates, Firewall und das Blocken von Angriffen übernimmt.