Aller au contenu
ecdsa.com
Go crypto/tlsGo

Message d’erreur

tls: first record does not look like a TLS handshake

gRPC, les pilotes de base de données et d’autres bibliothèques l’enveloppent dans leurs propres messages : cherchez donc le texte central dans les journaux. Face à une réponse HTTP, net/http affiche plutôt « http: server gave HTTP response to HTTPS client ».

Go crypto/tls — the peer's first bytes are not a TLS record (tls.Dial, gRPC, database drivers, http.Client)

Ce que cela signifie

Le client TLS de Go a envoyé un ClientHello, et le premier enregistrement reçu en retour n’a pas la structure d’un enregistrement de handshake TLS : il abandonne donc immédiatement. Le pair parle autre chose sur ce port : du HTTP en clair (quand Go ne parvient pas à le reconnaître comme tel), un serveur gRPC en clair, le message d’accueil d’un protocole de base de données ou de messagerie. Les serveurs Go consignent différemment la situation inverse, celle d’un client qui parle en clair à un port TLS.

Pourquoi cela se produit

Comment corriger l’erreur

  1. 1.

    Vérifier ce que parle le port

    Un handshake TLS avec openssl, ou un rapide coup d’œil à la bannière, montre si le port parle TLS ou non.

    bash
    # Does the port speak TLS?
    openssl s_client -connect api.example.com:8080 -servername api.example.com -brief </dev/null
    timeout 3 nc api.example.com 8080 </dev/null | head -1     # a text banner = plain protocol
  2. 2.

    gRPC : utiliser les informations d’identification attendues par le serveur

    Des informations d’identification TLS pour les serveurs TLS ; des informations d’identification non sécurisées uniquement pour les serveurs en clair sur des réseaux de confiance.

    go
    // gRPC: match the server. Plaintext server -> insecure credentials (only on trusted networks);
    // TLS server -> TLS credentials.
    conn, err := grpc.NewClient("api.example.com:9090",
    	grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{ServerName: "api.example.com"})))
  3. 3.

    Utiliser STARTTLS là où le protocole l’exige

    StartTLS de net/smtp (et ses équivalents dans les pilotes de base de données, par exemple sslmode pour PostgreSQL) fait basculer la connexion en TLS sur le même canal.

    go
    // SMTP on 587 starts in plain text: use STARTTLS, not tls.Dial
    c, err := smtp.Dial("mail.example.com:587")
    if err == nil {
    	err = c.StartTLS(&tls.Config{ServerName: "mail.example.com"})
    }

Erreurs associées

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