kratos服务端tls配置必须显式传入tls.config实例,通过tlsconfig(c *tls.config)选项生效;需包含certificates字段,支持mtls时还需设置clientauth和clientcas,框架不自动解析pem/jsk文件或读取系统truststore。

Kratos 服务端 TLS 配置必须显式传入 tls.Config,不能只靠环境变量或配置文件自动加载。框架本身不解析 PEM 或 JKS 文件,也不自动读取系统 truststore;所有证书、私钥、CA 根证书都得由你构造好 tls.Config 实例后,通过 TLSConfig(c *tls.Config) 传给 NewServer()。
kratos.Server 的 TLSConfig 是唯一生效入口
很多人误以为在 YAML 配置里写个 tls: {cert: ..., key: ...} 就能启用 HTTPS,但 Kratos 的 ServerOption 设计是纯代码驱动的。配置项只是数据,真正起作用的是你调用 TLSConfig 时传进去的那个 Go 结构体。
-
tls.Config必须包含Certificates字段(至少一个tls.Certificate),否则启动时会 panic 报"no certificate" - 若要支持双向认证(mTLS),需同时设置
ClientAuth(如tls.RequireAndVerifyClientCert)和ClientCAs(加载 CA 根证书的*x509.CertPool) - 不建议复用全局
tls.Config实例:多个 Server 共享同一实例时,GetCertificate回调可能被并发调用,若内部有非线程安全逻辑会出问题
证书加载常见错误:PEM 解析失败、密钥不匹配、SAN 缺失
报错如 "x509: certificate signed by unknown authority" 或 "tls: failed to find any PEM data in certificate input",基本都卡在这三步。
- 用
tls.LoadX509KeyPair(<code>cert.pem,key.pem) 加载时,cert.pem必须是完整证书链(含 leaf + intermediate),不能只放 leaf 证书;key.pem必须是未加密的 PKCS#1 或 PKCS#8 格式(OpenSSL 默认生成的是 PKCS#1,带-----BEGIN RSA PRIVATE KEY-----) - 用
crypto/tls自己解析 PEM 时,别漏掉中间证书:调用certpool.AppendCertsFromPEM()前,确保传入的是拼接好的 fullchain.pem(leaf + intermediates),不是单个 cert - 如果服务跑在 Kubernetes 里且用 Ingress 暴露,
cert.pem的Subject Alternative Name (SAN)必须包含 Ingress 域名(如example.com),否则客户端(比如 curl 或浏览器)校验失败
客户端连接 Kratos gRPC 服务时的 TLS 问题
gRPC 默认走明文,Kratos 的 grpc.Creds(credentials.NewTLS(...)) 只影响服务端监听;客户端必须自己配 credentials.TransportCredentials,否则连不上或报 "connection closed"。
- Go 客户端要用
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{InsecureSkipVerify: true}))(仅测试)或正确加载 server CA 到RootCAs - Java 客户端(如 grpc-java)需显式设置
ManagedChannelBuilder.sslContext(...),不能依赖 JVM 默认 truststore——除非你把 server CA 导入了$JAVA_HOME/jre/lib/security/cacerts - curl 测试 gRPC over TLS 要加
--http2 --cacert ca.crt,且服务端必须开启 HTTP/2(Kratos 默认已开,无需额外配置)
最易被忽略的一点:Kratos 的 TLSConfig 不控制客户端证书验证行为的粒度。比如你想对某些路径跳过客户端证书校验,它做不到——那是 gRPC 拦截器或自定义 GetConfigForClient 回调的事。TLS 层只管“有没有证书、能不能验”,业务级的条件放行必须在应用层做。











