Go容器间必须用mTLS实现双向身份认证,服务端需配置ClientAuth: tls.RequireAndVerifyClientCert和ClientCAs(加载同一CA根证书),客户端须同时提供自身证书并信任该CA,路径统一为/etc/tls/,SAN须匹配K8s DNS名,禁用InsecureSkipVerify,Secret挂载权限设为0444。

Go 容器间通信必须用 mTLS(双向 TLS),不能只靠单向 HTTPS 或网络策略;否则无法验证对端身份,等同于裸奔。
服务端配置 tls.Config 强制验签客户端证书
服务端不启用 ClientAuth: tls.RequireAndVerifyClientCert,就只是普通 TLS,起不到容器身份认证作用。常见错误是只配了 Certificates 却漏掉 ClientCAs 和 ClientAuth。
-
ClientCAs必须加载 CA 根证书(如/etc/tls/ca.crt),不能只读 service.crt -
Certificates传入的是服务端自己的证书链,需用tls.LoadX509KeyPair("service.crt", "service.key") - 务必设
MinVersion: tls.VersionTLS12,禁用 TLS 1.0/1.1(Go 1.19+ 默认已禁,但老镜像可能未更新) - 若用
http.Server,启动必须调server.ListenAndServeTLS("", "");若用net.Listener,得先tls.Listen("tcp", ":8080", cfg)
客户端加载自身证书并信任同一 CA 根
客户端代码里只配 RootCAs 是不够的——那只能验证服务端,无法完成 mTLS。它还必须提供自己的证书,否则服务端会拒绝连接,报错 tls: client didn't provide a certificate。
- 用
http.Transport时,TLSClientConfig.Certificates要填[]tls.Certificate{clientCert}(来自tls.LoadX509KeyPair("client.crt", "client.key")) -
TLSClientConfig.RootCAs加载的仍是同一份ca.crt,不是服务端证书 - 别用
InsecureSkipVerify: true,生产环境这等于关掉证书校验 - K8s 中挂载 Secret 后,权限必须为
0444,否则 Go 的crypto/tls会静默失败(不报错,但连接被拒)
证书路径、SAN 和挂载方式必须统一
容器内路径和代码中硬编码路径不一致,是最常导致 “certificate signed by unknown authority” 或 “x509: certificate is valid for xxx, not yyy” 的原因。
立即学习“go语言免费学习笔记(深入)”;
- 所有容器统一挂载证书到
/etc/tls/:即/etc/tls/tls.crt(服务端)、/etc/tls/tls.key、/etc/tls/ca.crt - 服务端证书的
SAN必须含 Kubernetes DNS 名,例如DNS:auth-svc.default.svc.cluster.local,不能只写localhost或 IP - 用 ConfigMap 挂载纯文本证书时,注意换行符是否被破坏(PEM 块末尾缺换行会导致
AppendCertsFromPEM返回 false) - 优先用 Secret + volumeMounts,而非环境变量传 Base64 ——后者易触发 shell 解析截断或长度限制
gRPC 场景下用 credentials.NewTLS 替代手工封装
如果走 gRPC(比 net/rpc 更推荐),不要自己写 tls.Dial 再包 rpc.Client,既冗余又难维护。
- 服务端监听用
grpc.Creds(credentials.NewTLS(tlsConfig)),其中tlsConfig含完整 mTLS 配置 - 客户端 Dial 用
grpc.Dial(addr, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig))) - gRPC 自动处理 ALPN 协商、HTTP/2 多路复用,且
credentials.NewTLS内部已做RootCAs/Certificates合理 fallback - 若需细粒度控制(如禁用某密码套件),直接在
tls.Config里设CurvePreferences或CipherSuites即可
最容易被忽略的其实是证书生命周期管理:自建 CA 签发的证书默认有效期短(如 24 小时),而 Go 服务启动后不会自动重载证书文件。一旦过期,连接全断,但日志里往往只显示 “remote error: tls: bad certificate”,得翻 CA 日志才能定位。


















