Python 客户端在 GRPC 存根上返回 CERTIFICATE_VERIFY_FAILED

Posted

技术标签:

【中文标题】Python 客户端在 GRPC 存根上返回 CERTIFICATE_VERIFY_FAILED【英文标题】:Python client returns CERTIFICATE_VERIFY_FAILED on GRPC stub 【发布时间】:2021-11-22 16:37:02 【问题描述】:

我有这个简单的代码可以连接到使用GRPC下载一些数据

creds = grpc.ssl_channel_credentials()
channel = grpc.secure_channel(f'HOST:PORT', credentials=creds)
stub = liveops_pb2_grpc.LiveOpsStub(channel=channel)
request = project_pb2.ListProjectsRequest(organization=ORGANIZATION)
projects = stub.ListProjects(request=request)
print(projects)

这在星期三运行良好。它在带有Python 3.8.10protobuf==3.18.0grpcio==1.40.0grpcio-tools==1.40.0 的docker 容器中运行。

今天我更新了MAC OS Big Sur to 11.6,在完成了代码的一些额外功能后,我看到它返回了:

E0930 21:12:04.108551900       1 ssl_transport_security.cc:1468] Handshake failed with fatal error SSL_ERROR_SSL: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED.
E0930 21:12:04.194319000       1 ssl_transport_security.cc:1468] Handshake failed with fatal error SSL_ERROR_SSL: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED.
E0930 21:12:04.286163700       1 ssl_transport_security.cc:1468] Handshake failed with fatal error SSL_ERROR_SSL: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED.
Traceback (most recent call last):
  File "", line 302, in <module>
    projects = liveops_stub.ListProjects(request=request)
  File "/home/airflow/.local/lib/python3.8/site-packages/grpc/_channel.py", line 946, in __call__
    return _end_unary_response_blocking(state, call, False, None)
  File "/home/airflow/.local/lib/python3.8/site-packages/grpc/_channel.py", line 849, in _end_unary_response_blocking
    raise _InactiveRpcError(state)
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
    status = StatusCode.UNAVAILABLE
    details = "failed to connect to all addresses"
    debug_error_string = ""created":"@1633036324.286560700","description":"Failed to pick subchannel","file":"src/core/ext/filters/client_channel/client_channel.cc","file_line":3186,"referenced_errors":["created":"@1633036324.286548700","description":"failed to connect to all addresses","file":"src/core/lib/transport/error_utils.cc","file_line":146,"grpc_status":14]"
>

似乎与 SSL 证书有关。 如果我检查 /etc/ssl/certs 文件夹它是空的,那么 SSL SO 证书是否已被删除?

我该如何解决?

【问题讨论】:

【参考方案1】:

Let's Encrypt cross-signed DST Root CA X3 expired 昨天,它在一些客户端上引起了一些 SSL 问题。我设法通过手动更改中间链以使用新的Root X1 来修复它。 在服务器上,运行:

sudo certbot certonly --nginx -d <ADDRESS> --preferred-chain "ISRG Root X1"

如果您没有运行 nginx,您可能需要将其替换为您的服务器,并确保重新启动它。

【讨论】:

是的,我刚刚修好了。我也会提供答案,因为我没有运行 nginx。谢谢!【参考方案2】:

正如 Firas Al Mannaa 所说,Let's Encrypt cross-signed DST Root CA X3 昨天过期,它在一些客户端上导致了一些 SSL 问题。

我添加了一个从 ca-bundle 获取证书的新功能:

def get_ssl_certificate():
    request_response = req.get('https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt')
    certificate_content = request_response.text
    certificate_as_bytes = str.encode(certificate_content)

    return certificate_as_bytes

然后我使用了这个证书

creds = grpc.ssl_channel_credentials(root_certificates=certificate_as_bytes)

【讨论】:

以上是关于Python 客户端在 GRPC 存根上返回 CERTIFICATE_VERIFY_FAILED的主要内容,如果未能解决你的问题,请参考以下文章

csharp中的grpc通道/存根线程是不是安全

存根的 gRPC 并发

gRPC实践:Server&Client

gRPC 中的通道/存根是线程安全的吗

GoLang -- gRPC框架四大服务

Golang 语言 gRPC 服务怎么同时支持 gRPC 和 HTTP 客户端调用?