Message d’erreur
invalid peer certificate: certificate not valid for name "api.example.com"; certificate is only valid for DnsName("www.example.com")
Le nom attendu et la liste présentée sont renseignés pour chaque échec ; les adresses IP apparaissent sous la forme IpAddress(…). Les versions antérieures de rustls n’affichaient que le nom de la variante (« invalid peer certificate: NotValidForName »).
rustls 0.23 (via reqwest, ureq, hyper-rustls) — CertificateError::NotValidForNameContext
Ce que cela signifie
La chaîne est approuvée, mais le nom auquel le client s’est connecté ne figure pas parmi les noms alternatifs du sujet (Subject Alternative Names) du certificat. rustls 0.23 indique les deux : le nom attendu et chaque nom que présente le certificat (entrées DnsName et IpAddress), ce qui rend la non-concordance évidente.
Pourquoi cela se produit
Le certificat ne couvre pas ce nom
fréquenteUn autre sous-domaine, le domaine nu ou un service renommé manque dans la liste des SAN ; un wildcard ne couvre qu’un seul niveau du nom.
Connexion par adresse IP ou par un alias interne
fréquenteDes noms de service (Kubernetes, docker-compose) ou des adresses brutes pour lesquels le certificat n’a jamais été émis.
Le serveur a envoyé son certificat par défaut
occasionnelleUn proxy sans configuration pour le nom demandé sert le certificat d’un autre site.
Comment corriger l’erreur
- 1.
Comparer les noms présentés avec l’URL
Le message les liste déjà ; openssl confirme ce qu’envoie le serveur.
bash echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \ | openssl x509 -noout -ext subjectAltName - 2.
Remplacer l’adresse, pas le nom
ClientBuilder::resolve de reqwest fixe l’adresse de socket utilisée pour un nom d’hôte : la vérification continue donc d’utiliser le nom du certificat.
rust // Keep the certificate's name in the URL and send the connection to a specific address let addr: std::net::SocketAddr = "10.0.0.5:443".parse()?; let client = reqwest::Client::builder().resolve("www.example.com", addr).build()?; let resp = client.get("https://www.example.com/health").send().await?; - 3.
Réémettre avec tous les noms utilisés
Ajoutez au certificat les noms DNS manquants (ou des entrées IP).
bash openssl req -new -key server.key -out server.csr -subj "/CN=api.example.com" \ -addext "subjectAltName=DNS:api.example.com,DNS:www.example.com"