Aller au contenu
ecdsa.com
Go crypto/tls (Go ≥ 1.20)Go

Message d’erreur

tls: failed to verify certificate: x509: certificate signed by unknown authority

Go crypto/tls (Go ≥ 1.20) — wrapping x509 verification errors

Ce que cela signifie

Depuis Go 1.20, les échecs du handshake TLS enveloppent l’erreur x509 sous-jacente dans le préfixe « tls: failed to verify certificate: », si bien que les journaux montrent à la fois la couche (handshake TLS) et la cause racine (échec de la construction de la chaîne). Le suffixe varie (autorité inconnue, certificat expiré, nom d’hôte discordant) et c’est sur lui qu’il faut agir. Le préfixe est aussi un filtre pratique pour les journaux : le rechercher avec grep sépare les échecs de confiance TLS des erreurs applicatives, et c’est précisément pour cela que cet enveloppement a été ajouté.

Pourquoi cela se produit

Comment corriger l’erreur

  1. 1.

    Fournir au client les bonnes ancres de confiance

    Même remède que pour l’erreur x509 seule : un pool de racines contenant l’AC émettrice, configuré sur le transport réellement utilisé pour la connexion.

    go
    pool := x509.NewCertPool()
    caPEM, _ := os.ReadFile("ca.pem")
    pool.AppendCertsFromPEM(caPEM)
    
    client := &http.Client{Transport: &http.Transport{
        TLSClientConfig: &tls.Config{RootCAs: pool},
    }}
    resp, err := client.Get("https://internal.example:8443/healthz")
  2. 2.

    Examiner ce que présente le serveur

    Examinez la chaîne servie, ses émetteurs et sa validité avant de toucher au code client : la plupart des corrections relèvent finalement de la configuration de la chaîne côté serveur.

    bash
    openssl s_client -connect internal.example:8443 -servername internal.example \
      </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates
  3. 3.

    Garder la vérification active, même dans les tests

    Les serveurs httptest vous fournissent un client préconfiguré ; utilisez-le au lieu de désactiver la vérification globalement.

    go
    srv := httptest.NewTLSServer(handler)
    defer srv.Close()
    resp, err := srv.Client().Get(srv.URL)   // trusts srv's cert, nothing else

Erreurs associées

Parcourir toute la base de données des erreurs de signature