方案:使用 ALTS或TLS加密传输
grpc 框架内有实现相关代码:

服务端实现:

  1. func (s *Server) handleRawConn(rawConn net.Conn) {
  2. if s.quit.HasFired() {
  3. rawConn.Close()
  4. return
  5. }
  6. rawConn.SetDeadline(time.Now().Add(s.opts.connectionTimeout))
  7. // 认证信息,tls或 alts服务解密
  8. conn, authInfo, err := s.useTransportAuthenticator(rawConn)
  9. if err != nil {
  10. // ErrConnDispatched means that the connection was dispatched away from
  11. // gRPC; those connections should be left open.
  12. if err != credentials.ErrConnDispatched {
  13. s.mu.Lock()
  14. s.errorf("ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err)
  15. s.mu.Unlock()
  16. channelz.Warningf(s.channelzID, "grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err)
  17. rawConn.Close()
  18. }
  19. rawConn.SetDeadline(time.Time{})
  20. return
  21. }

客户端实现:

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)
    }