Node.js-Anwendung absichern – mit Nginx, Let’s Encrypt & Docker Compose
In der heutigen digitalen Welt ist es von entscheidender Bedeutung, die Sicherheit Ihrer Anwendung zu gewährleisten. Dieser Blogbeitrag zeigt Ihnen, wie Sie eine containerisierte Node.js-Anwendung mit Nginx, Let’s Encrypt und Docker Compose sichern können.
Die Sicherheit einer Anwendung ist ein essentieller Aspekt in der Entwicklung. Durch den Einsatz eines Reverse-Proxys wie Nginx, der Lastenausgleich, Zwischenspeicherung statischer Inhalte und die Implementierung von TLS ermöglicht, können Sie die Sicherheit und Leistung Ihrer Anwendung verbessern. Dieser Beitrag führt Sie durch die Schritte, um eine containerisierte Node.js-Anwendung mit Nginx und Let’s Encrypt abzusichern, indem Docker Compose verwendet wird.
Voraussetzungen
- Ein Ubuntu 18.04 Server mit einem nicht-root Benutzer mit sudo-Berechtigungen und einer aktiven Firewall.
- Docker und Docker Compose auf deinem Server installiert.
- Eine registrierte Domain, die du für deine Anwendung verwenden kannst.
- Die DNS-Einträge für deine Domain konfiguriert.
Schritt 1 — Klonen und Testen der Node-Anwendung
Zunächst klonen Sie das Repository mit dem Node-Anwendung-Code. Anschließend testen Sie die Anwendung, um sicherzustellen, dass alles funktioniert. Dieser Schritt umfasst das Bauen und Ausführen der Anwendung ohne Reverse-Proxy oder SSL.
git clone https://github.com/do-community/nodejs-image-demo.git node_project
cd node_project
docker build -t node-demo .
docker run –name node-demo -p 80:8080 -d node-demo
Schritt 2 — Webserver-Konfiguration definieren
Nachdem die Node-Anwendung getestet wurde, erstellen Sie eine Konfigurationsdatei für den Nginx-Webserver. Diese Konfiguration wird es ermöglichen, Anfragen an Ihre Node-Anwendung weiterzuleiten und Zertifikatsanfragen von Certbot zu behandeln.
Schritt 3 — Erstellen der Docker Compose-Datei
Die `docker-compose.yml`-Datei definiert die Services für deine Anwendung, den Webserver und den Certbot-Container. Sie enthält Details wie benannte Volumes, Netzwerke und Portinformationen.
version: ‚3‘
services:
nodejs:
# Konfiguration für den Node-Dienst
webserver:
# Konfiguration für den Nginx-Webserver
certbot:
# Konfiguration für den Certbot-Container
Schritt 4: Starten der Container
Zuerst müssen wir die Container mit dem Befehl `docker-compose up` starten. Dadurch werden die Container und Dienste in der von uns festgelegten Reihenfolge erstellt und ausgeführt. Sobald die Domain-Anfragen erfolgreich sind, werden die Zertifikate im Ordner `/etc/letsencrypt/live` des Webservers bereitgestellt.
docker-compose up -d
Schritt 5: Überprüfen der Dienste
Mit dem Befehl `docker-compose ps` können wir den Status unserer Dienste überprüfen. Die Dienste `nodejs` und `webserver` sollten als „Up“ angezeigt werden, während der `certbot`-Container mit dem Status „Exit 0“ beendet sein sollte. Andernfalls können wir die Dienstprotokolle mit dem Befehl `docker-compose logs` überprüfen.
docker-compose ps
Schritt 6: Anpassen der Zertifikatsanforderungen
Wir können die `certbot`-Service-Definition bearbeiten, um das `–staging`-Flag zu entfernen und durch das `–force-renewal`-Flag zu ersetzen. Dadurch wird Certbot angewiesen, ein neues Zertifikat mit denselben Domains wie ein vorhandenes Zertifikat anzufordern.
certbot:
image: certbot/certbot
container_name: certbot
volumes:
– certbot-etc:/etc/letsencrypt
– certbot-var:/var/lib/letsencrypt
– web-root:/var/www/html
depends_on:
– webserver
command: certonly –webroot –webroot-path=/var/www/html –email sammy@your_domain –agree-tos –no-eff-email –force-renewal -d your_domain -d www.your_domain
Schritt 7: Aktualisieren der Nginx-Konfiguration
Um SSL in unserer Nginx-Konfiguration zu aktivieren, müssen wir einen HTTP-Redirect zu HTTPS hinzufügen und die SSL-Zertifikats- und Schlüsselstandorte angeben. Wir müssen auch die Diffie-Hellman-Gruppe spezifizieren, die für Perfect Forward Secrecy verwendet wird.
server {
listen 80;
listen [::]:80;
server_name your_domain www.your_domain;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name your_domain www.your_domain;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;
ssl_buffer_size 8k;
ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;
location / {
try_files $uri @nodejs;
}
location @nodejs {
proxy_pass http://nodejs:8080;
add_header X-Frame-Options „SAMEORIGIN“ always;
add_header X-XSS-Protection „1; mode=block“ always;
add_header X-Content-Type-Options „nosniff“ always;
add_header Referrer-Policy „no-referrer-when-downgrade“ always;
add_header Content-Security-Policy „default-src * data: ‚unsafe-eval‘ ‚unsafe-inline’“ always;
#add_header Strict-Transport-Security „max-age=31536000; includeSubDomains; preload“ always;
# enable strict transport security only if you understand the implications
}
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
}
Schritt 8: Erneuerung der Zertifikate
Da Let’s Encrypt-Zertifikate nur 90 Tage gültig sind, müssen wir einen automatisierten Erneuerungsprozess einrichten. Dies kann mit einem Cron-Job erfolgen, der ein Skript ausführt, das die Zertifikate erneuert und die Nginx-Konfiguration neu lädt.
#!/bin/bash
COMPOSE=“/usr/local/bin/docker-compose –ansi never“
DOCKER=“/usr/bin/docker“
cd /home/sammy/node_project/
$COMPOSE run certbot renew –dry-run && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af
Fazit
Mit Docker Compose haben wir SSL-Zertifikate für unsere Anwendung eingerichtet und einen automatisierten Erneuerungsprozess implementiert. Durch die Nutzung von Containern haben wir eine flexible und skalierbare Lösung geschaffen, um die Sicherheit unserer Webanwendung zu gewährleisten. Node.js-Anwendung absichern – mit Nginx, Let’s Encrypt & Docker Compose