Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

example: add mutual TLS example #5194

Merged
merged 8 commits into from
Feb 24, 2022
Merged

Conversation

sding3
Copy link
Contributor

@sding3 sding3 commented Feb 12, 2022

This update adds an example for mutual TLS.

Fixes #5002.

RELEASE NOTES: none

this was done by copying existing certs from testdata/x509/ to
examples/data/x509 with the following shell commands:

    src=testdata/x509
    tgt=examples/data/x509

    cp ${src}/client_ca_cert.pem  ${tgt}/client_ca_cert.pem
    cp ${src}/client1_cert.pem    ${tgt}/client_cert.pem
    cp ${src}/client1_key.pem     ${tgt}/client_key.pem
for _, p := range certPaths {
caBytes, err := ioutil.ReadFile(p)
if err != nil {
return nil, fmt.Errorf("failed to read cert %s: %v", p, err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: s/%s/%q/

}
ok := certPool.AppendCertsFromPEM(caBytes)
if !ok {
return nil, fmt.Errorf("failed to parse %s", p)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. Prefer %q.

Comment on lines 59 to 60
ok := certPool.AppendCertsFromPEM(caBytes)
if !ok {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please combine these two lines.

@@ -0,0 +1,31 @@
# Mutual TLS

In mutual TLS, the client and the server authenticates each other. gRPC allows
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: s/authenticates/authenticate/

*
*/

// The client demonstrates how to supply an OAuth2 token for every RPC.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment needs updating.

Something like

// Binary client is an example client which connects to the server using mTLS.


func main() {
flag.Parse()
fmt.Printf("server starting on port %d...\n", *port)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer log.Infof instead of fmt.Printf.

flag.Parse()
fmt.Printf("server starting on port %d...\n", *port)

serverCert, err := tls.LoadX509KeyPair(data.Path("x509/server_cert.pem"), data.Path("x509/server_key.pem"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/serverCert/cert/

log.Fatalf("failed to load key pair: %s", err)
}

trustedClientCAs := x509.NewCertPool()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this line required?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope - removed.

}

trustedClientCAs := x509.NewCertPool()
trustedClientCAs, err = data.NewCertPool(data.Path("x509/client_ca_cert.pem"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/trustedClientCAs/{ca|roots}/

Comment on lines 72 to 78
type ecServer struct {
pb.UnimplementedEchoServer
}

func (s *ecServer) UnaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) {
return &pb.EchoResponse{Message: req.Message}, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer moving this to be above main.

@easwars easwars added the Type: Documentation Documentation or examples label Feb 15, 2022
@easwars easwars added this to the 1.45 Release milestone Feb 15, 2022
@easwars
Copy link
Contributor

easwars commented Feb 15, 2022

@sding3 : Thank you for the PR.

Do you happen to know what signing algorithm is used in the certificates? Starting Go 1.18, support for SHA1 signatures is being dropped. We recently changed all our certificates to use SHA256 signatures.

@easwars
Copy link
Contributor

easwars commented Feb 15, 2022

#5002 says following regarding the location of the example:

A mutual TLS example here https://github.com/grpc/grpc-go/tree/master/examples/features/authentication

And I think that sounds better than examples/features/mutual_tls as is currently implemented. Thanks.

@sding3
Copy link
Contributor Author

sding3 commented Feb 15, 2022

#5002 says following regarding the location of the example:

A mutual TLS example here https://github.com/grpc/grpc-go/tree/master/examples/features/authentication

And I think that sounds better than examples/features/mutual_tls as is currently implemented. Thanks.

Yeah, I can move them to examples/features/authentication/mutual_tls, but that implies the existing content under examples/features/authentication/ would have to be moved into a new sub-directory, examples/features/authentication/oauth2, is that okay?

@easwars
Copy link
Contributor

easwars commented Feb 15, 2022

#5002 says following regarding the location of the example:

A mutual TLS example here https://github.com/grpc/grpc-go/tree/master/examples/features/authentication

And I think that sounds better than examples/features/mutual_tls as is currently implemented. Thanks.

Yeah, I can move them to examples/features/authentication/mutual_tls, but that implies the existing content under examples/features/authentication/ would have to be moved into a new sub-directory, examples/features/authentication/oauth2, is that okay?

Sorry, I wanted to examples/features/encryption/ where we currently have directories for TLS and ALTS. And I think we can add one for mTLS.

@sding3
Copy link
Contributor Author

sding3 commented Feb 16, 2022

@sding3 : Thank you for the PR.

Do you happen to know what signing algorithm is used in the certificates? Starting Go 1.18, support for SHA1 signatures is being dropped. We recently changed all our certificates to use SHA256 signatures.

Yeah, they are signed with sha256WithRSAEncryption.

@sding3
Copy link
Contributor Author

sding3 commented Feb 16, 2022

I've made updates and ready for you to take another look.

@@ -0,0 +1,74 @@
/*
*
* Copyright 2018 gRPC authors.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops ... s/2018/2022/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in cb32098

Copy link

@tomaswarynyca tomaswarynyca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for providing the example 🚀

@easwars
Copy link
Contributor

easwars commented Feb 22, 2022

@menghanl : Do you mind taking a look (for the second review).

@easwars easwars modified the milestones: 1.45 Release, 1.46 Release Feb 22, 2022
Copy link
Contributor

@menghanl menghanl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM. Just one comment on the helper function.

// NewCertPool returns a x509.CertPool given the absolute paths of a list of
// PEM certificates, or an error if any failure is encountered when loading
// the said certificates.
func NewCertPool(certPaths ...string) (*x509.CertPool, error) {
Copy link
Contributor

@menghanl menghanl Feb 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this function belongs here. The data package is only to solve problems caused by relative paths.

I think it would be OK to do this inline in both client and server.
It would be easier to read, and it isn't a long function anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, inlined in d66ce1d

Copy link
Contributor

@menghanl menghanl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks for the PR!

@menghanl menghanl assigned easwars and unassigned sding3 Feb 24, 2022
@easwars easwars changed the title Add mutual TLS example example: add mutual TLS example Feb 24, 2022
@easwars easwars merged commit 328efcc into grpc:master Feb 24, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 24, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Example feature mutual TLS in grpc go services
4 participants