我有一个grpc服务器(在Go),有一个有效的TLS证书,不需要客户端TLS。由于某些原因,我无法在Python中实现没有mTLS的客户端,尽管我可以在Golang中这样做。
在Python中我有
os.environ["GRPC_VERBOSITY"] = "DEBUG"
# os.environ["GRPC_DEFAULT_SSL_ROOTS_FILE_PATH"] = "/etc/ssl/certs/ca-bundle.crt"
channel = grpc.secure_channel(ADDR, grpc.ssl_channel_credentials())
grpc.channel_ready_future(channel).result(timeout=10)
这给了我以下错误
D0513 08:02:08.147319164 21092 security_handshaker.cc:181] Security handshake failed: {"created":"@1652446928.147311309","description":"Handshake failed","file":"src/core/lib/security/transport/security_handshaker.cc","file_line":377,"tsi_code":10,"tsi_error":"TSI_PROTOCOL_FAILURE"}
如果我使用SSL证书,取消注释掉的行,我可以让它工作。我知道一个事实,我的服务器不请求,要求或验证客户端证书作为以下Go代码工作完美
conn, err := grpc.DialContext(
ctx,
gRPCAddr,
grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")),
)
dummyClient := dummy.NewDummyServiceClient(conn)
if _, err := dummyClient.Ping(context.Background(), &dummy.PingRequest{
Ping: "go client ping",
}); err != nil {
return fmt.Errorf("failed to ping: %w", err)
}
如果服务器端的证书是公开签名的,则可以使用:
grpc.secure_channel(ORBIUM_ADDR, grpc.ssl_channel_credentials())
但这似乎对你不起作用,所以我猜服务器证书是由你拥有的根证书签名的。您可以将根证书传入root_certificates
字段[1],而将其他两个字段保留为空。这个用例记录在我们的认证指南[2]中。
with open(os.environ["GRPC_DEFAULT_SSL_ROOTS_FILE_PATH"], 'rb') as f:
creds = grpc.ssl_channel_credentials(f.read())
channel = grpc.secure_channel(ORBIUM_ADDR, creds)
[1] https://grpc.github.io/grpc/python/grpc.html grpc.ssl_channel_credentials
[2] https://grpc.io/docs/guides/auth/https://grpc.github.io/grpc/python/_modules/grpc.html#secure_channel有channel = grpc.secure_channel(ORBIUM_ADDR, grpc.ssl_channel_credentials())
的文档。这个函数依赖于类通道,参见docs https://grpc.github.io/grpc/python/_modules/grpc/aio/_channel.html。
@former_Epsilon给出的答案回答了我的问题,但是我为这个问题提出的解决方案是不同的,我最终使用了secure_channel
,所以我想发布一个答案。
import os
import grpc
# configure this dict for your systems
system_certs_map = {
"Windows": "<Path to system cert>",
"Darwin": "$REQUESTS_CA_BUNDLE",
"Linux": "/etc/ssl/certs/ca-bundle.crt",
}
os.environ["GRPC_DEFAULT_SSL_ROOTS_FILE_PATH"] = system_certs_map[platform.system()]
channel_credentials = grpc.ssl_channel_credentials()
基于Python GRPC文档https://grpc.github.io/grpc/python/grpc.html
channel = grpc.insecure_channel(ORBIUM_ADDR)
代替:
channel = grpc.secure_channel(ORBIUM_ADDR, grpc.ssl_channel_credentials())