Nginx als Reverse Proxy für Phoscon/deCONZ

Nachdem ich deCONZ/Phoscon installiert habe, musste ich feststellen, dass die Software bisher leider kein SSL/TLS verwendet. Daher möchte ich die Seite über einen NGINX-Reverse-Proxy aufrufen, der sich um die SSL/TLS-Verschlüsselung kümmert. 

deCONZ Default-Ports abändern

Als erstes muss das deCONZ Startup-Script angepasst werden, so dass die deCONZ-Dienste nicht mehr die Standardports 80/tcp und 443/tcp blockieren und Nginx fehlerfrei installiert werden kann. Über die Parameter --http-port und --ws-port können die von deCONZ verwendeten Ports geändert werden:

systemctl edit --full deconz
[Unit]
Description=deCONZ: ZigBee gateway -- REST API
Wants=deconz-init.service deconz-update.service

[Service]
User=deconz
[...]
ExecStart=/usr/bin/deCONZ -platform minimal --http-port=8080 --ws-port=8081
[...]

Nginx installieren und konfigurieren

Die Installation von NGINX unter debian ist denkbar einfach:

apt update
apt install nginx

In der nginx.conf habe ich nur wenige Sachen angepasst. Das wichtigste davon ist das auskommentieren der SSL-Einstellungen, da ich diese in einer gesonderten Config-Datei zusammenfasse:

  server_tokens off;
  server_names_hash_bucket_size 64;
  
  # Alle SSL-Optionen in der nginx.conf habe ich deaktiviert. 
  # SSL wird in einer eigenen Datei definiert (s.u.)
  # ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
  # ssl_prefer_server_ciphers on;

Die SSL-Konfiguraiton kommt in die Datei /etc/nginx/conf.d/ssl.conf, die automatisch in der nginx.conf Datei inkludiert wird:

echo "
  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:50m;
  ssl_session_tickets off;

  # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
  #ssl_dhparam /etc/nginx/tls/dh-parm-4096.pem;

  # Protokolle und Cipher Suiten festlegen
  ssl_protocols TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE and TLS 1.0/1.1
  ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
# more secure, but less compatible set of ciphers #ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384'; ssl_ecdh_curve secp521r1:secp384r1:prime256v1; ssl_prefer_server_ciphers on;
" > /etc/nginx/conf.d/ssl.conf

Die Default-Seite des NGINX wird nicht benötigt und kann daher deaktiviert werden:

rm /etc/nginx/sites-enabled/default

Da ich auf Port 80 keine Web-Dienste anbieten möchte, leite ich als nächstes den gesamten Datenverkehr auf Port 80 um, so dass alle unverschlüsselten Anfragen an HTTPS weitergeleitet werden:

echo "server {
    listen 80 default_server;
    listen [::]:80 default_server;

    # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
    location / {
        return 301 https://$host$request_uri;
    }

    ## Only allow these request methods ##
    if ($request_method !~ ^(GET|HEAD|POST)$ ) {
             return 444;
    }
    ## Do not accept DELETE, SEARCH and other methods ##
}" > /etc/nginx/sites-available/default-redirect

Mit der folgenden Konfiguration wird der eigentliche Reverse-Proxy konfiguriert. In Zeile 4 müssen natürlich die Namen eingetragen werden unter denen der Server im Netzwerk verfügbar ist. Zusätzlich müssen dann auch noch entsprechende Einträge im lokalen DNS-Server eingetragen werden, damit der Zugriff korrekt funktioniert.

echo "server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name deconz deconz.lan phoscon phoscon.lan;

    # ECC certificate (brainpool384r)
    ssl_certificate /etc/nginx/tls/ecc_fullchain.pem;
    ssl_certificate_key /etc/nginx/tls/ecc_key.pem;

    # RSA certificate (4096)
    ssl_certificate /etc/nginx/tls/rsa_fullchain.pem;
    ssl_certificate_key /etc/nginx/tls/rsa_key.pem;

    proxy_buffering off;

    location ~ (/.*) {
        set $p 8080;
        if ($http_upgrade = "websocket") {
            set $p 8081;
        }
        proxy_pass http://192.168.1.10:$p$1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}" > /etc/nginx/sites-available/deconz

Die in den Zeilen 7 - 12 referenzierten Schlüssel  und Zertifikate müssen natürlich noch erstellt werden. Hierzu gibt es zahlreiche Anleitungen im Netz, so dass ich in diesem Artikel nicht genauer darauf eingehen werde. Ist der Server öffentlich erreichbar, so bietet sich ein Zertifikat von Let's Encrpyt an. Alternativ kann man natürlich auch eine eigene CA erstellen.

Die erzeugten Sites müssen jetzt nur noch aktiviert werden:

cd /etc/nginx/sites-enabled
ln -s ../sites-available/default-redirect
ln -s ../sites-available/deconz

Mit dem Befehl nginx -t kann die Konfiguration überprüft werden. Wenn dabei keinen Fehler auftreten sollte es ungeführ so aussehen:

$ nginx -t

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Nach einem Neustart de Servers via systemctl restart nginx sollte das deCONZ dann auch über den neu eingerichteten Proxy erreichbar sein. 

 

Quellen

[1] https://github.com/dresden-elektronik/deconz-rest-plugin/issues/1279

Kommentare

PostadresseE-MailadresseFestnetzMobiltelefonSMS/SignalThreemaTwitter DirektnachrichtFAXWeb Page