场景:golang作为服务端,python作为客户端,grpc的加密传输
试了网上很多的方法,有带ca的有不带的,天花乱坠头都晕了。最烦躁的是网上服务器和客户端都是同一语言的,试了下都不怎么灵光。纠结了不少时间后,终于试出一套最简单的能调通的方案。
本方案不使用ca,因此不够高大上,但对于一般应用的安全需求应该是没问题了。
第一步:生成证书
在安装了openssl的linux系统上,敲下如下命令:
openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -days 3650 -out server.crt
然后命令行会让你敲一大堆东西:
Country Name (2 letter code) [XX]:xx
State or Province Name (full name) []:xx
Locality Name (eg, city) [Default City]:xx
Organization Name (eg, company) [Default Company Ltd]:xx
Organizational Unit Name (eg, section) []:xx
Common Name (eg, your name or your server's hostname) []:grpc-aggregate
Email Address []:xx
此处需要注意的是Common Name的输入,我输入的是grpc-aggregate,即我的业务名。
得到用到且仅用到的两个文件: server.key, server.crt,将其重命名为aggregate-server.key, aggregate-server.crt;这个重命名根据具体项目需要自由命名即可。
第二步:golang服务端编写
先将aggregate-server.key, aggregate-server.crt放到golang项目的根目录中,启动grpc的代码大致如下:
func (nk *Nk) startGrpc() {
log.Info("begin to start rpc server")
lis, err := net.Listen("tcp", ":52091")
if err != nil {
log.Error("failed to listen: %v", err)
return
}
creds, err := credentials.NewServerTLSFromFile("aggregate-server.crt", "aggregate-server.key")
if err != nil {
log.Error("could not load TLS keys: %s", err)
return
}
s := grpc.NewServer(grpc.Creds(creds))
aggregatepb.RegisterAggregateServer(s, dragonstone.NewServicer())
// Register reflection service on gRPC server.
reflection.Register(s)
log.Info("grpc prepare to listen...")
if err := s.Serve(lis); err != nil {
log.Error("failed to serve: %v", err)
}
}
第三步:python客户端的编写
将aggregate-server.crt放到python项目根目录下,代码大致如下:
with open('aggregate-server.crt', 'rb') as f:
trusted_certs = f.read()
creds = grpc.ssl_channel_credentials(root_certificates=trusted_certs)
# 1
channel = grpc.secure_channel(address, creds, options=(('grpc.ssl_target_name_override', "grpc-aggregate",),))
client = aggregate_pb2_grpc.AggregateStub(channel)
这里面尤其要注意的是#1处,
options=(('grpc.ssl_target_name_override', "grpc-aggregate",),)
标红的即为第一步中你填入的Common Name,必须保持一致,否则是访问不了服务端的。