Python gRPC服务器开启require_client_auth后证书验证失败求助
gRPC mTLS客户端证书认证失败排查方案
问题背景
搭建启用mTLS的gRPC服务器时,客户端证书认证失败。架构包含自签名根CA(签发服务器证书)和下级CA(签发客户端证书)。移除root_certificates和require_client_auth参数后连接可正常建立,且通过openssl验证所有证书均无问题。
服务器凭证初始化代码
server_credentials = grpc.ssl_server_credentials( [( server_key, # key of server cert server_cert, # server cert (signed by root CA) )], root_certificates=ca_cert, # cert of sub CA require_client_auth=True )
客户端请求命令(grpcurl)
grpcurl --cacert certs/root.crt -cert certs/client.crt -key certs/client.key example.com:8086 list
错误信息
Handshake failed with fatal error SSL_ERROR_SSL: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED. handshake_manager 0x7f1718022110: error=UNKNOWN:Ssl handshake failed: SSL_ERROR_SSL: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED {tsi_code:10, tsi_error:"TSI_PROTOCOL_FAILURE", created_time:"2024-04-16T08:19:04.830816282+00:00"} shutdown=0 index=1, args={endpoint=(nil), args={}, read_buffer=(nil) (length=0), exit_early=0} handshake_manager 0x7f1718022110: handshaking complete -- scheduling on_handshake_done with error=UNKNOWN:Ssl handshake failed: SSL_ERROR_SSL: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED {tsi_code:10, tsi_error:"TSI_PROTOCOL_FAILURE", created_time:"2024-04-16T08:19:04.830816282+00:00"}
排查与解决思路
修复服务器信任链配置:服务器的
root_certificates参数需要传入完整的信任链证书,而非仅下级CA证书。因为客户端证书由下级CA签发,而下级CA本身由根CA签发,服务器必须同时信任根CA和下级CA才能完成客户端证书的链式验证。将根CA和下级CA的证书内容合并到同一个文件中(顺序无强制要求,通常根CA在前),再将该文件内容作为root_certificates的值传入。验证客户端证书链完整性:使用以下命令检查证书链的层级关系:
# 查看客户端证书的签发者 openssl x509 -in certs/client.crt -text -noout | grep -A 2 "Issuer" # 查看下级CA证书的主体(应与客户端证书的签发者一致) openssl x509 -in certs/sub_ca.crt -text -noout | grep -A 2 "Subject" # 查看下级CA证书的签发者(应与根CA的主体一致) openssl x509 -in certs/sub_ca.crt -text -noout | grep -A 2 "Issuer" # 查看根CA证书的主体 openssl x509 -in certs/root.crt -text -noout | grep -A 2 "Subject"确保每一层的签发者与上层的主体完全匹配。
检查证书用途扩展字段:确认客户端证书包含
clientAuth用途,服务器证书包含serverAuth用途:# 检查客户端证书的扩展用途 openssl x509 -in certs/client.crt -text -noout | grep "Extended Key Usage" -A 1 # 检查服务器证书的扩展用途 openssl x509 -in certs/server.crt -text -noout | grep "Extended Key Usage" -A 1如果缺少对应用途,需要重新签发证书时添加该扩展。
确认grpcurl配置正确性:grpcurl的
--cacert参数用于验证服务器证书,这里配置根CA证书是正确的,因为服务器证书由根CA签发。无需修改该参数,重点还是服务器端的信任链配置。
内容的提问来源于stack exchange,提问作者michi-p
相关产品推荐
相关产品推荐

