1
0
Fork 0

Use central TLS config creation

master
Philip O'Toole 2 years ago
parent d8cf1ec2e9
commit c8231596ac

@ -3,10 +3,8 @@ package main
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io"
"io/ioutil"
"log"
"net"
"os"
@ -27,6 +25,7 @@ import (
"github.com/rqlite/rqlite/db"
"github.com/rqlite/rqlite/disco"
httpd "github.com/rqlite/rqlite/http"
"github.com/rqlite/rqlite/rtls"
"github.com/rqlite/rqlite/store"
"github.com/rqlite/rqlite/tcp"
)
@ -130,28 +129,10 @@ func main() {
// Register remaining status providers.
httpServ.RegisterStatus("cluster", clstr)
tlsConfig := tls.Config{InsecureSkipVerify: cfg.NoHTTPVerify}
if cfg.X509CACert != "" {
asn1Data, err := ioutil.ReadFile(cfg.X509CACert)
if err != nil {
log.Fatalf("ioutil.ReadFile failed: %s", err.Error())
}
tlsConfig.RootCAs = x509.NewCertPool()
ok := tlsConfig.RootCAs.AppendCertsFromPEM(asn1Data)
if !ok {
log.Fatalf("failed to parse root CA certificate(s) in %q", cfg.X509CACert)
}
}
if cfg.X509CertClient != "" {
asn1Data, err := ioutil.ReadFile(cfg.X509CertClient)
if err != nil {
log.Fatalf("ioutil.ReadFile failed: %s", err.Error())
}
tlsConfig.Certificates = make([]tls.Certificate, 1)
tlsConfig.Certificates[0], err = tls.X509KeyPair(asn1Data, []byte(cfg.X509KeyClient))
if err != nil {
log.Fatalf("tls.X509KeyPair failed: %s", err.Error())
}
tlsConfig, err := rtls.CreateClientConfig(cfg.X509CertClient, cfg.X509KeyClient, cfg.X509CACert,
cfg.NoHTTPVerify, cfg.TLS1011)
if err != nil {
log.Fatalf("failed to create TLS client config for cluster: %s", err.Error())
}
// Create the cluster!
@ -159,7 +140,7 @@ func main() {
if err != nil {
log.Fatalf("failed to get nodes %s", err.Error())
}
if err := createCluster(cfg, &tlsConfig, len(nodes) > 0, str, httpServ, credStr); err != nil {
if err := createCluster(cfg, tlsConfig, len(nodes) > 0, str, httpServ, credStr); err != nil {
log.Fatalf("clustering failure: %s", err.Error())
}

@ -5,7 +5,6 @@ package http
import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
"expvar"
@ -27,6 +26,7 @@ import (
"github.com/rqlite/rqlite/command"
"github.com/rqlite/rqlite/command/encoding"
"github.com/rqlite/rqlite/queue"
"github.com/rqlite/rqlite/rtls"
"github.com/rqlite/rqlite/store"
)
@ -274,6 +274,7 @@ type Service struct {
CertFile string // Path to server's own x509 certificate.
KeyFile string // Path to server's own x509 private key.
TLS1011 bool // Whether older, deprecated TLS should be supported.
ClientVerify bool // Whether client certificates should be verified.
DefaultQueueCap int
DefaultQueueBatchSz int
@ -324,7 +325,7 @@ func (s *Service) Start() error {
return err
}
} else {
config, err := createTLSConfig(s.CertFile, s.KeyFile, s.ClientCACertFile, s.TLS1011)
config, err := rtls.CreateServerConfig(s.CertFile, s.KeyFile, s.ClientCACertFile, s.ClientVerify, s.TLS1011)
if err != nil {
return err
}
@ -1737,39 +1738,6 @@ func requestQueries(r *http.Request) ([]*command.Statement, error) {
return ParseRequest(b)
}
// createTLSConfig returns a TLS config from the given cert and key.
func createTLSConfig(certFile, keyFile, clientCACertFile string, tls1011 bool) (*tls.Config, error) {
var err error
var minTLS = uint16(tls.VersionTLS12)
if tls1011 {
minTLS = tls.VersionTLS10
}
config := &tls.Config{
NextProtos: []string{"h2", "http/1.1"},
MinVersion: minTLS,
}
config.Certificates = make([]tls.Certificate, 1)
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return nil, err
}
if clientCACertFile != "" {
asn1Data, err := ioutil.ReadFile(clientCACertFile)
if err != nil {
return nil, err
}
config.ClientCAs = x509.NewCertPool()
ok := config.ClientCAs.AppendCertsFromPEM(asn1Data)
if !ok {
return nil, fmt.Errorf("failed to load CA certificate(s) for client verification in %q", clientCACertFile)
}
config.ClientAuth = tls.RequireAndVerifyClientCert
}
return config, nil
}
// queryParam returns whether the given query param is present.
func queryParam(req *http.Request, param string) (bool, error) {
err := req.ParseForm()

@ -8,6 +8,7 @@ import (
"testing"
"time"
"github.com/rqlite/rqlite/rtls"
"github.com/rqlite/rqlite/testdata/x509"
)
@ -149,7 +150,7 @@ func mustNewEchoServerTLS() (*echoServer, string, string) {
cert := x509.CertFile("")
key := x509.KeyFile("")
tlsConfig, err := createTLSConfig(cert, key, "")
tlsConfig, err := rtls.CreateServerConfig(cert, key, "", true, false)
if err != nil {
panic("failed to create TLS config")
}

@ -2,18 +2,18 @@ package tcp
import (
"crypto/tls"
"crypto/x509"
"errors"
"expvar"
"fmt"
"io"
"io/ioutil"
"log"
"net"
"os"
"strconv"
"sync"
"time"
"github.com/rqlite/rqlite/rtls"
)
const (
@ -115,13 +115,13 @@ 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) (*Mux, error) {
func NewTLSMux(ln net.Listener, adv net.Addr, cert, key, caCert string, insecure bool) (*Mux, error) {
mux, err := NewMux(ln, adv)
if err != nil {
return nil, err
}
mux.tlsConfig, err = createTLSConfig(cert, key, caCert)
mux.tlsConfig, err = rtls.CreateServerConfig(cert, key, caCert, insecure, false)
if err != nil {
return nil, err
}
@ -270,40 +270,3 @@ func (ln *listener) Close() error { return nil }
// Addr always returns nil
func (ln *listener) Addr() net.Addr { return nil }
// newTLSListener returns a net listener which encrypts the traffic using TLS.
func newTLSListener(ln net.Listener, certFile, keyFile, caCertFile string) (net.Listener, error) {
config, err := createTLSConfig(certFile, keyFile, caCertFile)
if err != nil {
return nil, err
}
return tls.NewListener(ln, config), nil
}
// createTLSConfig returns a TLS config from the given cert, key and optionally
// Certificate Authority cert for verifying client certificates.
func createTLSConfig(certFile, keyFile, caCertFile string) (*tls.Config, error) {
var err error
config := &tls.Config{}
config.Certificates = make([]tls.Certificate, 1)
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return nil, err
}
if caCertFile != "" {
asn1Data, err := ioutil.ReadFile(caCertFile)
if err != nil {
return nil, err
}
config.ClientCAs = x509.NewCertPool()
ok := config.ClientCAs.AppendCertsFromPEM(asn1Data)
if !ok {
return nil, fmt.Errorf("failed to parse Client Auth CA certificate in %q", caCertFile)
}
config.ClientAuth = tls.RequireAndVerifyClientCert
}
return config, nil
}

@ -177,7 +177,7 @@ func TestTLSMux(t *testing.T) {
key := x509.KeyFile("")
defer os.Remove(key)
mux, err := NewTLSMux(tcpListener, nil, cert, key, "")
mux, err := NewTLSMux(tcpListener, nil, cert, key, "", true)
if err != nil {
t.Fatalf("failed to create mux: %s", err.Error())
}
@ -200,7 +200,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", "")
_, err := NewTLSMux(tcpListener, nil, "xxxx", "yyyy", "", true)
if err == nil {
t.Fatalf("created mux unexpectedly with bad resources")
}

Loading…
Cancel
Save