Implement config reload support for TLS

Allows reloading TLS config. This includes enabling/disabling TLS,
rotating keys/certs, enabling/disabling client verification, etc.
This commit is contained in:
Tyler Treat
2017-06-07 12:25:56 -05:00
parent 9f31d972d2
commit b70e2c2fc2
3 changed files with 40 additions and 7 deletions

View File

@@ -2,3 +2,11 @@
debug: true # enable on reload
trace: true # enable on reload
logtime: false
# Enable TLS on reload
tls {
cert_file: "../test/configs/certs/server-cert.pem"
key_file: "../test/configs/certs/server-key.pem"
ca_file: "../test/configs/certs/ca.pem"
verify: true
}

View File

@@ -3,6 +3,7 @@
package server
import (
"crypto/tls"
"errors"
"fmt"
"reflect"
@@ -41,6 +42,20 @@ func (d *debugOption) Apply(server *Server) {
server.Noticef("Reloaded: debug = %v", d.newValue)
}
// tlsOption implements the option interface for the `tls` setting.
type tlsOption struct {
newValue *tls.Config
}
// Apply the tls change.
func (t *tlsOption) Apply(server *Server) {
tlsRequired := t.newValue != nil
server.info.TLSRequired = tlsRequired
server.info.TLSVerify = tlsRequired && t.newValue.ClientAuth == tls.RequireAndVerifyClientCert
server.generateServerInfoJSON()
server.Noticef("Reloaded: tls")
}
// Reload reads the current configuration file and applies any supported
// changes. This returns an error if the server was not started with a config
// file or an option which doesn't support hot-swapping was changed.
@@ -99,6 +114,8 @@ func (s *Server) diffOptions(newOpts *Options) ([]option, error) {
diffOpts = append(diffOpts, &traceOption{newValue.(bool)})
case "debug":
diffOpts = append(diffOpts, &debugOption{newValue.(bool)})
case "tlsconfig":
diffOpts = append(diffOpts, &tlsOption{newValue.(*tls.Config)})
default:
// Bail out if attempting to reload any unsupported options.
return nil, fmt.Errorf("Config reload not supported for %s", field.Name)

View File

@@ -193,12 +193,20 @@ func TestConfigReload(t *testing.T) {
}
// Ensure config changed.
var updatedGolden *Options = &Options{}
*updatedGolden = *golden
updatedGolden.Trace = true
updatedGolden.Debug = true
if !reflect.DeepEqual(updatedGolden, server.getOpts()) {
t.Fatalf("Options are incorrect.\nexpected: %+v\ngot: %+v",
updatedGolden, server.getOpts())
updated := server.getOpts()
if !updated.Trace {
t.Fatal("Expected Trace to be true")
}
if !updated.Debug {
t.Fatal("Expected Debug to be true")
}
if updated.TLSConfig == nil {
t.Fatal("Expected TLSConfig to be non-nil")
}
if !server.info.TLSRequired {
t.Fatal("Expected TLSRequired to be true")
}
if !server.info.TLSVerify {
t.Fatal("Expected TLSVerify to be true")
}
}