Skip to content

gRPC server and client

Nicolas Steenlant edited this page Oct 29, 2022 · 3 revisions

Biblio client examples

local development

go run client/main.go publication get 01GGCPYR3HWPGPF2SEZZA7T5V2 --port 3001 --insecure --username XXX --password XXX

remote with tls

go run client/main.go publication get-all --host backend.bibliotest.ugent.be --port 443 --username XXX --password XXX

debug

GODEBUG=http2debug=2  go run client/main.go

grpcurl client examples

brew install grpcurl

CREDS=$(echo -n "XXX:XXX" | base64)

grpcurl -proto dev/biblio-backoffice/api/v1/biblio.proto -expand-headers -H "Authorization: Basic $CREDS" backend.bibliotest.ugent.be:443 biblio.v1.Biblio.GetAllPublications

grpcurl -proto dev/biblio-backoffice/api/v1/biblio.proto -expand-headers -H "Authorization: Basic $CREDS" -d '{"id": "7035921"}' backend.bibliotest.ugent.be:443 biblio.v1.Biblio.GetPublication

Setup server behind traefik with tls and basic auth

NOTE: we now use grpc ServeHTTP but we should run the grpc standalone server (which also handles h2c traffic by default) behind traefik in the future

traefik needs to pass plain text http2 to the proxied service:

- 'traefik.http.routers.grpc-app.service=grpc-app'
- 'traefik.http.services.grpc-app.loadbalancer.server.scheme=h2c'

set api username and password:

BIBLIO_BACKEND_API_USERNAME: "XXX"
BIBLIO_BACKEND_API_PASSWORD: "XXX"

Relevant go server snippets

// route traffic to grpc or app
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   if r.ProtoMajor == 2 && strings.HasPrefix(r.Header.Get("Content-Type"), "application/grpc") {
	grpcHandler.ServeHTTP(w, r)
    } else {
	appHandler.ServeHTTP(w, r)
    }
})

// handle plain text http2 requests with h2c
server := &http.Server{
	Addr:         addr,
	Handler:      h2c.NewHandler(handler, &http2.Server{}),
	ReadTimeout:  3 * time.Minute,
	WriteTimeout: 3 * time.Minute,
}

Resources

OLD DOCUMENTATION BELOW

TLS and gRPC

TLS or Transport Layer Security is used to secure gRPC communication between services as well as the communication between the CLI Client and Biblio.

CLI Client / Server

The connection is secured using server-side TLS instead of mTLS (mutual TLS). This is okay for a CLI client since multiple clients can be installed and connect with the server. TLS is used to assure the integrity of the messages on both ends of the connection, as well as blocking eavesdropping.

More info:
https://dev.to/techschoolguru/how-to-secure-grpc-connection-with-ssl-tls-in-go-4ph
https://github.com/grpc/grpc-go/tree/master/examples/features/encryption
https://youngkin.github.io/post/gohttpsclientserver/

Running the biblio API server with TLS enabled:

go run main.go api start --api-tls-enabled --api-tls-servercert cert/server.pem --api-tls-serverkey cert/server.key

server.pem and server.key are, respectively, a server TLS certificate as well as a TLS key. You will need both here. Either acquire a pair from a trusted Certificate Authority (CA) or use a self-signed pair generated with openssl.

Running the biblio CLI client with TLS enabled:

Important! TLS is enabled by default as a security safeguard.

go run main.go publication get-all --api-tls-ca-cert cert/ca.pem

ca.pem is the CA certificate used to generate server.pem and server.key. The client requires ca.pem in order to verify the server certificates during initial TLS handshake and agree on a common cipher and secret used to secure the connection.

You can also run the client without providing --api-tls-ca-cert. The client will fallback to the operating system CA certificates. Go's [crypto/x509](https://pkg.go.dev/crypto/x509) can retrieve these certificates transparantly via the x509.SystemCertPool() function. This is useful for connecting to server endpoints secured with server certificates signed with public CA root certificates e.g. Let's Encrypt.

Running insecure

If you want to run the server in insecure - non TLS - mode (e.g. development):

go run main.go api start

... and the client:

go run main.go publication get-all --api-tls-disabled

Secure service-to-service communication

TBD

Clone this wiki locally