如何确认来自Go客户端的gRPC流量已进行TLS加密

问题描述

我在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数据包

wireshark screenshot

而我期望与以下内容类似的内容可以清楚地显示一些TLS活动(不是我的应用程序,图像是出于说明目的来自网络)

enter image description here

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

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

解决方法

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

,

您应该右键单击数据包列表,然后选择“解码为..”菜单项,然后选择“ tls”以强制Wireshark将该TCP端口中的流量分解为TLS。