Fehlermeldung
x509: certificate is not valid for any names, but wanted to match api.example.com
Auch ausgegeben als
- tls: failed to verify certificate: x509: certificate is not valid for any names, but wanted to match api.example.com
Der Name nach „wanted to match“ ist dein Verbindungsziel. Bei Zertifikaten ganz ohne SAN-Erweiterung meldet Go stattdessen „x509: certificate relies on legacy Common Name field, use SANs instead“ (wenn der CN gepasst hätte).
Go crypto/x509 — HostnameError for a certificate with no DNS SANs (e.g. IP-only or empty SAN list)
Was der Fehler bedeutet
Go wollte den Hostnamen mit dem Zertifikat abgleichen und hat überhaupt keine DNS-Namen gefunden: Die SAN-Erweiterung ist vorhanden, enthält aber nur IP-Adressen (oder andere Eintragstypen), und der Common Name wird nicht berücksichtigt. Go meldet, dass das Zertifikat keine Namen abdeckt, gefolgt von dem Namen, den es gesucht hat.
Warum der Fehler auftritt
Ein für eine IP-Adresse erstelltes Zertifikat wird mit einem Hostnamen verwendet
häufigZertifikate, die für die Adresse eines Nodes oder einer VM erzeugt (nur IP-SANs) und später über einen DNS-Namen angesprochen werden.
Ein Zertifikat für einen anderen Zweck
gelegentlichClient-Zertifikate, E-Mail-Zertifikate (S/MIME) oder Zertifikate für die Codesignatur enthalten keine DNS-SANs und können nicht als Serverzertifikate dienen.
Der Server liefert das falsche Zertifikat aus
gelegentlichEin Server, der versehentlich mit einem Client- oder internen Zertifikat konfiguriert wurde, oft nach einer Schlüsselrotation.
So behebst du den Fehler
- 1.
SAN-Einträge und Verwendungszweck prüfen
Die SAN-Liste zeigt, welche Arten von Namen vorhanden sind; extendedKeyUsage zeigt, ob es überhaupt ein Serverzertifikat ist.
bash echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \ | openssl x509 -noout -subject -ext subjectAltName,extendedKeyUsage - 2.
Serverzertifikat mit DNS-SANs ausstellen
Nimm die DNS-Namen auf, die Clients verwenden, und zusätzlich IP-Einträge, falls sie sich auch per Adresse verbinden.
bash openssl req -new -key server.key -out server.csr -subj "/CN=api.example.com" \ -addext "subjectAltName=DNS:api.example.com,IP:10.0.0.5" - 3.
Oder über die Adresse verbinden, die das Zertifikat nennt
IP-SANs passen nur, wenn sich der Client mit genau dieser IP verbindet.
go // If the certificate is meant for the IP address, dial the IP (it is matched against IP SANs) resp, err := client.Get("https://10.0.0.5:8443/")