Set minimum TLS protocol version to TLSv1.2, set PreferServerCipherSuites

Some environments are subject to strict rules about the permitted TLS
protocol verion and available ciphers. Setting TLSv1.2 as the minimum
version ensures we do not use weaker protocols. We've opted against
making this configurable given the age of TLSv1.2 and the increasing
push to deprecate TLSv1.1 and older.

The PreferServerCipherSuites setting is also commonly flagged by SSL
quality scanning tools. Since Go provides a relatively modern set of
default ciphers by default, defaulting this to true is unlikely to
make much practical difference.

Signed-off-by: Steven Danna <steve@chef.io>
This commit is contained in:
Steven Danna 2019-01-26 17:17:50 +00:00
parent 5ae094206b
commit 59f8b02d47
No known key found for this signature in database
GPG key ID: 94DFB46E861A7DAE

View file

@ -116,13 +116,19 @@ func serve(cmd *cobra.Command, args []string) error {
var grpcOptions []grpc.ServerOption var grpcOptions []grpc.ServerOption
if c.GRPC.TLSCert != "" { if c.GRPC.TLSCert != "" {
if c.GRPC.TLSClientCA != "" {
// Parse certificates from certificate file and key file for server. // Parse certificates from certificate file and key file for server.
cert, err := tls.LoadX509KeyPair(c.GRPC.TLSCert, c.GRPC.TLSKey) cert, err := tls.LoadX509KeyPair(c.GRPC.TLSCert, c.GRPC.TLSKey)
if err != nil { if err != nil {
return fmt.Errorf("invalid config: error parsing gRPC certificate file: %v", err) return fmt.Errorf("invalid config: error parsing gRPC certificate file: %v", err)
} }
tlsConfig := tls.Config{
Certificates: []tls.Certificate{cert},
MinVersion: tls.VersionTLS12,
PreferServerCipherSuites: true,
}
if c.GRPC.TLSClientCA != "" {
// Parse certificates from client CA file to a new CertPool. // Parse certificates from client CA file to a new CertPool.
cPool := x509.NewCertPool() cPool := x509.NewCertPool()
clientCert, err := ioutil.ReadFile(c.GRPC.TLSClientCA) clientCert, err := ioutil.ReadFile(c.GRPC.TLSClientCA)
@ -133,23 +139,17 @@ func serve(cmd *cobra.Command, args []string) error {
return errors.New("invalid config: failed to parse client CA") return errors.New("invalid config: failed to parse client CA")
} }
tlsConfig := tls.Config{ tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
Certificates: []tls.Certificate{cert}, tlsConfig.ClientCAs = cPool
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: cPool, // Only add metrics if client auth is enabled
}
grpcOptions = append(grpcOptions, grpcOptions = append(grpcOptions,
grpc.Creds(credentials.NewTLS(&tlsConfig)),
grpc.StreamInterceptor(grpcMetrics.StreamServerInterceptor()), grpc.StreamInterceptor(grpcMetrics.StreamServerInterceptor()),
grpc.UnaryInterceptor(grpcMetrics.UnaryServerInterceptor()), grpc.UnaryInterceptor(grpcMetrics.UnaryServerInterceptor()),
) )
} else {
opt, err := credentials.NewServerTLSFromFile(c.GRPC.TLSCert, c.GRPC.TLSKey)
if err != nil {
return fmt.Errorf("invalid config: load grpc certs: %v", err)
}
grpcOptions = append(grpcOptions, grpc.Creds(opt))
} }
grpcOptions = append(grpcOptions, grpc.Creds(credentials.NewTLS(&tlsConfig)))
} }
s, err := c.Storage.Config.Open(logger) s, err := c.Storage.Config.Open(logger)
@ -275,9 +275,18 @@ func serve(cmd *cobra.Command, args []string) error {
}() }()
} }
if c.Web.HTTPS != "" { if c.Web.HTTPS != "" {
httpsSrv := &http.Server{
Addr: c.Web.HTTPS,
Handler: serv,
TLSConfig: &tls.Config{
PreferServerCipherSuites: true,
MinVersion: tls.VersionTLS12,
},
}
logger.Infof("listening (https) on %s", c.Web.HTTPS) logger.Infof("listening (https) on %s", c.Web.HTTPS)
go func() { go func() {
err := http.ListenAndServeTLS(c.Web.HTTPS, c.Web.TLSCert, c.Web.TLSKey, serv) err = httpsSrv.ListenAndServeTLS(c.Web.TLSCert, c.Web.TLSKey)
errc <- fmt.Errorf("listening on %s failed: %v", c.Web.HTTPS, err) errc <- fmt.Errorf("listening on %s failed: %v", c.Web.HTTPS, err)
}() }()
} }