mipnw
mipnw

Reputation: 2355

How to confirm gRPC traffic from Go client is TLS encrypted

I wrote a sample gRPC client a server in Go, both configured for server-authenticated TLS.

The client gRPC call succeeds, giving me the impression the TLS is configured properly, otherwise if the TLS handshake had failed, I would expect the client to fail and not make the gRPC request (i.e. not default to plaintext).

Yet I am puzzled by a result I obtain when I attach Wireshark to that network to sniff TCP packets. I do not see any packet with TLS, for e.g. I do not see the TLS CLIENT HELLO packet.

So is this because I'm misinterpreting what I see in Wireshark, or is my gRPC client actually doing plaintext gRPC?

The client code looks like this, note the grpc.withTransportCredentials which I think means it will use TLS or fail, but never plaintext:

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

And here's a screenshot of Wireshark showing no TLS packet wireshark screenshot whereas I would expect something similar to the following which clearly shows some TLS activity (not my app, image is from the web for illustration purposes) enter image description here

I'm running Wireshark v2.6.10 on Ubuntu 16.04. The source and destination IPs match my gRPC client and server IPs (both are docker containers on the same docker network).

Not that it really matters, but as can be seen in my client code, I'm sharing a root CA certificate on the client (self signed). I can do this because I deploy both the client and the server.

Upvotes: 4

Views: 1744

Answers (2)

Skison
Skison

Reputation: 101

You should right click the packet list, and select 'decode as..' menu item, then select 'tls' to force wireshark dissect traffic in this tcp port as TLS.

Upvotes: 0

mipnw
mipnw

Reputation: 2355

As @steffanUllrich explained in the comments, this was a case of Wireshark can be better configured to show TLS. I confirmed the gRPC exchange is indeed TLS protected.

Upvotes: 1

Related Questions