1
0
Fork 0

Default to mutual TLS off for node-to-node

master
Philip O'Toole 2 years ago
parent 27839b53f7
commit 3e84139290

@ -106,7 +106,7 @@ func mustNewTLSMux() (net.Listener, *tcp.Mux) {
key := x509.KeyFile("")
defer os.Remove(key)
mux, err := tcp.NewTLSMux(ln, nil, cert, key, "", true)
mux, err := tcp.NewTLSMux(ln, nil, cert, key, "", true, false)
if err != nil {
panic(fmt.Sprintf("failed to create TLS mux: %s", err))
}

@ -79,6 +79,10 @@ type Config struct {
// NoNodeVerify disables checking other nodes' Node X509 certs for validity.
NoNodeVerify bool
// NodeVerifyClient indicates whether a node should verify client certificates from
// other nodes.
NodeVerifyClient bool
// NodeID is the Raft ID for the node.
NodeID string
@ -380,6 +384,7 @@ func ParseFlags(name, desc string, build *BuildInfo) (*Config, error) {
flag.StringVar(&config.NodeX509Cert, "node-cert", "", "Path to X.509 certificate for node-to-node mutual authentication and encryption")
flag.StringVar(&config.NodeX509Key, "node-key", "", "Path to X.509 private key for node-to-node mutual authentication and encryption")
flag.BoolVar(&config.NoNodeVerify, "node-no-verify", false, "Skip verification of any node-node certificate")
flag.BoolVar(&config.NodeVerifyClient, "node-verify-client", false, "Enable mutual TLS for node-to-node communication")
flag.StringVar(&config.AuthFile, "auth", "", "Path to authentication and authorization file. If not set, not enabled")
flag.StringVar(&config.RaftAddr, RaftAddrFlag, "localhost:4002", "Raft communication bind address")
flag.StringVar(&config.RaftAdv, RaftAdvAddrFlag, "", "Advertised Raft communication address. If not set, same as Raft bind")

@ -283,17 +283,19 @@ func startNodeMux(cfg *Config, ln net.Listener) (*tcp.Mux, error) {
var mux *tcp.Mux
if cfg.NodeX509Cert != "" {
var b strings.Builder
b.WriteString(fmt.Sprintf("enabling node-to-node encryption with cert: %s, key: %s", cfg.NodeX509Cert, cfg.NodeX509Key))
b.WriteString(fmt.Sprintf("enabling node-to-node encryption with cert: %s, key: %s",
cfg.NodeX509Cert, cfg.NodeX509Key))
if cfg.NodeX509CACert != "" {
b.WriteString(fmt.Sprintf(", CA cert %s", cfg.NodeX509CACert))
}
if cfg.NoNodeVerify {
b.WriteString(", client verification disabled")
if cfg.NodeVerifyClient {
b.WriteString(", mutual TLS disabled")
} else {
b.WriteString(", client verification enabled")
b.WriteString(", mutual TLS enabled")
}
log.Println(b.String())
mux, err = tcp.NewTLSMux(ln, adv, cfg.NodeX509Cert, cfg.NodeX509Key, cfg.NodeX509CACert, cfg.NoNodeVerify)
mux, err = tcp.NewTLSMux(ln, adv, cfg.NodeX509Cert, cfg.NodeX509Key, cfg.NodeX509CACert,
cfg.NoNodeVerify, cfg.NodeVerifyClient)
} else {
mux, err = tcp.NewMux(ln, adv)
}

@ -339,9 +339,9 @@ func (s *Service) Start() error {
b.WriteString(fmt.Sprintf(", CA cert %s", s.CACertFile))
}
if s.ClientVerify {
b.WriteString(", client verification enabled")
b.WriteString(", mutual TLS enabled")
} else {
b.WriteString(", client verification disabled")
b.WriteString(", mutual disabled")
}
// print the message
s.logger.Println(b.String())

@ -6,15 +6,15 @@ import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"os"
)
// CreateClientConfig creates a TLS configuration for use by a system that does both
// client and server authentication using the same cert, key, and CA cert. If noverify
// is true, the client will not verify the server's certificate and the server will not
// verify the client's certificate. If tls1011 is true, the client will accept TLS 1.0
// or 1.1. Otherwise, it will require TLS 1.2 or higher.
func CreateConfig(certFile, keyFile, caCertFile string, noverify, tls1011 bool) (*tls.Config, error) {
// is true, the client will not verify the server's certificate. If mutual is true,
// the server will verify the client's certificate. If tls1011 is true, the client will
// accept TLS 1.0 or 1.1. Otherwise, it will require TLS 1.2 or higher.
func CreateConfig(certFile, keyFile, caCertFile string, noverify, mutual, tls1011 bool) (*tls.Config, error) {
var err error
config := createBaseTLSConfig(noverify, tls1011)
@ -44,7 +44,7 @@ func CreateConfig(certFile, keyFile, caCertFile string, noverify, tls1011 bool)
return nil, fmt.Errorf("failed to load CA certificate(s) for client verification in %q", caCertFile)
}
}
if !noverify {
if mutual {
config.ClientAuth = tls.RequireAndVerifyClientCert
}
return config, nil

@ -25,14 +25,17 @@ func Test_CreateConfig(t *testing.T) {
}
caCertFile := mustWriteTempFile(t, caCertPEM)
// create a config with no client verification
config, err := CreateConfig(certFile, keyFile, caCertFile, true, false)
// create a config with no server or client verification
config, err := CreateConfig(certFile, keyFile, caCertFile, true, false, false)
if err != nil {
t.Fatalf("failed to create config: %v", err)
}
if config.ClientAuth != tls.NoClientCert {
t.Fatalf("expected ClientAuth to be NoClientCert, got %v", config.ClientAuth)
}
if !config.InsecureSkipVerify {
t.Fatalf("expected InsecureSkipVerify to be true, got false")
}
// Check that the certificate is loaded correctly
if len(config.Certificates) != 1 {
@ -65,14 +68,29 @@ func Test_CreateConfig(t *testing.T) {
t.Fatalf("expected client CA to be %v, got %v", caCertPool, config.ClientCAs)
}
// create a config with client verification
config, err = CreateConfig(certFile, keyFile, "", false, false)
// create a config with server cert verification only
config, err = CreateConfig(certFile, keyFile, caCertFile, false, false, false)
if err != nil {
t.Fatalf("failed to create config: %v", err)
}
if config.ClientAuth != tls.NoClientCert {
t.Fatalf("expected ClientAuth to be NoClientCert, got %v", config.ClientAuth)
}
if config.InsecureSkipVerify {
t.Fatalf("expected InsecureSkipVerify to be false, got true")
}
// create a config with both server and client verification
config, err = CreateConfig(certFile, keyFile, "", false, true, false)
if err != nil {
t.Fatalf("failed to create config: %v", err)
}
if config.ClientAuth != tls.RequireAndVerifyClientCert {
t.Fatalf("expected ClientAuth to be RequireAndVerifyClientCert, got %v", config.ClientAuth)
}
if config.InsecureSkipVerify {
t.Fatalf("expected InsecureSkipVerify to be false, got true")
}
}
func Test_CreateServerConfig(t *testing.T) {

@ -694,7 +694,7 @@ func mustNewOpenTLSMux(certFile, keyPath, addr string) *tcp.Mux {
}
var mux *tcp.Mux
mux, err = tcp.NewTLSMux(ln, nil, certFile, keyPath, "", true)
mux, err = tcp.NewTLSMux(ln, nil, certFile, keyPath, "", true, false)
if err != nil {
panic(fmt.Sprintf("failed to create node-to-node mux: %s", err.Error()))
}

@ -94,14 +94,16 @@ func NewMux(ln net.Listener, adv net.Addr) (*Mux, error) {
}
// NewTLSMux returns a new instance of Mux for ln, and encrypts all traffic
// using TLS. If adv is nil, then the addr of ln is used.
func NewTLSMux(ln net.Listener, adv net.Addr, cert, key, caCert string, insecure bool) (*Mux, error) {
// using TLS. If adv is nil, then the addr of ln is used. If insecure is true,
// then the server will not verify the client's certificate. If mutual is true,
// then the server will require the client to present a trusted certificate.
func NewTLSMux(ln net.Listener, adv net.Addr, cert, key, caCert string, insecure, mutual bool) (*Mux, error) {
mux, err := NewMux(ln, adv)
if err != nil {
return nil, err
}
mux.tlsConfig, err = rtls.CreateConfig(cert, key, caCert, insecure, false)
mux.tlsConfig, err = rtls.CreateConfig(cert, key, caCert, insecure, mutual, false)
if err != nil {
return nil, fmt.Errorf("cannot create TLS config: %s", err)
}

@ -176,7 +176,7 @@ func TestTLSMux(t *testing.T) {
key := x509.KeyFile("")
defer os.Remove(key)
mux, err := NewTLSMux(tcpListener, nil, cert, key, "", true)
mux, err := NewTLSMux(tcpListener, nil, cert, key, "", true, false)
if err != nil {
t.Fatalf("failed to create mux: %s", err.Error())
}
@ -199,7 +199,7 @@ func TestTLSMux(t *testing.T) {
func TestTLSMux_Fail(t *testing.T) {
tcpListener := mustTCPListener("127.0.0.1:0")
defer tcpListener.Close()
_, err := NewTLSMux(tcpListener, nil, "xxxx", "yyyy", "", true)
_, err := NewTLSMux(tcpListener, nil, "xxxx", "yyyy", "", true, false)
if err == nil {
t.Fatalf("created mux unexpectedly with bad resources")
}

Loading…
Cancel
Save