Add client certificate CA option to authenticate with client certs
Add the ability to authenticate against multiple client CA certificates. Signed-off-by: Simon Thulbourn <simon+github@thulbourn.com>master
							parent
							
								
									d3bbb078c1
								
							
						
					
					
						commit
						c8f3800f1c
					
				|  | @ -1,9 +1,12 @@ | |||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"crypto/tls" | ||||
| 	"crypto/x509" | ||||
| 	_ "expvar" | ||||
| 	"flag" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 	_ "net/http/pprof" | ||||
| 	"os" | ||||
|  | @ -67,8 +70,40 @@ func main() { | |||
| 			ctxu.GetLogger(app).Fatalln(err) | ||||
| 		} | ||||
| 	} else { | ||||
| 		tlsConf := &tls.Config{ | ||||
| 			ClientAuth: tls.NoClientCert, | ||||
| 		} | ||||
| 
 | ||||
| 		if len(config.HTTP.TLS.ClientCAs) != 0 { | ||||
| 			pool := x509.NewCertPool() | ||||
| 
 | ||||
| 			for _, ca := range config.HTTP.TLS.ClientCAs { | ||||
| 				caPem, err := ioutil.ReadFile(ca) | ||||
| 				if err != nil { | ||||
| 					ctxu.GetLogger(app).Fatalln(err) | ||||
| 				} | ||||
| 
 | ||||
| 				if ok := pool.AppendCertsFromPEM(caPem); !ok { | ||||
| 					ctxu.GetLogger(app).Fatalln(fmt.Errorf("Could not add CA to pool")) | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			for _, subj := range pool.Subjects() { | ||||
| 				ctxu.GetLogger(app).Debugf("CA Subject: %s", string(subj)) | ||||
| 			} | ||||
| 
 | ||||
| 			tlsConf.ClientAuth = tls.RequireAndVerifyClientCert | ||||
| 			tlsConf.ClientCAs = pool | ||||
| 		} | ||||
| 
 | ||||
| 		ctxu.GetLogger(app).Infof("listening on %v, tls", config.HTTP.Addr) | ||||
| 		if err := http.ListenAndServeTLS(config.HTTP.Addr, config.HTTP.TLS.Certificate, config.HTTP.TLS.Key, handler); err != nil { | ||||
| 		server := &http.Server{ | ||||
| 			Addr:      config.HTTP.Addr, | ||||
| 			Handler:   handler, | ||||
| 			TLSConfig: tlsConf, | ||||
| 		} | ||||
| 
 | ||||
| 		if err := server.ListenAndServeTLS(config.HTTP.TLS.Certificate, config.HTTP.TLS.Key); err != nil { | ||||
| 			ctxu.GetLogger(app).Fatalln(err) | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -57,6 +57,10 @@ type Configuration struct { | |||
| 			// contain the private portion for the file specified in
 | ||||
| 			// Certificate.
 | ||||
| 			Key string `yaml:"key,omitempty"` | ||||
| 
 | ||||
| 			// Specifies the CA certs for client authentication
 | ||||
| 			// A file may contain multiple CA certificates encoded as PEM
 | ||||
| 			ClientCAs []string `yaml:"clientcas,omitempty"` | ||||
| 		} `yaml:"tls,omitempty"` | ||||
| 
 | ||||
| 		// Debug configures the http debug interface, if specified. This can
 | ||||
|  |  | |||
|  | @ -52,6 +52,27 @@ var configStruct = Configuration{ | |||
| 			}, | ||||
| 		}, | ||||
| 	}, | ||||
| 	HTTP: struct { | ||||
| 		Addr   string `yaml:"addr,omitempty"` | ||||
| 		Prefix string `yaml:"prefix,omitempty"` | ||||
| 		Secret string `yaml:"secret,omitempty"` | ||||
| 		TLS    struct { | ||||
| 			Certificate string   `yaml:"certificate,omitempty"` | ||||
| 			Key         string   `yaml:"key,omitempty"` | ||||
| 			ClientCAs   []string `yaml:"clientcas,omitempty"` | ||||
| 		} `yaml:"tls,omitempty"` | ||||
| 		Debug struct { | ||||
| 			Addr string `yaml:"addr,omitempty"` | ||||
| 		} `yaml:"debug,omitempty"` | ||||
| 	}{ | ||||
| 		TLS: struct { | ||||
| 			Certificate string   `yaml:"certificate,omitempty"` | ||||
| 			Key         string   `yaml:"key,omitempty"` | ||||
| 			ClientCAs   []string `yaml:"clientcas,omitempty"` | ||||
| 		}{ | ||||
| 			ClientCAs: []string{"/path/to/ca.pem"}, | ||||
| 		}, | ||||
| 	}, | ||||
| } | ||||
| 
 | ||||
| // configYamlV0_1 is a Version 0.1 yaml document representing configStruct
 | ||||
|  | @ -82,6 +103,9 @@ notifications: | |||
| reporting: | ||||
|   bugsnag: | ||||
|     apikey: BugsnagApiKey | ||||
| http: | ||||
|   clientcas: | ||||
|     - /path/to/ca.pem | ||||
| ` | ||||
| 
 | ||||
| // inmemoryConfigYamlV0_1 is a Version 0.1 yaml document specifying an inmemory
 | ||||
|  |  | |||
|  | @ -62,6 +62,9 @@ http: | |||
| 	tls: | ||||
| 		certificate: /path/to/x509/public | ||||
| 		key: /path/to/x509/private | ||||
|     clientcas: | ||||
|       - /path/to/ca.pem | ||||
|       - /path/to/another/ca.pem | ||||
| 	debug: | ||||
| 		addr: localhost:5001 | ||||
| notifications: | ||||
|  | @ -260,6 +263,9 @@ http: | |||
| 	tls: | ||||
| 		certificate: /path/to/x509/public | ||||
| 		key: /path/to/x509/private | ||||
|     clientcas: | ||||
|       - /path/to/ca.pem | ||||
|       - /path/to/another/ca.pem | ||||
| 	debug: | ||||
| 		addr: localhost:5001 | ||||
| ``` | ||||
|  | @ -276,6 +282,7 @@ The tls option within http is **optional** and allows you to configure SSL for t | |||
| 
 | ||||
| - certificate: **Required** - Absolute path to x509 cert file | ||||
| - key: **Required** - Absolute path to x509 private key file | ||||
| - clientcas: **Optional** - An array of absolute paths to a x509 CA file | ||||
| 
 | ||||
| ### debug | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue