gcp

Decoding gRPC Messages using Envoy

2022-10-19

Envoy External Processing Filter which decodes and alters gRPC messages.

In this flow, the envoy filter will recieve gRPC messages from clients over TLS, then decode and send an altered message to the gRPC Server.

images/ext_grpc.png

This sample builds ontop of these articles:

Basically, the external filter will we will load the proto descriptors for the message type, then decode the grpc wire encoded message body, construct a new message, encode the altered message back to wireformat then finally send that to the upstream.

note, i’ve only tested this with unary messages (though streaming would be possible as well)


You can find the source here


In this demo, given the proto

syntax = "proto3";

package echo;

service EchoServer {
  rpc SayHelloUnary (EchoRequest) returns (EchoReply) {}
  rpc SayHelloServerStream(EchoRequest) returns (stream EchoReply) {}
}

message EchoRequest {
  string name = 1;
}

message EchoReply {
  string message = 1;
}

if the client sends SayHelloUnary using EchoRequest with name=alice, the filter will alter the payload and send name=bob to the grpcServer

if the client sendsSayHelloServerStream with name=carol, the gRPC server will stream two responses back with message="hi carol". However the filter will alter the final grpc message to the client as message="hi sally"

First start the external filter and envoy

cd ext_proc/

# start external processing server
go run filter.go

## Start envoy
envoy -c envoy_ext_proc.yaml -l debug

Then the grpc client and server.

cd grpc_server/

# run server
go run greeter_server/grpc_server.go --grpcport :50051 

# test client directly to server
go run greeter_client/grpc_client.go --host localhost:50051
    2022/10/19 17:37:46 hi alice
    2022/10/19 17:37:46 hi carol
    2022/10/19 17:37:46 hi carol

# test client via envoy
go run greeter_client/grpc_client.go --host localhost:8081
    2022/10/19 17:37:56 hi bob
    2022/10/19 17:37:57 hi sally
    2022/10/19 17:37:57 hi sally

Appendix

TODO: see if we can create a wasm filter to do the same (which isn’t that easy since we need to decode the wireformat)

This site supports webmentions. Send me a mention via this form.