|
|
@@ -31,6 +31,7 @@ import (
|
|
|
"github.com/coreos/etcd/pkg/cors"
|
|
|
"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"
|
|
|
|
|
|
@@ -183,6 +184,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"`
|
|
|
+
|
|
|
// debug
|
|
|
|
|
|
Debug bool `json:"debug"`
|
|
|
@@ -426,6 +432,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 := checkBindURLs(cfg.LPUrls); err != nil {
|
|
|
@@ -562,31 +586,41 @@ 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(filepath.Join(cfg.Dir, "fixtures", "client"), chosts)
|
|
|
- return err
|
|
|
- } else if cfg.ClientAutoTLS {
|
|
|
+ if !cfg.ClientAutoTLS {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ if !cfg.ClientTLSInfo.Empty() {
|
|
|
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(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(filepath.Join(cfg.Dir, "fixtures", "peer"), phosts)
|
|
|
- return err
|
|
|
- } else if cfg.PeerAutoTLS {
|
|
|
+ if !cfg.PeerAutoTLS {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ if !cfg.PeerTLSInfo.Empty() {
|
|
|
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(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,
|