Merge pull request #83500 from deads2k/tls-config

refactor tlsConfig creation for secure serving
This commit is contained in:
Kubernetes Prow Robot 2019-10-04 21:51:56 -07:00 committed by GitHub
commit c4383c9aa1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -37,6 +37,52 @@ const (
defaultKeepAlivePeriod = 3 * time.Minute
)
// tlsConfig produces the tls.Config to serve with.
func (s *SecureServingInfo) tlsConfig(stopCh <-chan struct{}) (*tls.Config, error) {
tlsConfig := &tls.Config{
NameToCertificate: s.SNICerts,
// Can't use SSLv3 because of POODLE and BEAST
// Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher
// Can't use TLSv1.1 because of RC4 cipher usage
MinVersion: tls.VersionTLS12,
// enable HTTP2 for go's 1.7 HTTP Server
NextProtos: []string{"h2", "http/1.1"},
}
// these are static aspects of the tls.Config
if s.DisableHTTP2 {
klog.Info("Forcing use of http/1.1 only")
tlsConfig.NextProtos = []string{"http/1.1"}
}
if s.MinTLSVersion > 0 {
tlsConfig.MinVersion = s.MinTLSVersion
}
if len(s.CipherSuites) > 0 {
tlsConfig.CipherSuites = s.CipherSuites
}
if s.Cert != nil {
tlsConfig.Certificates = []tls.Certificate{*s.Cert}
}
// append all named certs. Otherwise, the go tls stack will think no SNI processing
// is necessary because there is only one cert anyway.
// Moreover, if ServerCert.CertFile/ServerCert.KeyFile are not set, the first SNI
// cert will become the default cert. That's what we expect anyway.
for _, c := range s.SNICerts {
tlsConfig.Certificates = append(tlsConfig.Certificates, *c)
}
// TODO this will become dynamic.
if s.ClientCA != nil {
// Populate PeerCertificates in requests, but don't reject connections without certificates
// This allows certificates to be validated by authenticators, while still allowing other auth types
tlsConfig.ClientAuth = tls.RequestClientCert
// Specify allowed CAs for client certificates
tlsConfig.ClientCAs = s.ClientCA
}
return tlsConfig, nil
}
// Serve runs the secure http server. It fails only if certificates cannot be loaded or the initial listen call fails.
// The actual server loop (stoppable by closing stopCh) runs in a go routine, i.e. Serve does not block.
// It returns a stoppedCh that is closed when all non-hijacked active requests have been processed.
@ -45,51 +91,16 @@ func (s *SecureServingInfo) Serve(handler http.Handler, shutdownTimeout time.Dur
return nil, fmt.Errorf("listener must not be nil")
}
tlsConfig, err := s.tlsConfig(stopCh)
if err != nil {
return nil, err
}
secureServer := &http.Server{
Addr: s.Listener.Addr().String(),
Handler: handler,
MaxHeaderBytes: 1 << 20,
TLSConfig: &tls.Config{
NameToCertificate: s.SNICerts,
// Can't use SSLv3 because of POODLE and BEAST
// Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher
// Can't use TLSv1.1 because of RC4 cipher usage
MinVersion: tls.VersionTLS12,
// enable HTTP2 for go's 1.7 HTTP Server
NextProtos: []string{"h2", "http/1.1"},
},
}
if s.DisableHTTP2 {
klog.Info("Forcing use of http/1.1 only")
secureServer.TLSConfig.NextProtos = []string{"http/1.1"}
}
if s.MinTLSVersion > 0 {
secureServer.TLSConfig.MinVersion = s.MinTLSVersion
}
if len(s.CipherSuites) > 0 {
secureServer.TLSConfig.CipherSuites = s.CipherSuites
}
if s.Cert != nil {
secureServer.TLSConfig.Certificates = []tls.Certificate{*s.Cert}
}
// append all named certs. Otherwise, the go tls stack will think no SNI processing
// is necessary because there is only one cert anyway.
// Moreover, if ServerCert.CertFile/ServerCert.KeyFile are not set, the first SNI
// cert will become the default cert. That's what we expect anyway.
for _, c := range s.SNICerts {
secureServer.TLSConfig.Certificates = append(secureServer.TLSConfig.Certificates, *c)
}
if s.ClientCA != nil {
// Populate PeerCertificates in requests, but don't reject connections without certificates
// This allows certificates to be validated by authenticators, while still allowing other auth types
secureServer.TLSConfig.ClientAuth = tls.RequestClientCert
// Specify allowed CAs for client certificates
secureServer.TLSConfig.ClientCAs = s.ClientCA
TLSConfig: tlsConfig,
}
// At least 99% of serialized resources in surveyed clusters were smaller than 256kb.