- Veröffentlicht am
- • How2-Tipps
Debian + Nginx + Windows-SubCA: Internes TLS-Zertifikat mit SAN korrekt erstellen
- Autor
-
-
- Benutzer
- tmueller
- Beiträge dieses Autors
- Beiträge dieses Autors
-
In vielen internen Netzwerken werden Webserver über eine eigene PKI abgesichert – häufig mit einer Windows-basierten Sub-CA (z. B. Active Directory Certificate Services). Das klingt zunächst einfach: CSR erzeugen, Zertifikat ausstellen, in Nginx einbinden – fertig.
In der Praxis stolpert man jedoch schnell über moderne Browser-Fehler wie:
ERR_CERT_COMMON_NAME_INVALID
oder harte HSTS-Blockaden.
In diesem Artikel zeige ich Schritt für Schritt, wie man auf einem Debian-Server mit Nginx ein korrektes SAN-Zertifikat von einer Windows-SubCA erstellt und sauber ausliefert – inklusive Fullchain.
Beispielumgebung (Dummy):
- Server:
srv-doc01.intern.example.local - Website:
docs.intern.example.local - SubCA:
Example-SubCA
Warum der Common Name nicht mehr reicht
Früher genügte es, wenn der Common Name (CN) im Zertifikat dem Hostnamen entsprach:
CN = docs.intern.example.local
Heute akzeptieren Browser das nicht mehr zuverlässig.
Stattdessen wird ausschließlich das Feld:
Subject Alternative Name (SAN)
ausgewertet.
Fehlt dort der Hostname, erscheint sofort:
ERR_CERT_COMMON_NAME_INVALID
Der CN wird praktisch ignoriert.
👉 Jedes Serverzertifikat braucht SAN.
Schritt 1 – Private Key erzeugen (Debian)
Empfehlung: pro Host einen eigenen Key.
sudo mkdir -p /etc/ssl/private /etc/ssl/certs
sudo openssl genrsa -out /etc/ssl/private/docs.intern.example.local.key 4096
sudo chmod 600 /etc/ssl/private/docs.intern.example.local.key
Schritt 2 – CSR mit SAN erstellen (entscheidend!)
Konfigurationsdatei anlegen:
cat > /root/docs.intern.example.local-san.conf <<'EOF'
[req]
default_md = sha256
prompt = no
distinguished_name = dn
req_extensions = req_ext
[dn]
C = DE
ST = NRW
L = ExampleCity
O = ExampleOrg
OU = IT
CN = docs.intern.example.local
emailAddress = admin@example.local
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = docs.intern.example.local
EOF
CSR erzeugen:
openssl req -new \
-key /etc/ssl/private/docs.intern.example.local.key \
-out /root/docs.intern.example.local.csr \
-config /root/docs.intern.example.local-san.conf
Kurz prüfen:
openssl req -in /root/docs.intern.example.local.csr -noout -text | grep -A2 "Subject Alternative Name"
Du solltest sehen:
DNS:docs.intern.example.local
Schritt 3 – CSR bei der Windows-SubCA einreichen
Auf der CA (z. B. Microsoft AD CS):
Variante Web Enrollment
- Aufrufen:
http://<CA-SERVER>/certsrv
- Request a certificate
- advanced certificate request
- CSR (inkl. BEGIN/END) einfügen
- Passendes Template wählen (z. B. „Web Server“)
- Zertifikat als Base64 herunterladen
Wichtig:
👉 Das verwendete Template muss SAN aus der CSR übernehmen. Falls nicht, muss es vom CA-Admin angepasst werden.
Schritt 4 – Zertifikat auf Debian installieren
Angenommen, du bekommst docs.cer.
Falls nötig von DER nach PEM:
openssl x509 -inform DER -in docs.cer -out /etc/ssl/certs/docs.intern.example.local.pem
Schritt 5 – SubCA (Intermediate) bereitstellen
Auch das SubCA-Zertifikat wird benötigt:
openssl x509 -inform DER -in Example-SubCA.cer -out /etc/ssl/certs/Example-SubCA.pem
Schritt 6 – Fullchain bauen
cat /etc/ssl/certs/docs.intern.example.local.pem \
/etc/ssl/certs/Example-SubCA.pem \
> /etc/ssl/certs/docs.intern.example.local-fullchain.pem
Schritt 7 – Nginx konfigurieren
Im passenden server {}-Block von Nginx:
server {
listen 443 ssl http2;
server_name docs.intern.example.local;
ssl_certificate /etc/ssl/certs/docs.intern.example.local-fullchain.pem;
ssl_certificate_key /etc/ssl/private/docs.intern.example.local.key;
}
Reload:
nginx -t && systemctl reload nginx
Schritt 8 – Finale Prüfungen
Hat das Zertifikat SAN?
openssl x509 -in /etc/ssl/certs/docs.intern.example.local.pem -noout -ext subjectAltName
Liefert Nginx die komplette Chain?
echo | openssl s_client -connect 127.0.0.1:443 -servername docs.intern.example.local | tail -n 20
Du willst sehen:
Verify return code: 0 (ok)
Typische Fehlerquellen
- Zertifikat ohne SAN → Browserfehler
- SubCA nicht im Fullchain → „unable to verify the first certificate“
- falscher Nginx-vHost → falsches Zertifikat
- DNS zeigt auf andere IP → du konfigurierst korrekt, Browser landet woanders
Für interne TLS-Zertifikate gilt heute:
- SAN ist Pflicht
- Fullchain ist Pflicht
- systematische OpenSSL-Tests sparen Stunden Fehlersuche
Hat man das einmal sauber umgesetzt, funktionieren auch interne Sites genauso zuverlässig wie öffentliche HTTPS-Dienste.