Sample client server in golang that demonstrates how to decode protobuf messages for a gRPC Client->Server over TLS.
This is nothing new and is described here in wireshark’s documentation (How to Export TLS Master keys of gRPC)
What drove me to write this sample was a co-woker who as interested in viewing gRPC protbuf message in java for Google Cloud Pubsub.
Since i earlier worked on similar stuff in other repos like
i figured i’d give it a shot..it took a little bit to get going since i had to decode TLS and ultimately upgrade wireshark (per wireshark issue#17744)).
Anyway, what this repo does show is a very simple go-based client/server gRPC system that does unary, client streaming, server streaming and full bidi. All along the tls traffic is seen by wireshark, decrypted and after that, parsed using the
you’ll find the source here
Lets get started
First thing is to setup the client server and wireshark (plase note, use wireshark
For wireshark, we will save the TLS encryption keys to
/tmp/keylog.log. This file contains the TLS keys in NSS Key Log Format which golang can output and wireshark can consume.
First tell wireshark where to find it
Now we need to tell wireshark how to decode the proto after TLS is done. For that, we will configure wireshark to look at
You’ll also want to install protoc core
in my case, it was unzipped to
/usr/local/include/ (i.,e the
.proto are under
Then specify them in the configurations
Now we’re ready to start the gRPC Server
# optionally, if you really want to compile from source... # protoc --go_out=. --go_opt=paths=source_relative --go-grpc_opt=require_unimplemented_servers=false --go-grpc_out=. --go-grpc_opt=paths=source_relative src/echo/echo.proto go run src/grpc_server.go \ --grpcport 0.0.0.0:50051 \ --tlsCert=certs/grpc_server_crt.pem \ --tlsKey=certs/grpc_server_key.pem
Now start wireshark. In a new window run
Once you start wireshark, select the ’lo’ (local interface)
Run the client but first tell it where to log the keys
export SSLKEYLOGFILE=/tmp/keylog.log go run src/grpc_client.go \ --host 127.0.0.1:50051 \ --tlsCert=certs/CA_crt.pem \ --servername=grpc.domain.com
Note, to use go, you need to first ask it to dump the keylog per crypto.tls.Config.KeyLogWriter. Please take careful note of the dangers described there…
The output of the various modes
Stream ID 15 is used in both paths
I’ve also left a sample keylog and wireshark file for you to load and test decoding
Ok, so now we’re back to what i really wanted to do…decode PubSub.
protoc if you haven’t already
# https://grpc.io/docs/protoc-installation/ # in my case, it was unzipped to /usr/local/include/google/protobuf/ # first get all the protos git clone https://github.com/googleapis/googleapis.git
Then tell wireshark to load the proto files: (note, the spot where
googleapis/ folder is will be different)
$ more /home/srashid/.config/wireshark/protobuf_search_paths # This file is automatically generated, DO NOT MODIFY. "/usr/local/include","TRUE" "/home/srashid/Desktop/grpc_sslkeylog/googleapis","TRUE"
Anyway, if you ran the grpc client in this repo, and prior to that set the
SSLKEYLOGFILE parameter, you should be able to see the pubsub traffic if you use the following
filter in wireshark:
tcp.port == 443 and tls.handshake.extensions_server_name=="pubsub.googleapis.com"
However, even if you cant’ see the traffic, you can still see the bytes…presumably, you can dump the
DATA to a file from wireshark, then use go to read each payload as protoMessage
I tried to use jSSLKeyLog with Cloud PubSub in Java and while it did dump the keys to a file, I wasn’t able to use wireshark to decrypt the data
I’ve left off as far as i got with that here in he repo
# run standalone mvn clean install exec:java # create fatjar mvn clean package # or as package java -jar target/TestApp-1.0-SNAPSHOT-jar-with-dependencies.jar