tlsutil: Adding wrappers for hostname verification
This commit is contained in:
parent
c8fb9ab369
commit
1f984dfea8
|
@ -9,9 +9,14 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// Wrapper is a function that is used to wrap a non-TLS connection
|
||||
// and returns an appropriate TLS connection or error
|
||||
type Wrapper func(net.Conn) (net.Conn, error)
|
||||
// DCWrapper is a function that is used to wrap a non-TLS connection
|
||||
// and returns an appropriate TLS connection or error. This takes
|
||||
// a datacenter as an argument.
|
||||
type DCWrapper func(dc string, conn net.Conn) (net.Conn, error)
|
||||
|
||||
// Wrapper is a variant of DCWrapper, where the DC is provided as
|
||||
// a constant value. This is usually done by currying DCWrapper.
|
||||
type Wrapper func(conn net.Conn) (net.Conn, error)
|
||||
|
||||
// Config used to create tls.Config
|
||||
type Config struct {
|
||||
|
@ -26,6 +31,14 @@ type Config struct {
|
|||
// server nodes.
|
||||
VerifyOutgoing bool
|
||||
|
||||
// VerifyServerHostname is used to enable hostname verification of servers. This
|
||||
// ensures that the certificate presented is valid for server.<datacenter>.<domain>.
|
||||
// This prevents a compromised client from being restarted as a server, and then
|
||||
// intercepting request traffic as well as being added as a raft peer. This should be
|
||||
// enabled by default with VerifyOutgoing, but for legacy reasons we cannot break
|
||||
// existing clients.
|
||||
VerifyServerHostname bool
|
||||
|
||||
// CAFile is a path to a certificate authority file. This is used with VerifyIncoming
|
||||
// or VerifyOutgoing to verify the TLS connection.
|
||||
CAFile string
|
||||
|
@ -44,6 +57,9 @@ type Config struct {
|
|||
// ServerName is used with the TLS certificate to ensure the name we
|
||||
// provide matches the certificate
|
||||
ServerName string
|
||||
|
||||
// Domain is the Consul TLD being used. Defaults to "consul."
|
||||
Domain string
|
||||
}
|
||||
|
||||
// AppendCA opens and parses the CA file and adds the certificates to
|
||||
|
@ -94,6 +110,11 @@ func (c *Config) OutgoingTLSConfig() (*tls.Config, error) {
|
|||
tlsConfig.ServerName = c.ServerName
|
||||
tlsConfig.InsecureSkipVerify = false
|
||||
}
|
||||
if c.VerifyServerHostname {
|
||||
// ServerName is filled in dynamically based on the target DC
|
||||
tlsConfig.ServerName = "VerifyServerHostname"
|
||||
tlsConfig.InsecureSkipVerify = false
|
||||
}
|
||||
|
||||
// Ensure we have a CA if VerifyOutgoing is set
|
||||
if c.VerifyOutgoing && c.CAFile == "" {
|
||||
|
@ -117,6 +138,48 @@ func (c *Config) OutgoingTLSConfig() (*tls.Config, error) {
|
|||
return tlsConfig, nil
|
||||
}
|
||||
|
||||
// OutgoingTLSWrapper returns a a DCWrapper 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() (DCWrapper, error) {
|
||||
// Get the TLS config
|
||||
tlsConfig, err := c.OutgoingTLSConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check if TLS is not enabled
|
||||
if tlsConfig == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Generate the wrapper based on hostname verification
|
||||
if c.VerifyServerHostname {
|
||||
wrapper := func(dc string, conn net.Conn) (net.Conn, error) {
|
||||
conf := *tlsConfig
|
||||
conf.ServerName = "server." + dc + "." + c.Domain
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// SpecificDC is used to invoke a static datacenter
|
||||
// and turns a DCWrapper into a Wrapper type.
|
||||
func SpecificDC(dc string, tlsWrap DCWrapper) Wrapper {
|
||||
if tlsWrap == nil {
|
||||
return nil
|
||||
}
|
||||
return func(conn net.Conn) (net.Conn, error) {
|
||||
return tlsWrap(dc, conn)
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap a net.Conn into a client tls connection, performing any
|
||||
// additional verification as needed.
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue