如何确认来自 Go 客户端的 gRPC 流量是否经过 TLS 加密

How to confirm gRPC traffic from Go client is TLS encrypted

我用 Go 写了一个示例 gRPC 客户端和一个服务器,都配置为服务器验证的 TLS。

客户端 gRPC 调用成功,给我的印象是 TLS 配置正确,否则如果 TLS 握手失败,我希望客户端失败并且不会发出 gRPC 请求(即不默认为明文)。

然而,我对将 Wireshark 连接到该网络以嗅探 TCP 数据包时获得的结果感到困惑。我没有看到任何带有 TLS 的数据包,例如我没有看到 TLS CLIENT HELLO 数据包。

这是因为我误解了我在 Wireshark 中看到的内容,还是我的 gRPC 客户端实际上在执行明文 gRPC?

客户端代码如下所示,请注意 grpc.withTransportCredentials,我认为这意味着它将使用 TLS 或失败,但绝不会使用纯文本:

    // block the dial until connection is successful or 3 sec timeout
    dialOptions := []grpc.DialOption{
        grpc.WithBlock(),
        grpc.WithTimeout(3 * time.Second),
    }

    // Load TLS Configuration
    tlsCredentials, err := LoadTLSCredentials()
    if err != nil {
        log.Fatalf("Failed to load TLS credentials: %v", err)
    }

    dialOptions = append(dialOptions, grpc.WithTransportCredentials(tlsCredentials))

    // Dial the gRPC server
    log.Printf("Dialing %v", *address)
    conn, err := grpc.Dial(*address, dialOptions...)
    if err != nil {
        log.Fatalf("Failed to connect to the server: %v", err)
    }
    defer conn.Close()

    // then this application sets up a gRPC request, and logs the response to stdout,
    // in my testing stdout shows the expected gRPC response, so I'd assume TLS is working.


func LoadTLSCredentials() (credentials.TransportCredentials, error) {
    rootCA, err := ioutil.ReadFile("ca.cert")
    if err != nil {
        return nil, err
    }

    certPool := x509.NewCertPool()
    if !certPool.AppendCertsFromPEM(rootCA) {
        return nil, fmt.Errorf("Failed to add rootCA to x509 certificate pool")
    }

    config := &tls.Config{
        MinVersion: tls.VersionTLS12,
        RootCAs: certPool,
    }

    return credentials.NewTLS(config), nil
}

这里是 Wireshark 的屏幕截图,显示没有 TLS 数据包 而我希望类似于下面的内容清楚地显示一些 TLS activity(不是我的应用程序,图片来自网络用于说明目的)

我 运行 Wireshark v2.6.10 Ubuntu 16.04。源 IP 和目标 IP 匹配我的 gRPC 客户端和服务器 IP(两者都是同一 docker 网络上的 docker 容器)。

这并不重要,但从我的客户端代码中可以看出,我在客户端共享根 CA 证书(自签名)。我可以这样做,因为我同时部署了客户端和服务器。

正如@steffanUllrich 在评论中解释的那样,这是 Wireshark 可以更好地配置为显示 TLS 的情况。我确认 gRPC 交换确实受 TLS 保护。

您应该右键单击数据包列表,然后 select 'decode as..' 菜单项,然后 select 'tls' 强制 wireshark 将此 tcp 端口中的流量解析为 TLS。