Merge pull request #661 from rithujohn191/gRPC-client-auth
cmd/dex: add option for gRPC client auth CA.
This commit is contained in:
		| @@ -15,6 +15,8 @@ grpc: | ||||
|   # Server certs. If TLS credentials aren't provided dex will generate self-signed ones. | ||||
|   tlsCert: /etc/dex/grpc.crt | ||||
|   tlsKey: /etc/dex/grpc.key | ||||
|   # Client auth CA. | ||||
|   tlsClientCA: /etc/dex/client.crt | ||||
| ``` | ||||
|  | ||||
| ## Generating clients | ||||
|   | ||||
| @@ -88,9 +88,10 @@ type Web struct { | ||||
| // GRPC is the config for the gRPC API. | ||||
| type GRPC struct { | ||||
| 	// The port to listen on. | ||||
| 	Addr    string `yaml:"addr"` | ||||
| 	TLSCert string `yaml:"tlsCert"` | ||||
| 	TLSKey  string `yaml:"tlsKey"` | ||||
| 	Addr        string `yaml:"addr"` | ||||
| 	TLSCert     string `yaml:"tlsCert"` | ||||
| 	TLSKey      string `yaml:"tlsKey"` | ||||
| 	TLSClientCA string `yaml:"tlsClientCA"` | ||||
| } | ||||
|  | ||||
| // Storage holds app's storage configuration. | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"crypto/tls" | ||||
| 	"crypto/x509" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| @@ -67,6 +69,7 @@ func serve(cmd *cobra.Command, args []string) error { | ||||
| 		{c.GRPC.TLSCert != "" && c.GRPC.Addr == "", "no address specified for gRPC"}, | ||||
| 		{c.GRPC.TLSKey != "" && c.GRPC.Addr == "", "no address specified for gRPC"}, | ||||
| 		{(c.GRPC.TLSCert == "") != (c.GRPC.TLSKey == ""), "must specific both a gRPC TLS cert and key"}, | ||||
| 		{c.GRPC.TLSCert == "" && c.GRPC.TLSClientCA != "", "cannot specify gRPC TLS client CA without a gRPC TLS cert"}, | ||||
| 	} | ||||
|  | ||||
| 	for _, check := range checks { | ||||
| @@ -77,11 +80,36 @@ func serve(cmd *cobra.Command, args []string) error { | ||||
|  | ||||
| 	var grpcOptions []grpc.ServerOption | ||||
| 	if c.GRPC.TLSCert != "" { | ||||
| 		opt, err := credentials.NewServerTLSFromFile(c.GRPC.TLSCert, c.GRPC.TLSKey) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("load grpc certs: %v", err) | ||||
| 		if c.GRPC.TLSClientCA != "" { | ||||
| 			// Parse certificates from certificate file and key file for server. | ||||
| 			cert, err := tls.LoadX509KeyPair(c.GRPC.TLSCert, c.GRPC.TLSKey) | ||||
| 			if err != nil { | ||||
| 				return fmt.Errorf("parsing certificate file: %v", err) | ||||
| 			} | ||||
|  | ||||
| 			// Parse certificates from client CA file to a new CertPool. | ||||
| 			cPool := x509.NewCertPool() | ||||
| 			clientCert, err := ioutil.ReadFile(c.GRPC.TLSClientCA) | ||||
| 			if err != nil { | ||||
| 				return fmt.Errorf("reading from client CA file: %v", err) | ||||
| 			} | ||||
| 			if cPool.AppendCertsFromPEM(clientCert) != true { | ||||
| 				return errors.New("failed to parse client CA") | ||||
| 			} | ||||
|  | ||||
| 			tlsConfig := tls.Config{ | ||||
| 				Certificates: []tls.Certificate{cert}, | ||||
| 				ClientAuth:   tls.RequireAndVerifyClientCert, | ||||
| 				ClientCAs:    cPool, | ||||
| 			} | ||||
| 			grpcOptions = append(grpcOptions, grpc.Creds(credentials.NewTLS(&tlsConfig))) | ||||
| 		} else { | ||||
| 			opt, err := credentials.NewServerTLSFromFile(c.GRPC.TLSCert, c.GRPC.TLSKey) | ||||
| 			if err != nil { | ||||
| 				return fmt.Errorf("load grpc certs: %v", err) | ||||
| 			} | ||||
| 			grpcOptions = append(grpcOptions, grpc.Creds(opt)) | ||||
| 		} | ||||
| 		grpcOptions = append(grpcOptions, grpc.Creds(opt)) | ||||
| 	} | ||||
|  | ||||
| 	connectors := make([]server.Connector, len(c.Connectors)) | ||||
|   | ||||
| @@ -22,6 +22,7 @@ web: | ||||
| #   addr: 127.0.0.1:5557 | ||||
| #   tlsCert: /etc/dex/grpc.crt | ||||
| #   tlsKey: /etc/dex/grpc.key | ||||
| #   tlsClientCA: /etc/dex/client.crt | ||||
|  | ||||
| # Instead of reading from an external storage, use this list of clients. | ||||
| # | ||||
|   | ||||
		Reference in New Issue
	
	Block a user