1
0
Fork 0

Consolidate TLS config creation

master
Philip O'Toole 2 years ago
parent ec939ec383
commit d8982d044e

@ -100,7 +100,7 @@ func main() {
}
// Create cluster service now, so nodes will be able to learn information about each other.
clstr, err := clusterService(cfg, mux.Listen(cluster.MuxClusterHeader), str, str, credStr)
clstrServ, err := clusterService(cfg, mux.Listen(cluster.MuxClusterHeader), str, str, credStr)
if err != nil {
log.Fatalf("failed to create cluster service: %s", err.Error())
}
@ -111,18 +111,9 @@ func main() {
// We want to start the HTTP server as soon as possible, so the node is responsive and external
// systems can see that it's running. We still have to open the Store though, so the node won't
// be able to do much until that happens however.
var dialerTLSConfig *tls.Config
if cfg.NodeX509Cert != "" || cfg.NodeX509CACert != "" {
dialerTLSConfig, err = rtls.CreateClientConfig(cfg.NodeX509Cert, cfg.NodeX509Key,
cfg.NodeX509CACert, cfg.NoNodeVerify, cfg.TLS1011)
if err != nil {
log.Fatalf("failed to create TLS config for cluster dialer: %s", err.Error())
}
}
clstrDialer := tcp.NewDialer(cluster.MuxClusterHeader, dialerTLSConfig)
clstrClient := cluster.NewClient(clstrDialer, cfg.ClusterConnectTimeout)
if err := clstrClient.SetLocal(cfg.RaftAdv, clstr); err != nil {
log.Fatalf("failed to set cluster client local parameters: %s", err.Error())
clstrClient, err := createClusterClient(cfg, clstrServ)
if err != nil {
log.Fatalf("failed to create cluster client: %s", err.Error())
}
httpServ, err := startHTTPService(cfg, str, clstrClient, credStr)
if err != nil {
@ -136,23 +127,14 @@ func main() {
}
// Register remaining status providers.
httpServ.RegisterStatus("cluster", clstr)
var clstrTLSConfig *tls.Config
if cfg.HTTPx509Cert != "" || cfg.HTTPx509CACert != "" {
clstrTLSConfig, err = rtls.CreateClientConfig(cfg.HTTPx509Cert, cfg.HTTPx509Key, cfg.HTTPx509CACert,
cfg.NoHTTPVerify, cfg.TLS1011)
if err != nil {
log.Fatalf("failed to create TLS client config for cluster: %s", err.Error())
}
}
httpServ.RegisterStatus("cluster", clstrServ)
// Create the cluster!
nodes, err := str.Nodes()
if err != nil {
log.Fatalf("failed to get nodes %s", err.Error())
}
if err := createCluster(cfg, clstrTLSConfig, len(nodes) > 0, str, httpServ, credStr); err != nil {
if err := createCluster(cfg, len(nodes) > 0, str, httpServ, credStr); err != nil {
log.Fatalf("clustering failure: %s", err.Error())
}
@ -179,7 +161,7 @@ func main() {
if err := str.Close(true); err != nil {
log.Printf("failed to close store: %s", err.Error())
}
clstr.Close()
clstrServ.Close()
muxLn.Close()
stopProfile()
log.Println("rqlite server stopped")
@ -266,15 +248,10 @@ func createDiscoService(cfg *Config, str *store.Store) (*disco.Service, error) {
}
func startHTTPService(cfg *Config, str *store.Store, cltr *cluster.Client, credStr *auth.CredentialsStore) (*httpd.Service, error) {
// Create HTTP server and load authentication information if required.
var s *httpd.Service
if credStr != nil {
s = httpd.New(cfg.HTTPAddr, str, cltr, credStr)
} else {
s = httpd.New(cfg.HTTPAddr, str, cltr, nil)
}
// Create HTTP server and load authentication information.
s := httpd.New(cfg.HTTPAddr, str, cltr, credStr)
s.ClientCACertFile = cfg.HTTPx509CACert
s.CACertFile = cfg.HTTPx509CACert
s.CertFile = cfg.HTTPx509Cert
s.KeyFile = cfg.HTTPx509Key
s.TLS1011 = cfg.TLS1011
@ -346,8 +323,36 @@ func clusterService(cfg *Config, tn cluster.Transport, db cluster.Database, mgr
return c, nil
}
func createCluster(cfg *Config, tlsConfig *tls.Config, hasPeers bool, str *store.Store,
func createClusterClient(cfg *Config, clstr *cluster.Service) (*cluster.Client, error) {
var dialerTLSConfig *tls.Config
var err error
if cfg.NodeX509Cert != "" || cfg.NodeX509CACert != "" {
dialerTLSConfig, err = rtls.CreateClientConfig(cfg.NodeX509Cert, cfg.NodeX509Key,
cfg.NodeX509CACert, cfg.NoNodeVerify, cfg.TLS1011)
if err != nil {
log.Fatalf("failed to create TLS config for cluster dialer: %s", err.Error())
}
}
clstrDialer := tcp.NewDialer(cluster.MuxClusterHeader, dialerTLSConfig)
clstrClient := cluster.NewClient(clstrDialer, cfg.ClusterConnectTimeout)
if err := clstrClient.SetLocal(cfg.RaftAdv, clstr); err != nil {
log.Fatalf("failed to set cluster client local parameters: %s", err.Error())
}
return clstrClient, nil
}
func createCluster(cfg *Config, hasPeers bool, str *store.Store,
httpServ *httpd.Service, credStr *auth.CredentialsStore) error {
var tlsConfig *tls.Config
var err error
if cfg.HTTPx509Cert != "" || cfg.HTTPx509CACert != "" {
tlsConfig, err = rtls.CreateClientConfig(cfg.HTTPx509Cert, cfg.HTTPx509Key, cfg.HTTPx509CACert,
cfg.NoHTTPVerify, cfg.TLS1011)
if err != nil {
return fmt.Errorf("failed to create TLS client config for cluster: %s", err.Error())
}
}
joins := cfg.JoinAddresses()
if joins == nil && cfg.DiscoMode == "" && !hasPeers {
// Brand new node, told to bootstrap itself. So do it.

@ -270,11 +270,12 @@ type Service struct {
statusMu sync.RWMutex
statuses map[string]StatusReporter
ClientCACertFile string // Path to x509 CA certificate used to verify client certificates.
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.
ClientNoVerify bool // Whether client certificates should not be verified.
CACertFile string // Path to x509 CA certificate used to verify certificates.
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.
ClientNoVerify bool // Whether client certificates should not be verified.
tlsConfig *tls.Config
DefaultQueueCap int
DefaultQueueBatchSz int
@ -325,11 +326,11 @@ func (s *Service) Start() error {
return err
}
} else {
config, err := rtls.CreateServerConfig(s.CertFile, s.KeyFile, s.ClientCACertFile, s.ClientNoVerify, s.TLS1011)
s.tlsConfig, err = rtls.CreateServerConfig(s.CertFile, s.KeyFile, s.CACertFile, s.ClientNoVerify, s.TLS1011)
if err != nil {
return err
}
ln, err = tls.Listen("tcp", s.addr, config)
ln, err = tls.Listen("tcp", s.addr, s.tlsConfig)
if err != nil {
return err
}
@ -951,6 +952,7 @@ func (s *Service) handleStatus(w http.ResponseWriter, r *http.Request) {
"auth": prettyEnabled(s.credentialStore != nil),
"cluster": clusterStatus,
"queue": queueStats,
"tls": s.tlsStats(),
}
nodeStatus := map[string]interface{}{
@ -1689,6 +1691,21 @@ func (s *Service) addBuildVersion(w http.ResponseWriter) {
w.Header().Add(VersionHTTPHeader, version)
}
// tlsStats returns the TLS stats for the service.
func (s *Service) tlsStats() map[string]interface{} {
m := map[string]interface{}{
"enabled": prettyEnabled(s.tlsConfig != nil),
}
if s.tlsConfig != nil {
m["client_auth"] = s.tlsConfig.ClientAuth.String()
m["cert_file"] = s.CertFile
m["key_file"] = s.KeyFile
m["ca_file"] = s.CACertFile
m["next_protos"] = s.tlsConfig.NextProtos
}
return m
}
// writeResponse writes the given response to the given writer.
func (s *Service) writeResponse(w http.ResponseWriter, r *http.Request, j Responser) {
var b []byte

@ -41,15 +41,18 @@ 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 {
config.ClientAuth = tls.RequireAndVerifyClientCert
}
return config, nil
}
// CreateClientConfig creates a new tls.Config for use by a client. The certFile and keyFile
// parameters are the paths to the client's certificate and key files, which will be used to
// authenticate the client to the server. The caCertFile parameter is the path to the CA
// certificate file, which the client will use to verify any certificate presented by the
// server . If noverify is true, the client will not verify the server's certificate. If
// tls1011 is true, the client will accept TLS 1.0 or 1.1. Otherwise, it will require TLS 1.2
// authenticate the client to the server if mutual TLS is active. The caCertFile parameter
// is the path to the CA certificate file, which the client will use to verify any certificate
// presented by the server. If noverify is true, the client will not verify the server'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 CreateClientConfig(certFile, keyFile, caCertFile string, noverify, tls1011 bool) (*tls.Config, error) {
var err error
@ -86,7 +89,7 @@ func CreateClientConfig(certFile, keyFile, caCertFile string, noverify, tls1011
func CreateServerConfig(certFile, keyFile, caCertFile string, noverify, tls1011 bool) (*tls.Config, error) {
var err error
config := createBaseTLSConfig(noverify, tls1011)
config := createBaseTLSConfig(false, tls1011)
config.Certificates = make([]tls.Certificate, 1)
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
@ -102,6 +105,8 @@ func CreateServerConfig(certFile, keyFile, caCertFile string, noverify, tls1011
if !ok {
return nil, fmt.Errorf("failed to load CA certificate(s) for client verification in %q", caCertFile)
}
}
if !noverify {
config.ClientAuth = tls.RequireAndVerifyClientCert
}
return config, nil

Loading…
Cancel
Save