方案:使用 ALTS或TLS加密传输
grpc 框架内有实现相关代码:
服务端实现:
func (s *Server) handleRawConn(rawConn net.Conn) {if s.quit.HasFired() {rawConn.Close()return}rawConn.SetDeadline(time.Now().Add(s.opts.connectionTimeout))// 认证信息,tls或 alts服务解密conn, authInfo, err := s.useTransportAuthenticator(rawConn)if err != nil {// ErrConnDispatched means that the connection was dispatched away from// gRPC; those connections should be left open.if err != credentials.ErrConnDispatched {s.mu.Lock()s.errorf("ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err)s.mu.Unlock()channelz.Warningf(s.channelzID, "grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err)rawConn.Close()}rawConn.SetDeadline(time.Time{})return}
客户端实现:
func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts ConnectOptions, onPrefaceReceipt func(), onGoAway func(GoAwayReason), onClose func()) (_ *http2Client, err error) {
// 拨号连接
conn, err := dial(connectCtx, opts.Dialer, addr.Addr)
if err != nil {
if opts.FailOnNonTempDialError {
return nil, connectionErrorf(isTemporary(err), err, "transport: error while dialing: %v", err)
}
return nil, connectionErrorf(true, err, "transport: Error while dialing %v", err)
}
// ...
// 有证书,则用https
if transportCreds != nil {
scheme = "https"
conn, authInfo, err = transportCreds.ClientHandshake(connectCtx, addr.Authority, conn)
if err != nil {
return nil, connectionErrorf(isTemporary(err), err, "transport: authentication handshake failed: %v", err)
}
isSecure = true
}
//...
}
TLS为例:
使用方法:
服务端:
// Create tls based credential.
creds, err := credentials.NewServerTLSFromFile(testdata.Path("server1.pem"), testdata.Path("server1.key"))
if err != nil {
log.Fatalf("failed to create credentials: %v", err)
}
s := grpc.NewServer(grpc.Creds(creds))
client端:
// Create tls based credential.
creds, err := credentials.NewClientTLSFromFile(testdata.Path("ca.pem"), "x.test.youtube.com")
if err != nil {
log.Fatalf("failed to load credentials: %v", err)
}
// Set up a connection to the server.
conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(creds), grpc.WithBlock())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
