C++ gRPC客户端如何跳过对等名称验证?
C++ gRPC客户端如何跳过对等名称验证?
我之前在K8s集群内部部署gRPC服务时也碰到过一模一样的问题——旧版gRPC的GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION参数在新版里找不到了,而且内部服务的证书名称经常和调用用的FQDN不匹配,导致连接报错Peer name xxx is not in peer certificate。结合实际踩坑经验,给你两个可行的解决方案:
方案一:覆盖目标验证名称(推荐)
新版gRPC提供了GRPC_SSL_TARGET_NAME_OVERRIDE_ARG参数,让你可以指定客户端验证服务器证书时用的名称,而非默认的连接FQDN。这种方式既解决了名称不匹配的问题,又保留了证书链的安全性验证,比完全跳过验证更稳妥。
具体代码实现如下:
#include <grpcpp/grpcpp.h> #include <grpcpp/security/credentials.h> int main() { grpc::ChannelArguments channel_args; // 替换成服务器证书中实际的CN或SAN名称 channel_args.SetString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, "actual-server-cert-name"); // 配置mTLS所需的客户端证书、根证书等参数 grpc::SslCredentialsOptions ssl_opts; ssl_opts.pem_root_certs = "你的根证书内容"; ssl_opts.pem_private_key = "你的客户端私钥内容"; ssl_opts.pem_cert_chain = "你的客户端证书链内容"; // 创建自定义通道 auto channel = grpc::CreateCustomChannel( "your-service-fqdn:8080", // 实际调用的服务FQDN和端口 grpc::SslCredentials(ssl_opts), channel_args); // 后续使用channel创建stub进行调用 return 0; }
方案二:自定义证书验证回调,跳过名称检查
如果你的场景确实不需要验证服务器证书的名称,可以通过自定义验证回调来完全跳过这一步,同时保留mTLS的客户端证书验证逻辑。
代码示例:
#include <grpcpp/grpcpp.h> #include <grpcpp/security/credentials.h> int main() { grpc::SslCredentialsOptions ssl_opts; // 配置mTLS参数 ssl_opts.pem_root_certs = "你的根证书内容"; ssl_opts.pem_private_key = "你的客户端私钥内容"; ssl_opts.pem_cert_chain = "你的客户端证书链内容"; // 自定义验证回调,跳过对等名称检查 ssl_opts.verify_server_cert = [](const std::string& peer_name, grpc::SslCertVerifyStatus* status, const std::vector<grpc::SslCertPair>& certs) { // 直接将验证状态设为OK,跳过名称匹配检查 *status = GRPC_SSL_CERT_VERIFY_OK; return true; }; auto channel = grpc::CreateCustomChannel( "your-service-fqdn:8080", grpc::SslCredentials(ssl_opts), grpc::ChannelArguments{}); // 后续业务调用逻辑 return 0; }
注意事项
- 优先选择方案一,因为方案二相当于跳过了服务器证书的名称验证,虽然能解决问题,但安全性略低;
- 确保mTLS的参数配置正确:根证书要能信任服务器证书,客户端的私钥和证书链要能被服务器端验证通过;
- 如果你是在K8s内部使用Service名称调用,也可以考虑统一证书的SAN字段包含所有可能的服务名称,从根源上避免名称不匹配的问题。
内容来源于stack exchange
相关产品推荐
相关产品推荐

