使用grpc_cli连接grpc服务时出现SSL版本错误及证书验证问题
解决gRPC单向SSL认证及编译问题
一、修复服务端SSL配置(核心问题)
单向认证(仅服务器认证)场景下,grpc::SslServerCredentialsOptions的pem_root_certs字段是用于双向认证时验证客户端证书的,完全不需要设置。你的服务端代码错误添加了根证书配置,导致SSL握手逻辑异常,修改后的代码如下:
ServerBuilder builder; std::string server_key = readFile("$HOME/test_certs/server.key"); std::string server_cert = readFile("$HOME/test_certs/server.crt"); grpc::SslServerCredentialsOptions ssl_opts; // 移除pem_root_certs的设置,单向认证不需要该配置 ssl_opts.pem_key_cert_pairs.push_back(grpc::SslServerCredentialsOptions::PemKeyCertPair{server_key, server_cert}); builder.AddListeningPort(server_address, grpc::SslServerCredentials(ssl_opts)); builder.RegisterService(&service);
二、修复grpc_cli连接问题
1. 错误原因分析
- 不加
--channel_creds_type ssl:客户端用明文连接SSL端口,协议不匹配触发WRONG_VERSION_NUMBER错误,这是预期行为,必须指定SSL类型。 - 加参数后
CERTIFICATE_VERIFY_FAILED:grpc_cli默认不信任自签名CA证书,需要显式指定信任的根证书或临时跳过验证(仅测试环境)。
2. 正确调用方式
方式一:指定CA根证书(推荐,符合生产规范)
grpc_cli ls --channel_creds_type ssl --ssl_target_name_override localhost --root_certificates $HOME/test_certs/ca.crt <server_address>
--ssl_target_name_override localhost:若服务端连接地址不是证书中的CN(比如用IP连接),需指定该参数匹配证书CN;直接用localhost连接可省略。--root_certificates:指定信任的CA根证书路径。
方式二:跳过证书验证(仅测试用)
grpc_cli ls --channel_creds_type ssl --insecure <server_address>
--insecure参数会跳过证书链和主机名验证,仅用于本地测试,生产环境禁止使用。
三、修复gRPC编译OpenSSL链接错误
使用-DgRPC_SSL_PROVIDER=package切换到系统OpenSSL时,需确保cmake能正确定位OpenSSL的头文件和库文件,常见问题解决方法:
1. 指定OpenSSL路径(非默认安装位置)
若OpenSSL安装在自定义路径(如/usr/local/openssl),添加以下cmake参数:
cmake .. \ -DgRPC_SSL_PROVIDER=package \ -DOPENSSL_ROOT_DIR=/usr/local/openssl \ -DOPENSSL_INCLUDE_DIR=/usr/local/openssl/include \ -DOPENSSL_LIBRARIES=/usr/local/openssl/lib64
2. 确保版本兼容
gRPC master分支支持OpenSSL 3.x,若存在多版本OpenSSL冲突,可先卸载旧版本,或通过LD_LIBRARY_PATH指定运行时库路径:
export LD_LIBRARY_PATH=/usr/local/openssl/lib64:$LD_LIBRARY_PATH
3. 清理缓存重新编译
残留的cmake缓存可能导致链接错误,清理后重新编译:
rm -rf build/ mkdir build && cd build cmake .. [你的编译参数] make -j$(nproc)
四、验证证书有效性(可选)
用OpenSSL工具确认证书生成是否正确:
# 验证服务器证书是否由CA签名 openssl verify -CAfile ca.crt server.crt # 查看证书内容,确认CN字段与服务端地址一致 openssl x509 -in server.crt -text -noout
内容的提问来源于stack exchange,提问作者VorpalSword
相关产品推荐
相关产品推荐

