Nginx Client Zertifikat
Version vom 12. Juni 2026, 12:40 Uhr von Thomas.will (Diskussion | Beiträge)
Absicherung von Webdiensten mit 2FA: Zertifikat + Passwort (Nginx)
Einführung
- Zwei Faktoren: Besitz (Client-Zertifikat) und Wissen (Passwort).
- Der Server prüft das Client-Zertifikat gegen unsere CA (mTLS), danach folgt HTTP-Basic-Auth.
Ausgangspunkt
- Bestehender Nginx-vHost secure.it2XX.int (Debian) mit fertigem Server-Zertifikat
- Wenn vorhanden
- rm -v /var/www/secure/.htaccess
- cat /etc/nginx/sites-available/secure.conf
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name secure.it2XX.int;
root /var/www/secure;
index index.html;
ssl_certificate /etc/ssl/own.crt;
ssl_certificate_key /etc/ssl/own.key;
location / {
try_files $uri $uri/ =404;
}
}
Auf dem CA-Host
Client-Zertifikat erstellen
- cd ~/intermediate-ca
#Variablen setzen CA=it2XX-ca USER_B=client #CSR erzeugen openssl req -new -newkey rsa:2048 -nodes -keyout $USER_B.key -out $USER_B.csr -subj "/CN=$USER_B" #Signieren openssl x509 -req -in $USER_B.csr -CA $CA.crt -CAkey $CA.key -CAcreateserial -out $USER_B.crt -days 365 -extfile <(printf "extendedKeyUsage=clientAuth") #PKCS12 für den Browser-Import bauen (Export-Passwort setzen) openssl pkcs12 -export -in $USER_B.crt -inkey $USER_B.key -certfile $CA.crt -out $USER_B.p12
- $USER_B.p12 muss zum Client
Intermediate CA Fullchain
#Root-Zertifikat besorgen wget https://web.samogo.de/certs/ca.crt #CA-Fullchain erzeugen cat it2XX-ca.crt ca.crt > ca-fullchain.crt
- ca-fullchain.crt muss zum Webserver
Benutzer für Basic-Auth anlegen
- htpasswd -c /etc/nginx/.htpasswd martha
Nginx-Konfiguration erweitern
- cat /etc/nginx/sites-available/secure.conf
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name secure.it2XX.int;
root /var/www/secure;
index index.html;
ssl_certificate /etc/ssl/own.crt;
ssl_certificate_key /etc/ssl/own.key;
ssl_client_certificate /etc/ssl/ca-fullchain.crt;
ssl_verify_client on;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
auth_basic "Login mit Benutzername und Passwort";
auth_basic_user_file /etc/nginx/.htpasswd;
try_files $uri $uri/ =404;
}
}
- Config testen und neu laden
- nginx -t
- systemctl reload nginx
Zertifikat im Firefox einbinden
- Import
- Firefox → Einstellungen → Datenschutz & Sicherheit → Zertifikate anzeigen
- Reiter "Ihre Zertifikate" → Importieren → client.p12 (Export-Passwort eingeben)
- Verwendung
- Seite aufrufen: https://secure.it2XX.int
- Firefox fragt nach Zertifikat → dann HTTP-Login
Test
- Kein Zertifikat
- TLS-Handshake-Fehler (curl: alert certificate required, kein HTTP-Fehlercode)
- Falsches Passwort
- Fehler 401
- Zertifikat + Passwort korrekt
- Zugriff erlaubt
- Test mit curl
- curl --cert client.crt --key client.key -u martha https://secure.it2XX.int
Optional: Nur bestimmten CN zulassen
- ssl_verify_client prüft nur die Signatur der CA – jedes von ihr ausgestellte Zertifikat wird akzeptiert.
- Im location-Block ergänzen
if ($ssl_client_s_dn !~ "CN=client") {
return 403;
}
- Testfall
- gültiges Zertifikat, falscher CN
- Fehler 403
Fazit
- mTLS plus Basic-Auth ergibt eine echte 2-Faktor-Absicherung: Besitz und Wissen.
- ssl_client_certificate bestimmt, wessen Client-Zertifikate akzeptiert werden.