SSL für Nginx in Docker: PFX-Zertifikate richtig einrichten

Eine praktische Anleitung für Self-Hoster: So wandelst du PFX-Zertifikate in PEM um und richtest SSL/TLS für deinen Nginx-Container in Docker sicher ein.

SSL für Nginx in Docker: PFX-Zertifikate richtig einrichten hero image

Einleitung

Die Absicherung von Webanwendungen mit SSL/TLS ist oft unerlässlich. Eine verschlüsselte Verbindung via HTTPS schützt nicht nur die Daten deiner Nutzer, sondern schafft auch Vertrauen. Während Dienste wie Let’s Encrypt den Prozess automatisieren, erhält man von manchen Zertifizierungsstellen oder für interne Netzwerke Zertifikate im PFX-Format (.pfx oder .p12).

Dieses Format bündelt Zertifikat und privaten Schlüssel in einer passwortgeschützten Datei, was für Windows-Server praktisch ist. Nginx, der beliebteste Webserver im Docker-Umfeld, bevorzugt jedoch das PEM-Format mit getrennten Dateien.

Dieser Artikel zeigt dir Schritt für Schritt, wie du ein PFX-Zertifikat mit OpenSSL für den Einsatz mit einem Nginx-Container vorbereitest und konfigurierst.

Glossar: Wichtige Begriffe rund um SSL

BegriffBeschreibung
SSL/TLSSecure Sockets Layer / Transport Layer Security. Protokolle zur Verschlüsselung der Datenübertragung im Internet. TLS ist der moderne Nachfolger von SSL.
PFX/PKCS#12Ein binäres Dateiformat, das ein SSL-Zertifikat, Zwischenzertifikate und den privaten Schlüssel in einer einzigen, passwortgeschützten Datei bündelt. Endungen sind oft .pfx oder .p12.
PEMPrivacy Enhanced Mail. Ein textbasiertes Dateiformat, das kryptografische Informationen (wie Zertifikate oder Schlüssel) in Base64 kodiert. Nginx und Apache bevorzugen dieses Format.
OpenSSLEin leistungsstarkes Kommandozeilen-Tool zur Arbeit mit SSL/TLS-Zertifikaten. Wir nutzen es zur Konvertierung.
Private KeyDer private Schlüssel (.key oder .pem). Er muss geheim gehalten werden und wird vom Server verwendet, um die an ihn gesendeten Daten zu entschlüsseln.
CertificateDas öffentliche Zertifikat (.crt oder .pem). Es wird vom Server an den Client (Browser) gesendet, um seine Identität zu beweisen.
CA ChainCertificate Authority Chain. Eine Kette von Zwischenzertifikaten, die die Vertrauenswürdigkeit deines Zertifikats bis zu einer Root-CA belegt. Essentiell, um Browser-Warnungen zu vermeiden.
NginxEin leistungsstarker, ressourcenschonender Webserver und Reverse Proxy, der häufig in Docker-Setups eingesetzt wird.
Docker ComposeEin Werkzeug, um Multi-Container-Docker-Anwendungen mithilfe einer einzigen YAML-Datei zu definieren und auszuführen.

Schritt 1: PFX-Zertifikat für Nginx aufbereiten

Die Umwandlung einer PFX-Datei lässt sich vollständig mit dem Kommandozeilen-Tool openssl bewerkstelligen, das auf den meisten Linux-Systemen vorinstalliert ist. Führe die folgenden Befehle in deinem Terminal im Hauptverzeichnis deines Docker-Projekts aus.

1. Verzeichnis für SSL-Zertifikate erstellen

Zuerst legen wir eine saubere Verzeichnisstruktur an. Innerhalb deines Nginx-Konfigurationsordners ist ein ssl-Unterverzeichnis ein guter und üblicher Ort für deine Zertifikatsdateien.

mkdir -p nginx/ssl
cd nginx/ssl

2. PFX-Datei kopieren

Kopiere deine erhaltene PFX-Datei (z. B. certificate.pfx) in dieses neu erstellte nginx/ssl-Verzeichnis.

3. Privaten Schlüssel extrahieren

Dieser Befehl extrahiert den privaten Schlüssel aus der PFX-Datei. Du wirst zur Eingabe des Passworts für die PFX-Datei aufgefordert. Das Ergebnis ist eine noch passwortgeschützte PEM-Datei.

openssl pkcs12 -in certificate.pfx -nocerts -out private-key-encrypted.pem
# Gib dein PFX-Passwort ein

4. Zertifikat extrahieren

Als Nächstes wird das öffentliche Zertifikat aus der PFX-Datei ausgelesen.

openssl pkcs12 -in certificate.pfx -clcerts -nokeys -out certificate.pem

5. CA-Zertifikatskette (falls vorhanden) extrahieren

Moderne Zertifikate enthalten oft auch die Kette der Zwischenzertifikate (Intermediate Certificates). Diese sollten ebenfalls extrahiert werden, um Vertrauensprobleme in Browsern zu vermeiden.

openssl pkcs12 -in certificate.pfx -cacerts -nokeys -out ca-chain.pem

6. Passwortschutz vom privaten Schlüssel entfernen

Der extrahierte private Schlüssel ist noch mit einer Passphrase geschützt. Damit Nginx beim Start des Containers nicht nach einem Passwort fragt und automatisiert starten kann, müssen wir diesen Schutz entfernen.

openssl rsa -in private-key-encrypted.pem -out private-key.pem

7. Aufräumen

Die verschlüsselte Version des privaten Schlüssels wird nicht mehr benötigt und sollte aus Sicherheitsgründen entfernt werden.

rm private-key-encrypted.pem

8. Berechtigungen setzen

Der Schutz des privaten Schlüssels ist entscheidend. Stelle sicher, dass nur der Eigentümer die Datei lesen kann. Öffentliche Zertifikate können von allen gelesen werden.

chmod 600 private-key.pem
chmod 644 certificate.pem ca-chain.pem

9. Komplette Zertifikatskette erstellen (Empfohlen)

Für eine optimale Kompatibilität mit allen Browsern und einfacherer Konfiguration in Nginx ist es ratsam, dein Zertifikat und die CA-Kette zu einer einzigen Datei zusammenzufügen. Nginx kann diese fullchain.pem dann direkt verwenden.

cat certificate.pem ca-chain.pem > fullchain.pem

Nach diesen Schritten sollten sich in deinem nginx/ssl-Verzeichnis die zwei entscheidenden Dateien private-key.pem und fullchain.pem befinden. Wir können nun die Nginx-Konfiguration anpassen.

cd ../.. # Zurück ins Hauptverzeichnis

Schritt 2: Nginx-Konfiguration für SSL anpassen

Nun müssen wir Nginx mitteilen, wo die Zertifikatsdateien zu finden sind und dass der Server auf dem HTTPS-Port 443 lauschen soll.

Lege eine Konfigurationsdatei an, z. B. nginx.conf. Eine typische Konfiguration, die HTTP-Anfragen auf HTTPS umleitet und SSL verwendet, sieht wie folgt aus:

cd nginx
touch nginx.conf
server {
    listen 80;
    server_name deine-domain.de www.deine-domain.de;

    # Umleitung aller HTTP-Anfragen auf HTTPS mit Statuscode 301 (Permanent)
    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name deine-domain.de www.deine-domain.de;

    # Pfade zu den SSL-Zertifikatsdateien IM CONTAINER
    ssl_certificate /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/private-key.pem;

    # Weitere SSL-Optimierungen (Best Practices)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-RSA-AES128-GCM-SHA256';
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # HSTS Header (Strict Transport Security) hinzufügen
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

    location / {
        # Hier kann z.B. ein Reverse Proxy zu einer anderen Anwendung folgen
        proxy_pass http://mein-container:8080;

        # Oder statische Inhalte ausgeliefert werden
        # root   /usr/share/nginx/html;
        # index  index.html index.htm;
    }
}

Wichtige Hinweise zur Konfiguration:

  • Ersetze deine-domain.de durch deine tatsächliche Domain.
  • Die Pfade ssl_certificate und ssl_certificate_key zeigen auf den Ort innerhalb des Docker-Containers, den wir im nächsten Schritt per Volume-Mount bereitstellen.

Schritt 3: Docker Compose-Setup für Nginx mit SSL

Um den Nginx-Container zu starten und unsere Konfiguration sowie die Zertifikate zu verwenden, ist Docker Compose ideal. Wie bei meinen Anleitungen zu Paperless-NGX auf Synology oder der Einrichtung eines Homeservers setzen wir auch hier auf eine compose.yaml-Datei im Hauptverzeichnis deines Projekts.

touch compose.yaml
services:
    nginx:
        image: nginx:latest
        container_name: nginx_webserver
        restart: unless-stopped
        ports:
            - "80:80"
            - "443:443"
        volumes:
            # Nginx Konfigurationsdateien
            - ./nginx.conf:/etc/nginx/nginx.conf:ro
            # SSL Zertifikate (nur lesend einbinden)
            - ./ssl:/etc/nginx/ssl:ro
            # Beispiel für statische Inhalte
            # - ./html:/usr/share/nginx/html:ro
        networks:
            - web_network

networks:
    web_network:
        external: true

Erläuterung der Volumes:

  • ./nginx/conf.d:/etc/nginx/conf.d:ro: Bindet unser lokales Konfigurationsverzeichnis in den Container ein. Der Zusatz :ro (read-only) ist eine gute Sicherheitspraxis, da der Container die Konfiguration nicht ändern sollte.
  • ./nginx/ssl:/etc/nginx/ssl:ro: Macht unsere vorbereiteten SSL-Zertifikate für Nginx im Container verfügbar, ebenfalls schreibgeschützt.

Nachdem du die dcompose.yaml gespeichert hast, kannst du den Nginx-Container mit einem einfachen Befehl starten:

docker compose up -d

Dein Webserver ist nun über https://deine-domain.de erreichbar und die Verbindung ist sicher verschlüsselt. Du kannst die Qualität deiner SSL-Konfiguration mit Tools wie dem SSL Labs Server Test überprüfen.

Fazit

Die manuelle Konfiguration von SSL-Zertifikaten für Nginx in Docker ist mit den richtigen Werkzeugen und Schritten schnell erledigt. Indem du PFX-Dateien korrekt in das PEM-Format konvertierst und eine saubere Struktur für deine Konfiguration und Zertifikate pflegst, schaffst du ein robustes und sicheres Setup für deine selbst gehosteten Dienste.

FAQs

Warum muss ich den Passwortschutz vom privaten Schlüssel entfernen?

Nginx und andere Webserver laufen als Dienste im Hintergrund. Wenn der private Schlüssel passwortgeschützt ist, würde der Server bei jedem Start auf eine Passworteingabe warten, was einen automatisierten Betrieb unmöglich macht. Die Sicherheit wird stattdessen durch strikte Dateiberechtigungen (chmod 600) auf dem Host-System gewährleistet.

Was ist der Unterschied zwischen fullchain.pem und certificate.pem?

certificate.pem enthält nur das Zertifikat für deine Domain. fullchain.pem enthält zusätzlich die Kette der Zwischenzertifikate (CA Chain). Die Verwendung der fullchain.pem wird dringend empfohlen, da sie es Browsern ermöglicht, die gesamte Vertrauenskette zu validieren, was 'Certificate Not Trusted'-Fehler verhindert.

Kann ich diesen Prozess automatisieren?

Ja, die hier gezeigten OpenSSL-Befehle lassen sich leicht in ein Shell-Skript packen. Wenn du häufiger Zertifikate in diesem Format erhältst, kann ein Skript den Prozess auf einen einzigen Befehl reduzieren.

Funktioniert das auch mit anderen Reverse Proxys wie Traefik oder Caddy?

Ja, der Prozess der Zertifikatskonvertierung von PFX zu PEM ist universell. Traefik und Caddy benötigen ebenfalls PEM-formatierte Zertifikate (Schlüssel und Zertifikatsdatei). Die Konfiguration, wo die Zertifikate abgelegt und referenziert werden, unterscheidet sich jedoch je nach Proxy.

Was passiert, wenn mein Zertifikat abläuft?

Du musst den Prozess mit der neuen PFX-Datei wiederholen, um die Zertifikatsdateien (private-key.pem, fullchain.pem) zu aktualisieren. Anschließend startest du den Nginx-Container neu, damit er die neuen Zertifikate lädt. Ein `docker compose restart nginx` genügt in der Regel.

Diesen Beitrag teilen:

Diese Website verwendet Cookies. Diese sind notwendig, um die Funktionalität der Website zu gewährleisten. Weitere Informationen finden Sie in der Datenschutzerklärung