Mensagem de erro
remote error: tls: unknown certificate authority
Servidores Go registram “http: TLS handshake error from <client>: remote error: tls: unknown certificate authority”. Nos nossos testes, quando clientes OpenSSL 3.5 rejeitavam o mesmo certificado via TLS 1.3, o servidor Go 1.27 registrava, em vez disso, “local error: tls: bad record MAC”; já os clientes Go enviam bad_certificate (registrado como “remote error: tls: bad certificate”).
Go crypto/tls — TLS alert 48 (unknown_ca) received from the peer, e.g. an OpenSSL-based client rejecting a Go server's certificate
O que significa
O outro lado da conexão enviou o alerta TLS 48 (unknown_ca): não conseguiu ligar o certificado recebido a uma CA em que confia. No log de um servidor Go, isso significa que um cliente (baseado em OpenSSL: curl, Python, Ruby, PHP, nginx como proxy) rejeitou o certificado do servidor durante um handshake TLS 1.2. Em um cliente Go, significa que o servidor rejeitou o certificado de cliente no TLS mútuo.
Por que acontece
O cliente não confia na CA emissora
comumCAs privadas ou da empresa que as máquinas ou os contêineres clientes não têm.
O servidor Go envia só o certificado folha
comumO ListenAndServeTLS envia exatamente os certificados que estão no arquivo; um arquivo só com o certificado folha deixa os clientes sem como chegar a uma raiz.
TLS mútuo: o servidor não confia na CA do cliente
ocasionalNo lado do cliente, este alerta significa que o ClientCAs do servidor não inclui o emissor do certificado de cliente.
Como corrigir
- 1.
Verificar, de um cliente, a cadeia servida
Se só o certificado folha é enviado, corrija o arquivo; se a cadeia termina em uma raiz privada, instale essa raiz nos clientes.
bash openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \ | grep -E '^ *[0-9]+ s:|^ *i:|Verify return code' - 2.
Servir a cadeia completa no servidor Go
Coloque o certificado folha e os intermediários dele no arquivo PEM passado ao ListenAndServeTLS (ou ao tls.LoadX509KeyPair).
go // Leaf + intermediates in one file; Go sends every certificate in it srv := &http.Server{Addr: ":443"} log.Fatal(srv.ListenAndServeTLS("fullchain.pem", "server.key")) - 3.
Instalar a raiz privada nos clientes
Para serviços internos, distribua a raiz da empresa para os sistemas e contêineres que chamam o servidor.
bash # Private CA: install the root on the clients (Debian/Ubuntu example) sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt && sudo update-ca-certificates