dexidp / dex

OpenID Connect (OIDC) identity and OAuth 2.0 provider with pluggable connectors
https://dexidp.io
Apache License 2.0
9.52k stars 1.71k forks source link

GRPC server: baseTLSConfig should include "h2" in NextProtos to support ALPN #3860

Open nr-tdeluna opened 3 days ago

nr-tdeluna commented 3 days ago

Preflight Checklist

Version

2.41.1

Storage Type

Postgres

Installation Type

Official container image, Custom container image

Expected Behavior

go clients using grpc-go versions 1.67.0 and above should be able to connect to the Dex gRPC service via mTLS without having to set the environment variable GRPC_ENFORCE_ALPN_ENABLED=false .

Actual Behavior

When trying to connect the client fails with the log message:

transport: authentication handshake failed: credentials: cannot check peer: missing selected ALPN property

Steps To Reproduce

  1. Create mTLS certificates using examples/grpc-client/cert-gen
  2. Start the server with mTLS enabled as described in examples/grpc-client/README.md
  3. Create a new go module, copy the dex go client example in examples/grpc-client/client.go
  4. Ensure go-grpc dependency 1.67.0 or later with go get google.golang.org/grpc@v1.67.0
  5. Try to connect and see the client error logs.

Additional Information

Summary

The dex gRPC server is not doing proper protocol negotiation when served through TLS. It's not advertising http2 during protocol negotiation.

The default value of the environment variable GRPC_ENFORCE_ALPN_ENABLED changed from false to true on version 1.67.0. This causes clients to fail when the server does not advertise http2.

https://github.com/grpc/grpc-go/pull/7535

Details

The baseTLSConfig created for the gRPC service should include NextProtos: []string{"h2"}, https://github.com/dexidp/dex/blob/fa0240d396db1d8ed02ff52f8d010786aacd6936/cmd/dex/serve.go#L176-L181

In most cases "h2" is added by go-grpc's credentials.NewTLS https://github.com/grpc/grpc-go/blob/2da976983bbb33feb3e25b7daaa8f60b9769adb5/credentials/tls.go#L201-L204

But dex's fsnotify reloader returns a certificate based on the original baseTLSConfig. Any modifications by go-grpc are discarded. https://github.com/dexidp/dex/blob/fa0240d396db1d8ed02ff52f8d010786aacd6936/cmd/dex/serve.go#L657-L660

Configuration

No response

Logs

No response