Merge pull request #1909 from hashicorp/region-wrapper
Making Nomad TLS configs region aware
This commit is contained in:
commit
808718523b
|
@ -166,7 +166,7 @@ var (
|
|||
// NewClient is used to create a new client from the given configuration
|
||||
func NewClient(cfg *config.Config, consulSyncer *consul.Syncer, logger *log.Logger) (*Client, error) {
|
||||
// Create the tls wrapper
|
||||
var tlsWrap tlsutil.Wrapper
|
||||
var tlsWrap tlsutil.RegionWrapper
|
||||
if cfg.TLSConfig.EnableRPC {
|
||||
tw, err := cfg.TLSConfiguration().OutgoingTLSWrapper()
|
||||
if err != nil {
|
||||
|
|
|
@ -241,7 +241,6 @@ func (c *Config) TLSConfiguration() *tlsutil.Config {
|
|||
CAFile: c.TLSConfig.CAFile,
|
||||
CertFile: c.TLSConfig.CertFile,
|
||||
KeyFile: c.TLSConfig.KeyFile,
|
||||
ServerName: c.Node.Name,
|
||||
}
|
||||
return tlsConf
|
||||
}
|
||||
|
|
|
@ -67,7 +67,6 @@ func NewHTTPServer(agent *Agent, config *Config, logOutput io.Writer) (*HTTPServ
|
|||
CAFile: config.TLSConfig.CAFile,
|
||||
CertFile: config.TLSConfig.CertFile,
|
||||
KeyFile: config.TLSConfig.KeyFile,
|
||||
ServerName: config.NodeName,
|
||||
}
|
||||
tlsConfig, err := tlsConf.IncomingTLSConfig()
|
||||
if err != nil {
|
||||
|
|
|
@ -9,6 +9,22 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// RegionSpecificWrapper is used to invoke a static Region and turns a
|
||||
// RegionWrapper into a Wrapper type.
|
||||
func RegionSpecificWrapper(region string, tlsWrap RegionWrapper) Wrapper {
|
||||
if tlsWrap == nil {
|
||||
return nil
|
||||
}
|
||||
return func(conn net.Conn) (net.Conn, error) {
|
||||
return tlsWrap(region, conn)
|
||||
}
|
||||
}
|
||||
|
||||
// RegionWrapper is a function that is used to wrap a non-TLS connection and
|
||||
// returns an appropriate TLS connection or error. This takes a Region as an
|
||||
// argument.
|
||||
type RegionWrapper func(region string, conn net.Conn) (net.Conn, error)
|
||||
|
||||
// Wrapper wraps a connection and enables TLS on it.
|
||||
type Wrapper func(conn net.Conn) (net.Conn, error)
|
||||
|
||||
|
@ -44,10 +60,6 @@ type Config struct {
|
|||
// KeyFile is used to provide a TLS key that is used for serving TLS connections.
|
||||
// Must be provided to serve TLS connections.
|
||||
KeyFile string
|
||||
|
||||
// ServerName is used with the TLS certificate to ensure the name we
|
||||
// provide matches the certificate
|
||||
ServerName string
|
||||
}
|
||||
|
||||
// AppendCA opens and parses the CA file and adds the certificates to
|
||||
|
@ -98,8 +110,8 @@ func (c *Config) OutgoingTLSConfig() (*tls.Config, error) {
|
|||
RootCAs: x509.NewCertPool(),
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
if c.ServerName != "" {
|
||||
tlsConfig.ServerName = c.ServerName
|
||||
if c.VerifyServerHostname {
|
||||
// ServerName is filled in dynamically based on the target DC
|
||||
tlsConfig.InsecureSkipVerify = false
|
||||
}
|
||||
|
||||
|
@ -128,7 +140,7 @@ func (c *Config) OutgoingTLSConfig() (*tls.Config, error) {
|
|||
// OutgoingTLSWrapper returns a a Wrapper based on the OutgoingTLS
|
||||
// configuration. If hostname verification is on, the wrapper
|
||||
// will properly generate the dynamic server name for verification.
|
||||
func (c *Config) OutgoingTLSWrapper() (Wrapper, error) {
|
||||
func (c *Config) OutgoingTLSWrapper() (RegionWrapper, error) {
|
||||
// Get the TLS config
|
||||
tlsConfig, err := c.OutgoingTLSConfig()
|
||||
if err != nil {
|
||||
|
@ -140,10 +152,21 @@ func (c *Config) OutgoingTLSWrapper() (Wrapper, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
wrapper := func(conn net.Conn) (net.Conn, error) {
|
||||
return WrapTLSClient(conn, tlsConfig)
|
||||
// Generate the wrapper based on hostname verification
|
||||
if c.VerifyServerHostname {
|
||||
wrapper := func(region string, conn net.Conn) (net.Conn, error) {
|
||||
conf := *tlsConfig
|
||||
conf.ServerName = "server." + region + ".nomad"
|
||||
return WrapTLSClient(conn, &conf)
|
||||
}
|
||||
return wrapper, nil
|
||||
} else {
|
||||
wrapper := func(dc string, c net.Conn) (net.Conn, error) {
|
||||
return WrapTLSClient(c, tlsConfig)
|
||||
}
|
||||
return wrapper, nil
|
||||
}
|
||||
return wrapper, nil
|
||||
|
||||
}
|
||||
|
||||
// Wrap a net.Conn into a client tls connection, performing any
|
||||
|
@ -203,9 +226,9 @@ func WrapTLSClient(conn net.Conn, tlsConfig *tls.Config) (net.Conn, error) {
|
|||
func (c *Config) IncomingTLSConfig() (*tls.Config, error) {
|
||||
// Create the tlsConfig
|
||||
tlsConfig := &tls.Config{
|
||||
ServerName: c.ServerName,
|
||||
ClientCAs: x509.NewCertPool(),
|
||||
ClientAuth: tls.NoClientCert,
|
||||
ServerName: "*." + region + ".nomad",
|
||||
}
|
||||
|
||||
// Parse the CA cert if any
|
||||
|
|
|
@ -278,7 +278,6 @@ func (c *Config) tlsConfig() *tlsutil.Config {
|
|||
CAFile: c.TLSConfig.CAFile,
|
||||
CertFile: c.TLSConfig.CertFile,
|
||||
KeyFile: c.TLSConfig.KeyFile,
|
||||
ServerName: c.NodeName,
|
||||
}
|
||||
return tlsConf
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ type ConnPool struct {
|
|||
limiter map[string]chan struct{}
|
||||
|
||||
// TLS wrapper
|
||||
tlsWrap tlsutil.Wrapper
|
||||
tlsWrap tlsutil.RegionWrapper
|
||||
|
||||
// Used to indicate the pool is shutdown
|
||||
shutdown bool
|
||||
|
@ -141,7 +141,7 @@ type ConnPool struct {
|
|||
// Set maxTime to 0 to disable reaping. maxStreams is used to control
|
||||
// the number of idle streams allowed.
|
||||
// If TLS settings are provided outgoing connections use TLS.
|
||||
func NewPool(logOutput io.Writer, maxTime time.Duration, maxStreams int, tlsWrap tlsutil.Wrapper) *ConnPool {
|
||||
func NewPool(logOutput io.Writer, maxTime time.Duration, maxStreams int, tlsWrap tlsutil.RegionWrapper) *ConnPool {
|
||||
pool := &ConnPool{
|
||||
logOutput: logOutput,
|
||||
maxTime: maxTime,
|
||||
|
@ -261,7 +261,7 @@ func (p *ConnPool) getNewConn(region string, addr net.Addr, version int) (*Conn,
|
|||
}
|
||||
|
||||
// Wrap the connection in a TLS client
|
||||
tlsConn, err := p.tlsWrap(conn)
|
||||
tlsConn, err := p.tlsWrap(region, conn)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
return nil, err
|
||||
|
|
|
@ -188,7 +188,7 @@ func NewServer(config *Config, consulSyncer *consul.Syncer, logger *log.Logger)
|
|||
}
|
||||
|
||||
// Configure TLS
|
||||
var tlsWrap tlsutil.Wrapper
|
||||
var tlsWrap tlsutil.RegionWrapper
|
||||
var incomingTLS *tls.Config
|
||||
if config.TLSConfig.EnableRPC {
|
||||
tlsConf := config.tlsConfig()
|
||||
|
@ -594,7 +594,7 @@ func (s *Server) setupVaultClient() error {
|
|||
}
|
||||
|
||||
// setupRPC is used to setup the RPC listener
|
||||
func (s *Server) setupRPC(tlsWrap tlsutil.Wrapper) error {
|
||||
func (s *Server) setupRPC(tlsWrap tlsutil.RegionWrapper) error {
|
||||
// Create endpoints
|
||||
s.endpoints.Status = &Status{s}
|
||||
s.endpoints.Node = &Node{srv: s}
|
||||
|
@ -640,7 +640,8 @@ func (s *Server) setupRPC(tlsWrap tlsutil.Wrapper) error {
|
|||
return fmt.Errorf("RPC advertise address is not advertisable: %v", addr)
|
||||
}
|
||||
|
||||
s.raftLayer = NewRaftLayer(s.rpcAdvertise, tlsWrap)
|
||||
wrapper := tlsutil.RegionSpecificWrapper(s.config.Region, tlsWrap)
|
||||
s.raftLayer = NewRaftLayer(s.rpcAdvertise, wrapper)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue