consul: support the new TLS wrapper

This commit is contained in:
Armon Dadgar 2015-05-11 15:15:36 -07:00
parent 1f984dfea8
commit 9642384429
4 changed files with 34 additions and 32 deletions

View file

@ -1,11 +1,9 @@
package consul
import (
"crypto/tls"
"fmt"
"log"
"math/rand"
"net"
"os"
"path/filepath"
"strconv"
@ -14,7 +12,6 @@ import (
"time"
"github.com/hashicorp/consul/consul/structs"
"github.com/hashicorp/consul/tlsutil"
"github.com/hashicorp/serf/serf"
)
@ -93,18 +90,12 @@ func NewClient(config *Config) (*Client, error) {
config.LogOutput = os.Stderr
}
// Create the tlsConfig
var tlsConfig *tls.Config
var err error
if tlsConfig, err = config.tlsConfig().OutgoingTLSConfig(); err != nil {
// Create the tls Wrapper
tlsWrap, err := config.tlsConfig().OutgoingTLSWrapper()
if err != nil {
return nil, err
}
// Define a TLS wrapper
tlsWrap := func(c net.Conn) (net.Conn, error) {
return tlsutil.WrapTLSClient(c, tlsConfig)
}
// Create a logger
logger := log.New(config.LogOutput, "", log.LstdFlags)

View file

@ -56,6 +56,9 @@ type Config struct {
// Node name is the name we use to advertise. Defaults to hostname.
NodeName string
// Domain is the DNS domain for the records. Defaults to "consul."
Domain string
// RaftConfig is the configuration used for Raft in the local DC
RaftConfig *raft.Config
@ -100,6 +103,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
@ -267,13 +278,15 @@ func DefaultConfig() *Config {
func (c *Config) tlsConfig() *tlsutil.Config {
tlsConf := &tlsutil.Config{
VerifyIncoming: c.VerifyIncoming,
VerifyOutgoing: c.VerifyOutgoing,
CAFile: c.CAFile,
CertFile: c.CertFile,
KeyFile: c.KeyFile,
NodeName: c.NodeName,
ServerName: c.ServerName}
VerifyIncoming: c.VerifyIncoming,
VerifyOutgoing: c.VerifyOutgoing,
VerifyServerHostname: c.VerifyServerHostname,
CAFile: c.CAFile,
CertFile: c.CertFile,
KeyFile: c.KeyFile,
NodeName: c.NodeName,
ServerName: c.ServerName,
Domain: c.Domain,
}
return tlsConf
}

View file

@ -135,7 +135,7 @@ type ConnPool struct {
pool map[string]*Conn
// TLS wrapper
tlsWrap tlsutil.Wrapper
tlsWrap tlsutil.DCWrapper
// Used to indicate the pool is shutdown
shutdown bool
@ -147,7 +147,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.DCWrapper) *ConnPool {
pool := &ConnPool{
logOutput: logOutput,
maxTime: maxTime,
@ -227,7 +227,7 @@ func (p *ConnPool) getNewConn(dc string, addr net.Addr, version int) (*Conn, err
}
// Wrap the connection in a TLS client
tlsConn, err := p.tlsWrap(conn)
tlsConn, err := p.tlsWrap(dc, conn)
if err != nil {
conn.Close()
return nil, err

View file

@ -183,18 +183,13 @@ func NewServer(config *Config) (*Server, error) {
config.LogOutput = os.Stderr
}
// Create the tlsConfig for outgoing connections
// Create the tls wrapper for outgoing connections
tlsConf := config.tlsConfig()
tlsConfig, err := tlsConf.OutgoingTLSConfig()
tlsWrap, err := tlsConf.OutgoingTLSWrapper()
if err != nil {
return nil, err
}
// Define a TLS wrapper
tlsWrap := func(c net.Conn) (net.Conn, error) {
return tlsutil.WrapTLSClient(c, tlsConfig)
}
// Get the incoming tls config
incomingTLS, err := tlsConf.IncomingTLSConfig()
if err != nil {
@ -416,7 +411,7 @@ func (s *Server) setupRaft() error {
}
// setupRPC is used to setup the RPC listener
func (s *Server) setupRPC(tlsWrap tlsutil.Wrapper) error {
func (s *Server) setupRPC(tlsWrap tlsutil.DCWrapper) error {
// Create endpoints
s.endpoints.Status = &Status{s}
s.endpoints.Catalog = &Catalog{s}
@ -459,7 +454,10 @@ func (s *Server) setupRPC(tlsWrap tlsutil.Wrapper) error {
return fmt.Errorf("RPC advertise address is not advertisable: %v", addr)
}
s.raftLayer = NewRaftLayer(advertise, tlsWrap)
// Provide a DC specific wrapper. Raft replication is only
// ever done in the same datacenter, so we can provide it as a constant.
wrapper := tlsutil.SpecificDC(s.config.Datacenter, tlsWrap)
s.raftLayer = NewRaftLayer(advertise, wrapper)
return nil
}