|
|
@@ -32,6 +32,7 @@ import (
|
|
|
"github.com/coreos/etcd/pkg/flags"
|
|
|
"github.com/coreos/etcd/pkg/netutil"
|
|
|
"github.com/coreos/etcd/pkg/srv"
|
|
|
+ "github.com/coreos/etcd/pkg/tlsutil"
|
|
|
"github.com/coreos/etcd/pkg/transport"
|
|
|
"github.com/coreos/etcd/pkg/types"
|
|
|
|
|
|
@@ -175,6 +176,11 @@ type Config struct {
|
|
|
PeerTLSInfo transport.TLSInfo
|
|
|
PeerAutoTLS bool
|
|
|
|
|
|
+ // CipherSuites is a list of supported TLS cipher suites between
|
|
|
+ // client/server and peers. If empty, Go auto-populates the list.
|
|
|
+ // Note that cipher suites are prioritized in the given order.
|
|
|
+ CipherSuites []string `json:"cipher-suites"`
|
|
|
+
|
|
|
ClusterState string `json:"initial-cluster-state"`
|
|
|
DNSCluster string `json:"discovery-srv"`
|
|
|
DNSClusterServiceName string `json:"discovery-srv-name"`
|
|
|
@@ -510,6 +516,24 @@ func (cfg *configYAML) configFromFile(path string) error {
|
|
|
return cfg.Validate()
|
|
|
}
|
|
|
|
|
|
+func updateCipherSuites(tls *transport.TLSInfo, ss []string) error {
|
|
|
+ if len(tls.CipherSuites) > 0 && len(ss) > 0 {
|
|
|
+ return fmt.Errorf("TLSInfo.CipherSuites is already specified (given %v)", ss)
|
|
|
+ }
|
|
|
+ if len(ss) > 0 {
|
|
|
+ cs := make([]uint16, len(ss))
|
|
|
+ for i, s := range ss {
|
|
|
+ var ok bool
|
|
|
+ cs[i], ok = tlsutil.GetCipherSuite(s)
|
|
|
+ if !ok {
|
|
|
+ return fmt.Errorf("unexpected TLS cipher suite %q", s)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ tls.CipherSuites = cs
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
// Validate ensures that '*embed.Config' fields are properly configured.
|
|
|
func (cfg *Config) Validate() error {
|
|
|
if err := cfg.setupLogging(); err != nil {
|
|
|
@@ -703,39 +727,49 @@ func (cfg Config) defaultClientHost() bool {
|
|
|
}
|
|
|
|
|
|
func (cfg *Config) ClientSelfCert() (err error) {
|
|
|
- if cfg.ClientAutoTLS && cfg.ClientTLSInfo.Empty() {
|
|
|
- chosts := make([]string, len(cfg.LCUrls))
|
|
|
- for i, u := range cfg.LCUrls {
|
|
|
- chosts[i] = u.Host
|
|
|
- }
|
|
|
- cfg.ClientTLSInfo, err = transport.SelfCert(cfg.logger, filepath.Join(cfg.Dir, "fixtures", "client"), chosts)
|
|
|
- return err
|
|
|
- } else if cfg.ClientAutoTLS {
|
|
|
+ if !cfg.ClientAutoTLS {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ if !cfg.ClientTLSInfo.Empty() {
|
|
|
if cfg.logger != nil {
|
|
|
cfg.logger.Warn("ignoring client auto TLS since certs given")
|
|
|
} else {
|
|
|
plog.Warningf("ignoring client auto TLS since certs given")
|
|
|
}
|
|
|
+ return nil
|
|
|
}
|
|
|
- return nil
|
|
|
+ chosts := make([]string, len(cfg.LCUrls))
|
|
|
+ for i, u := range cfg.LCUrls {
|
|
|
+ chosts[i] = u.Host
|
|
|
+ }
|
|
|
+ cfg.ClientTLSInfo, err = transport.SelfCert(cfg.logger, filepath.Join(cfg.Dir, "fixtures", "client"), chosts)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ return updateCipherSuites(&cfg.ClientTLSInfo, cfg.CipherSuites)
|
|
|
}
|
|
|
|
|
|
func (cfg *Config) PeerSelfCert() (err error) {
|
|
|
- if cfg.PeerAutoTLS && cfg.PeerTLSInfo.Empty() {
|
|
|
- phosts := make([]string, len(cfg.LPUrls))
|
|
|
- for i, u := range cfg.LPUrls {
|
|
|
- phosts[i] = u.Host
|
|
|
- }
|
|
|
- cfg.PeerTLSInfo, err = transport.SelfCert(cfg.logger, filepath.Join(cfg.Dir, "fixtures", "peer"), phosts)
|
|
|
- return err
|
|
|
- } else if cfg.PeerAutoTLS {
|
|
|
+ if !cfg.PeerAutoTLS {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ if !cfg.PeerTLSInfo.Empty() {
|
|
|
if cfg.logger != nil {
|
|
|
cfg.logger.Warn("ignoring peer auto TLS since certs given")
|
|
|
} else {
|
|
|
plog.Warningf("ignoring peer auto TLS since certs given")
|
|
|
}
|
|
|
+ return nil
|
|
|
}
|
|
|
- return nil
|
|
|
+ phosts := make([]string, len(cfg.LPUrls))
|
|
|
+ for i, u := range cfg.LPUrls {
|
|
|
+ phosts[i] = u.Host
|
|
|
+ }
|
|
|
+ cfg.PeerTLSInfo, err = transport.SelfCert(cfg.logger, filepath.Join(cfg.Dir, "fixtures", "peer"), phosts)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ return updateCipherSuites(&cfg.PeerTLSInfo, cfg.CipherSuites)
|
|
|
}
|
|
|
|
|
|
// UpdateDefaultClusterFromName updates cluster advertise URLs with, if available, default host,
|