diff --git a/staging/src/k8s.io/apiserver/pkg/server/secure_serving.go b/staging/src/k8s.io/apiserver/pkg/server/secure_serving.go index 031f4b045ad..1d4520f4fe7 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/secure_serving.go +++ b/staging/src/k8s.io/apiserver/pkg/server/secure_serving.go @@ -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.