diff --git a/config.example.yaml b/config.example.yaml index ffb89bdc80..cdefaef61a 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -31,7 +31,8 @@ updater: notifier: # HTTP endpoint that will receive notifications with POST requests. endpoint: - # Path to certificates to call the endpoint securely with TLS and client certificate auth. + # Server name and path to certificates to call the endpoint securely with TLS and client certificate auth. + servername: cafile: keyfile: certfile: diff --git a/config/config.go b/config/config.go index f944d50b0d..5c0859940e 100644 --- a/config/config.go +++ b/config/config.go @@ -1,5 +1,3 @@ -package config - // Copyright 2015 clair authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,6 +12,8 @@ package config // See the License for the specific language governing permissions and // limitations under the License. +package config + import ( "io/ioutil" "os" @@ -44,8 +44,11 @@ type UpdaterConfig struct { // NotifierConfig is the configuration for the Notifier service. type NotifierConfig struct { - Endpoint string - CertFile, KeyFile, CAFile string + Endpoint string + ServerName string + CertFile string + KeyFile string + CAFile string } // APIConfig is the configuration for the API service. diff --git a/notifier/notifier.go b/notifier/notifier.go index fbf38c176f..d432e301c2 100644 --- a/notifier/notifier.go +++ b/notifier/notifier.go @@ -18,7 +18,10 @@ package notifier import ( "bytes" + "crypto/tls" + "crypto/x509" "encoding/json" + "io/ioutil" "net/http" "net/url" "time" @@ -30,7 +33,6 @@ import ( "github.com/coreos/clair/database" "github.com/coreos/clair/health" "github.com/coreos/clair/utils" - httputils "github.com/coreos/clair/utils/http" ) var log = capnslog.NewPackageLogger("github.com/coreos/clair", "notifier") @@ -70,7 +72,7 @@ func New(config *config.NotifierConfig) *Notifier { } // Initialize TLS. - tlsConfig, err := httputils.LoadTLSClientConfig(config.CertFile, config.KeyFile, config.CAFile) + tlsConfig, err := loadTLSClientConfig(config) if err != nil { log.Fatalf("could not initialize client cert authentification: %s\n", err) } @@ -203,3 +205,37 @@ func (n *Notifier) Healthcheck() health.Status { queueSize, err := database.CountNotificationsToSend() return health.Status{IsEssential: false, IsHealthy: err == nil, Details: struct{ QueueSize int }{QueueSize: queueSize}} } + +// loadTLSClientConfig initializes a *tls.Config using the given notifier +// configuration. +// +// If no certificates are given, (nil, nil) is returned. +// The CA certificate is optional and falls back to the system default. +func loadTLSClientConfig(cfg *config.NotifierConfig) (*tls.Config, error) { + if cfg.CertFile == "" || cfg.KeyFile == "" { + return nil, nil + } + + cert, err := tls.LoadX509KeyPair(cfg.CertFile, cfg.KeyFile) + if err != nil { + return nil, err + } + + var caCertPool *x509.CertPool + if cfg.CAFile != "" { + caCert, err := ioutil.ReadFile(cfg.CAFile) + if err != nil { + return nil, err + } + caCertPool = x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + } + + tlsConfig := &tls.Config{ + ServerName: cfg.ServerName, + Certificates: []tls.Certificate{cert}, + RootCAs: caCertPool, + } + + return tlsConfig, nil +} diff --git a/utils/http/http.go b/utils/http/http.go index 1b1c0f8d43..b06c94ac2b 100644 --- a/utils/http/http.go +++ b/utils/http/http.go @@ -31,39 +31,6 @@ import ( // MaxPostSize is the maximum number of bytes that ParseHTTPBody reads from an http.Request.Body. const MaxBodySize int64 = 1048576 -// LoadTLSClientConfig initializes a *tls.Config using the given certificates and private key, that -// can be used to communicate with a server using client certificate authentificate. -// -// If no certificates are given, a nil *tls.Config is returned. -// The CA certificate is optionnal, the system defaults are used if not provided. -func LoadTLSClientConfig(certFile, keyFile, caFile string) (*tls.Config, error) { - if len(certFile) == 0 || len(keyFile) == 0 { - return nil, nil - } - - cert, err := tls.LoadX509KeyPair(certFile, keyFile) - if err != nil { - return nil, err - } - - var caCertPool *x509.CertPool - if len(caFile) > 0 { - caCert, err := ioutil.ReadFile(caFile) - if err != nil { - return nil, err - } - caCertPool = x509.NewCertPool() - caCertPool.AppendCertsFromPEM(caCert) - } - - tlsConfig := &tls.Config{ - Certificates: []tls.Certificate{cert}, - RootCAs: caCertPool, - } - - return tlsConfig, nil -} - // LoadTLSClientConfigForServer initializes a *tls.Config using the given CA, that can be used to // configure http server to do client certificate authentification. //