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