Fehlermeldung
x509: certificate is valid for example.com, not api.example.com
Die beiden Namen werden bei jedem Fehler eingesetzt: zuerst die Namen, die das Zertifikat abdeckt, dann der Name, den dein Client angefragt hat.
Go crypto/x509 — HostnameError from VerifyHostname / TLS dials
Was der Fehler bedeutet
Die TLS-Verbindung kam weit genug, um das Zertifikat zu lesen, aber keiner seiner Subject Alternative Names (SANs) passt zu dem Hostnamen, mit dem sich der Client verbinden wollte. Der Fehler nennt beide Seiten, deshalb ist die Lücke sofort sichtbar: Das Zertifikat deckt X ab, du hast Y angefragt. Beachte, dass moderne Prüfungen nur die SANs verwenden – das veraltete Feld Common Name wird ignoriert.
Warum der Fehler auftritt
In der SAN-Liste fehlt der verwendete Name
häufigEin für example.com ausgestelltes Zertifikat deckt api.example.com nicht ab (und ein Wildcard-Eintrag *.example.com deckt nur eine Ebene ab – weder example.com selbst noch a.b.example.com). Neue Subdomains brauchen neu ausgestellte Zertifikate.
Verbindung über einen internen Alias
häufigVerbindest du dich mit einem docker-compose-Dienstnamen oder einem anderen internen Alias, präsentiert der Server das Zertifikat der Identität, für die er sich hält – die SANs enthalten öffentliche DNS-Namen, nicht deinen Alias, deshalb schlägt der Abgleich fehl. Eine Verbindung zu einer reinen IP-Adresse scheitert stattdessen mit einer verwandten Meldung: „x509: cannot validate certificate for 10.0.0.5 because it doesn't contain any IP SANs“.
Falsches oder Standardzertifikat ausgeliefert (SNI)
gelegentlichMandantenfähige Ingresses wählen Zertifikate anhand von SNI aus. Lässt ein Client ServerName weg oder hat der Ingress keine Regel für den Host, kommt das Standardzertifikat zurück – oft ein Platzhalter wie „Kubernetes Ingress Controller Fake Certificate“.
So behebst du den Fehler
- 1.
Mit allen tatsächlich verwendeten Namen neu ausstellen
Nimm bei der Ausstellung alle Hostnamen als SANs auf; sieh dir die aktuelle SAN-Liste an, um zu erkennen, was heute abgedeckt ist.
bash echo | openssl s_client -connect host:443 -servername api.example.com 2>/dev/null \ | openssl x509 -noout -ext subjectAltName # request with SANs: openssl req -new -key key.pem -out req.csr \ -subj "/CN=example.com" -addext "subjectAltName=DNS:example.com,DNS:api.example.com" - 2.
Über den Namen verbinden oder ServerName explizit setzen
Muss die Netzwerkadresse vom Namen im Zertifikat abweichen (VIP, Portweiterleitung, Sidecar), bleibt die Prüfung aussagekräftig, wenn du TLS mitteilst, welche Identität du erwartest.
go conn, err := tls.Dial("tcp", "10.0.0.5:443", &tls.Config{ ServerName: "api.example.com", // matched against SANs, sent as SNI })