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
Client TLS face à un port en clair
fréquenteUn port de service sans TLS, souvent celui d’un sidecar ou d’un écouteur interne, appelé avec tls.Dial ou https://.
Client gRPC avec des informations d’identification TLS face à un serveur en clair
fréquenteLes serveurs de développement tournent souvent sans TLS alors que le client est construit avec des informations d’identification TLS (ou l’inverse, ce qui échoue côté serveur).
TLS implicite face à un protocole STARTTLS
occasionnelleSMTP sur le port 587, PostgreSQL, MySQL, Redis avec TLS sur un autre port : le serveur envoie d’abord un message d’accueil en clair.
Comment corriger l’erreur
- 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.
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.
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"}) }