Merge pull request #2502 from kelseyhightower/trusted-ca-and-client-auth

etcd: server SSL and client cert auth configuration is more explicit
This commit is contained in:
Kelsey Hightower 2015-03-14 09:40:53 -07:00
commit 9c74f98b97
3 changed files with 74 additions and 36 deletions

View File

@ -172,9 +172,13 @@ func NewConfig() *config {
fs.StringVar(&cfg.clientTLSInfo.CAFile, "ca-file", "", "Path to the client server TLS CA file.")
fs.StringVar(&cfg.clientTLSInfo.CertFile, "cert-file", "", "Path to the client server TLS cert file.")
fs.StringVar(&cfg.clientTLSInfo.KeyFile, "key-file", "", "Path to the client server TLS key file.")
fs.BoolVar(&cfg.clientTLSInfo.ClientCertAuth, "client-cert-auth", false, "Enable client cert authentication.")
fs.StringVar(&cfg.clientTLSInfo.TrustedCAFile, "trusted-ca-file", "", "Path to the client server TLS trusted CA key file.")
fs.StringVar(&cfg.peerTLSInfo.CAFile, "peer-ca-file", "", "Path to the peer server TLS CA file.")
fs.StringVar(&cfg.peerTLSInfo.CertFile, "peer-cert-file", "", "Path to the peer server TLS cert file.")
fs.StringVar(&cfg.peerTLSInfo.KeyFile, "peer-key-file", "", "Path to the peer server TLS key file.")
fs.BoolVar(&cfg.peerTLSInfo.ClientCertAuth, "peer-client-cert-auth", false, "Enable peer client cert authentication.")
fs.StringVar(&cfg.peerTLSInfo.TrustedCAFile, "peer-trusted-ca-file", "", "Path to the peer server TLS trusted CA file.")
// unsafe
fs.BoolVar(&cfg.forceNewCluster, "force-new-cluster", false, "Force to create a new one member cluster")

View File

@ -81,12 +81,20 @@ security flags:
path to the client server TLS cert file.
--key-file ''
path to the client server TLS key file.
--client-cert-auth 'false'
enable client cert authentication.
--trusted-ca-file ''
path to the client server TLS trusted CA key file.
--peer-ca-file ''
path to the peer server TLS CA file.
--peer-cert-file ''
path to the peer server TLS cert file.
--peer-key-file ''
path to the peer server TLS key file.
--peer-client-cert-auth 'false'
enable peer client cert authentication.
--peer-trusted-ca-file ''
path to the peer server TLS trusted CA file.
unsafe flags:

View File

@ -66,9 +66,11 @@ func NewTransport(info TLSInfo) (*http.Transport, error) {
}
type TLSInfo struct {
CertFile string
KeyFile string
CAFile string
CertFile string
KeyFile string
CAFile string
TrustedCAFile string
ClientCertAuth bool
// parseFunc exists to simplify testing. Typically, parseFunc
// should be left nil. In that case, tls.X509KeyPair will be used.
@ -115,29 +117,47 @@ func (info TLSInfo) baseConfig() (*tls.Config, error) {
return cfg, nil
}
// ServerConfig generates a tls.Config object for use by an HTTP server
// cafiles returns a list of CA file paths.
func (info TLSInfo) cafiles() []string {
cs := make([]string, 0)
if info.CAFile != "" {
cs = append(cs, info.CAFile)
}
if info.TrustedCAFile != "" {
cs = append(cs, info.TrustedCAFile)
}
return cs
}
// ServerConfig generates a tls.Config object for use by an HTTP server.
func (info TLSInfo) ServerConfig() (*tls.Config, error) {
cfg, err := info.baseConfig()
if err != nil {
return nil, err
}
if info.CAFile != "" {
cfg.ClientAuth = tls.NoClientCert
if info.CAFile != "" || info.ClientCertAuth {
cfg.ClientAuth = tls.RequireAndVerifyClientCert
cp, err := newCertPool(info.CAFile)
}
CAFiles := info.cafiles()
if len(CAFiles) > 0 {
cp, err := newCertPool(CAFiles)
if err != nil {
return nil, err
}
cfg.ClientCAs = cp
} else {
cfg.ClientAuth = tls.NoClientCert
}
return cfg, nil
}
// ClientConfig generates a tls.Config object for use by an HTTP client
func (info TLSInfo) ClientConfig() (cfg *tls.Config, err error) {
// ClientConfig generates a tls.Config object for use by an HTTP client.
func (info TLSInfo) ClientConfig() (*tls.Config, error) {
var cfg *tls.Config
var err error
if !info.Empty() {
cfg, err = info.baseConfig()
if err != nil {
@ -147,34 +167,40 @@ func (info TLSInfo) ClientConfig() (cfg *tls.Config, err error) {
cfg = &tls.Config{}
}
if info.CAFile != "" {
cfg.RootCAs, err = newCertPool(info.CAFile)
if err != nil {
return
}
}
return
}
// newCertPool creates x509 certPool with provided CA file
func newCertPool(CAFile string) (*x509.CertPool, error) {
certPool := x509.NewCertPool()
pemByte, err := ioutil.ReadFile(CAFile)
if err != nil {
return nil, err
}
for {
var block *pem.Block
block, pemByte = pem.Decode(pemByte)
if block == nil {
return certPool, nil
}
cert, err := x509.ParseCertificate(block.Bytes)
CAFiles := info.cafiles()
if len(CAFiles) > 0 {
cfg.RootCAs, err = newCertPool(CAFiles)
if err != nil {
return nil, err
}
certPool.AddCert(cert)
}
return cfg, nil
}
// newCertPool creates x509 certPool with provided CA files.
func newCertPool(CAFiles []string) (*x509.CertPool, error) {
certPool := x509.NewCertPool()
for _, CAFile := range CAFiles {
pemByte, err := ioutil.ReadFile(CAFile)
if err != nil {
return nil, err
}
for {
var block *pem.Block
block, pemByte = pem.Decode(pemByte)
if block == nil {
break
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, err
}
certPool.AddCert(cert)
}
}
return certPool, nil
}