grpc-go: Surface TLS errors to RPC errors

Hello, I was trying to check what error was returned from the server when the client’s certificate is expired. The error I got was generic: transport is closing. At first I was thinking the idea was to not expose the error, for security reasons. However, after some research, I’ve found that the std tls package sends alerts to the client, in that case the alert was: alertBadCertificate. So far so good, but it turned out that the grpc http2 client disregards that alert and does not expose it to the end user. That’s the code where error/alert is disregarded:

// .../google.golang.org/grpc@v1.27.0/internal/transport/http2_client.go:1242

func (t *http2Client) reader() {
	defer close(t.readerDone)
	// Check the validity of server preface.
	frame, err := t.framer.fr.ReadFrame()
	if err != nil {
		t.Close() // this kicks off resetTransport, so must be last before return
		return
	}
	t.conn.SetReadDeadline(time.Time{}) // reset deadline once we get the settings frame (we didn't time out, yay!)
	if t.keepaliveEnabled {
		atomic.StoreInt64(&t.lastRead, time.Now().UnixNano())
	}
	sf, ok := frame.(*http2.SettingsFrame)
	if !ok {
		t.Close() // this kicks off resetTransport, so must be last before return
		return
	}
// ....

After debugging, I’ve found that in that line frame, err := t.framer.fr.ReadFrame() alert is received as error, but not used and just the transport is closed, without any more info. Is that on purpose? If not, I am willing to contribute to the project and fix it.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 3
  • Comments: 23 (13 by maintainers)

Most upvoted comments

None of us are working on this actively and there is little chance that someone might pick this up this quarter. So. please go ahead and take a shot at it. If you get stuck somewhere, feel free to reach out to us on this thread.

Hey folks; we use mTLS quite heavily in our organization so we’ve run into this issue quite a bit as of late. Namely, instead of getting the TLS alert code, we just get connection closed before server preface received as the error message; including with and without using WithBlock(). We’re using v1.43.x.

It seems like the last piece after #4311 is to propagate the error further to ClientConn and/or LB policy.

Is anyone working on this already? If not, I could take a stab at it - though I admit it may take me a while to get used to the guts of the transport/conn code 😄

I can confirm that v1.51.0 the issue is resolved for us as well. Thank you so much!

@anitgandhi @srimaln91 I will take another look at this issue and will summarize what still needs to be done based on the current state of affairs and will report back soon. Thanks.