Go微服务实战|第9章:gRPC TLS Secure

  • 原创
  • Madman
  • /
  • /
  • 0
  • 1568 次阅读

Go 微服务实战.png

Synopsis: 为了保证 gRPC 服务端与客户端之间的数据交互的安全性,需要启用 TLS 加密

代码已上传到 https://github.com/wangy8961/grpc-go-tutorial/tree/v0.9 ,欢迎 star

1. 要点

gRPC 默认使用 HTTP2 来传输用 Protocol buffers 编码后的二进制数据,而 HTTP2 协议需要启用 TLS 加密连接。但是,你会发现前面几篇博文中,我们在没有启用 TLS 加密的情况下,也能正常使用 gRPC,是因为在客户端代码中通过 grpc.Dial(*addr, grpc.WithInsecure()) 中的 grpc.WithInsecure() 暂时禁止了安全传输功能

1.1 ServerOption

服务端代码在 grpc.NewServer() 中接受 0 个或多个选项参数 grpc.ServerOption

func NewServer(opt ...ServerOption) *Server {
    ...
}

我们可以通过 credentials.NewServerTLSFromFile() 来返回 grpc.TransportCredentials

func NewServerTLSFromFile(certFile, keyFile string) (TransportCredentials, error) {
    ...
}

也可以通过如下方式获取 grpc.TransportCredentials

cert, err := tls.LoadX509KeyPair(*certFile, *keyFile)
if err != nil {
    log.Fatalf("failed to load key pair: %s", err)
}
creds := credentials.NewServerTLSFromCert(&cert)

然后再将返回值 grpc.TransportCredentials 传入 grpc.Creds() 函数,就可以获取 grpc.ServerOption(它包含了启用 TLS 连接所需要的参数)

总体代码类似:

creds, err := credentials.NewServerTLSFromFile(certFile, keyFile)
if err != nil {
    log.Fatalf("failed to load certificates: %v", err)
}

s := grpc.NewServer(grpc.Creds(creds))

说明: certFile 是服务端的数字证书(已由 CA 签名),keyFile 是服务端的 私钥。如果你不明白 TLS 加密的原理,请仔细阅读: https://madmalls.com/blog/category/network-security/

1.2 DialOption

客户端代码在 grpc.Dial() 中接受 0 个或多个选项参数 grpc.DialOption

func Dial(target string, opts ...DialOption) (*ClientConn, error) {
    ...
}

我们可以通过 credentials.NewClientTLSFromFile() 来返回 grpc.TransportCredentials

func NewClientTLSFromFile(certFile, serverNameOverride string) (TransportCredentials, error) {
    ...
}

然后再将返回值 grpc.TransportCredentials 传入 grpc.WithTransportCredentials() 函数(客户端产生 DialOption 的函数都以 With 字符开头),就可以获取 grpc.DialOption(它包含了启用 TLS 连接所需要的参数)

总体代码类似:

creds, err := credentials.NewClientTLSFromFile(certFile, "")
if err != nil {
    log.Fatalf("failed to load CA root certificate: %v", err)
}

// Set up a connection to the server.
conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(creds))
if err != nil {
    log.Fatalf("did not connect: %v", err)
}
defer conn.Close()

说明: certFileCA 根证书,用来验证服务端发来的 数字证书。如果你不明白 TLS 加密的原理,请仔细阅读: https://madmalls.com/blog/category/network-security/

2. 申请证书

TLS加密的架构.jpg

假设已经在 192.168.40.128 上搭建了私有 CA,具体步骤请参考: https://madmalls.com/blog/post/openssl-howto/#4-ca 。gRPC 的服务端 IP 为 192.168.40.123,客户端既可以通过此 IP 访问它,也可以通过 www.wangy.com 域名解析访问它,详情可参考: https://madmalls.com/blog/post/migrating-from-http-to-https/#2

现在为 gRPC 服务端申请数字证书:

1. 生成 RSA 私钥
[root@CentOS ~]# (umask 077; openssl genrsa -out server.key 2048)

2. 创建证书签署请求 CSR
[root@CentOS ~]# openssl req -new \
  -key server.key \
  -out server.csr \
  -subj "/C=CN/ST=GuangDong/L=ShenZhen/O=Madmalls.com Co.,Ltd/OU=gRPC Server/CN=*.wangy.com" \
  -reqexts SAN \
  -config <
                                
                            
未经允许不得转载: LIFE & SHARE - 王颜公子 » Go微服务实战|第9章:gRPC TLS Secure

分享

作者

作者头像

Madman

如需 Linux / Python 相关问题付费解答,请按如下方式联系我

0 条评论

暂时还没有评论.