diff --git a/internal/ingress/controller/controller.go b/internal/ingress/controller/controller.go index f0892e0dc9..92786af9a2 100644 --- a/internal/ingress/controller/controller.go +++ b/internal/ingress/controller/controller.go @@ -858,9 +858,11 @@ func (n *NGINXController) createServers(data []*extensions.Ingress, // initialize default server and root location servers[defServerName] = &ingress.Server{ - Hostname: defServerName, - SSLCertificate: defaultPemFileName, - SSLPemChecksum: defaultPemSHA, + Hostname: defServerName, + SSLCert: ingress.SSLCert{ + PemFileName: defaultPemFileName, + PemSHA: defaultPemSHA, + }, Locations: []*ingress.Location{ { Path: rootLocation, @@ -989,7 +991,7 @@ func (n *NGINXController) createServers(data []*extensions.Ingress, } // only add a certificate if the server does not have one previously configured - if servers[host].SSLCertificate != "" { + if servers[host].SSLCert.PemFileName != "" { continue } @@ -1002,8 +1004,8 @@ func (n *NGINXController) createServers(data []*extensions.Ingress, if tlsSecretName == "" { glog.V(3).Infof("Host %q is listed in the TLS section but secretName is empty. Using default certificate.", host) - servers[host].SSLCertificate = defaultPemFileName - servers[host].SSLPemChecksum = defaultPemSHA + servers[host].SSLCert.PemFileName = defaultPemFileName + servers[host].SSLCert.PemSHA = defaultPemSHA continue } @@ -1027,10 +1029,7 @@ func (n *NGINXController) createServers(data []*extensions.Ingress, } } - servers[host].SSLCertificate = cert.PemFileName - servers[host].SSLFullChainCertificate = cert.FullChainPemFileName - servers[host].SSLPemChecksum = cert.PemSHA - servers[host].SSLExpireTime = cert.ExpireTime + servers[host].SSLCert = *cert if cert.ExpireTime.Before(time.Now().Add(240 * time.Hour)) { glog.Warningf("SSL certificate for server %q is about to expire (%v)", cert.ExpireTime) diff --git a/internal/ingress/controller/metrics.go b/internal/ingress/controller/metrics.go index d6d842fc44..dae8f9a449 100644 --- a/internal/ingress/controller/metrics.go +++ b/internal/ingress/controller/metrics.go @@ -114,7 +114,7 @@ func ConfigSuccessTime() { func setSSLExpireTime(servers []*ingress.Server) { for _, s := range servers { if s.Hostname != defServerName { - sslExpireTime.WithLabelValues(s.Hostname).Set(float64(s.SSLExpireTime.Unix())) + sslExpireTime.WithLabelValues(s.Hostname).Set(float64(s.SSLCert.ExpireTime.Unix())) } } } diff --git a/internal/ingress/types.go b/internal/ingress/types.go index 693b48846d..e265df3734 100644 --- a/internal/ingress/types.go +++ b/internal/ingress/types.go @@ -17,8 +17,6 @@ limitations under the License. package ingress import ( - "time" - apiv1 "k8s.io/api/core/v1" extensions "k8s.io/api/extensions/v1beta1" "k8s.io/apimachinery/pkg/util/intstr" @@ -143,18 +141,8 @@ type Server struct { // SSLPassthrough indicates if the TLS termination is realized in // the server or in the remote endpoint SSLPassthrough bool `json:"sslPassthrough"` - // SSLCertificate path to the SSL certificate on disk - SSLCertificate string `json:"sslCertificate"` - // SSLFullChainCertificate path to the SSL certificate on disk - // This certificate contains the full chain (ca + intermediates + cert) - SSLFullChainCertificate string `json:"sslFullChainCertificate"` - // SSLExpireTime has the expire date of this certificate - SSLExpireTime time.Time `json:"sslExpireTime"` - // SSLPemChecksum returns the checksum of the certificate file on disk. - // There is no restriction in the hash generator. This checksum can be - // used to determine if the secret changed without the use of file - // system notifications - SSLPemChecksum string `json:"sslPemChecksum"` + // SSLCert describes the certificate that will be used on the server + SSLCert SSLCert `json:"sslCert"` // Locations list of URIs configured in the server. Locations []*Location `json:"locations,omitempty"` // Alias return the alias of the server name diff --git a/internal/ingress/types_equals.go b/internal/ingress/types_equals.go index 462a69736e..4c4aac2c8d 100644 --- a/internal/ingress/types_equals.go +++ b/internal/ingress/types_equals.go @@ -263,16 +263,7 @@ func (s1 *Server) Equal(s2 *Server) bool { if s1.SSLPassthrough != s2.SSLPassthrough { return false } - if s1.SSLCertificate != s2.SSLCertificate { - return false - } - if s1.SSLFullChainCertificate != s2.SSLFullChainCertificate { - return false - } - if !s1.SSLExpireTime.Equal(s2.SSLExpireTime) { - return false - } - if s1.SSLPemChecksum != s2.SSLPemChecksum { + if !(&s1.SSLCert).Equal(&s2.SSLCert) { return false } if s1.Alias != s2.Alias { @@ -494,7 +485,7 @@ func (l4b1 *L4Backend) Equal(l4b2 *L4Backend) bool { return true } -// Equal tests for equality between two L4Backend types +// Equal tests for equality between two SSLCert types func (s1 *SSLCert) Equal(s2 *SSLCert) bool { if s1 == s2 { return true @@ -511,6 +502,9 @@ func (s1 *SSLCert) Equal(s2 *SSLCert) bool { if !s1.ExpireTime.Equal(s2.ExpireTime) { return false } + if s1.FullChainPemFileName != s2.FullChainPemFileName { + return false + } for _, cn1 := range s1.CN { found := false diff --git a/rootfs/etc/nginx/template/nginx.tmpl b/rootfs/etc/nginx/template/nginx.tmpl index 451d6c4891..ed3409570d 100644 --- a/rootfs/etc/nginx/template/nginx.tmpl +++ b/rootfs/etc/nginx/template/nginx.tmpl @@ -725,7 +725,7 @@ stream { {{/* Listen on {{ $all.ListenPorts.SSLProxy }} because port {{ $all.ListenPorts.HTTPS }} is used in the TLS sni server */}} {{/* This listener must always have proxy_protocol enabled, because the SNI listener forwards on source IP info in it. */}} - {{ if not (empty $server.SSLCertificate) }} + {{ if not (empty $server.SSLCert.PemFileName) }} {{ range $address := $all.Cfg.BindAddressIpv4 }} listen {{ $address }}:{{ if $all.IsSSLPassthroughEnabled }}{{ $all.ListenPorts.SSLProxy }} proxy_protocol {{ else }}{{ $all.ListenPorts.HTTPS }}{{ if $all.Cfg.UseProxyProtocol }} proxy_protocol{{ end }}{{ end }} {{ if eq $server.Hostname "_"}} default_server {{ if $all.Cfg.ReusePort }}reuseport{{ end }} backlog={{ $all.BacklogSize }}{{end}} ssl {{ if $all.Cfg.UseHTTP2 }}http2{{ end }}; {{ else }} @@ -733,17 +733,17 @@ stream { {{ end }} {{ if $all.IsIPV6Enabled }} {{ range $address := $all.Cfg.BindAddressIpv6 }} - {{ if not (empty $server.SSLCertificate) }}listen {{ $address }}:{{ if $all.IsSSLPassthroughEnabled }}{{ $all.ListenPorts.SSLProxy }} proxy_protocol{{ else }}{{ $all.ListenPorts.HTTPS }}{{ if $all.Cfg.UseProxyProtocol }} proxy_protocol{{ end }}{{ end }}{{ end }} {{ if eq $server.Hostname "_"}} default_server {{ if $all.Cfg.ReusePort }}reuseport{{ end }} backlog={{ $all.BacklogSize }}{{end}} ssl {{ if $all.Cfg.UseHTTP2 }}http2{{ end }}; + {{ if not (empty $server.SSLCert.PemFileName) }}listen {{ $address }}:{{ if $all.IsSSLPassthroughEnabled }}{{ $all.ListenPorts.SSLProxy }} proxy_protocol{{ else }}{{ $all.ListenPorts.HTTPS }}{{ if $all.Cfg.UseProxyProtocol }} proxy_protocol{{ end }}{{ end }}{{ end }} {{ if eq $server.Hostname "_"}} default_server {{ if $all.Cfg.ReusePort }}reuseport{{ end }} backlog={{ $all.BacklogSize }}{{end}} ssl {{ if $all.Cfg.UseHTTP2 }}http2{{ end }}; {{ else }} - {{ if not (empty $server.SSLCertificate) }}listen [::]:{{ if $all.IsSSLPassthroughEnabled }}{{ $all.ListenPorts.SSLProxy }} proxy_protocol{{ else }}{{ $all.ListenPorts.HTTPS }}{{ if $all.Cfg.UseProxyProtocol }} proxy_protocol{{ end }}{{ end }}{{ end }} {{ if eq $server.Hostname "_"}} default_server {{ if $all.Cfg.ReusePort }}reuseport{{ end }} backlog={{ $all.BacklogSize }}{{end}} ssl {{ if $all.Cfg.UseHTTP2 }}http2{{ end }}; + {{ if not (empty $server.SSLCert.PemFileName) }}listen [::]:{{ if $all.IsSSLPassthroughEnabled }}{{ $all.ListenPorts.SSLProxy }} proxy_protocol{{ else }}{{ $all.ListenPorts.HTTPS }}{{ if $all.Cfg.UseProxyProtocol }} proxy_protocol{{ end }}{{ end }}{{ end }} {{ if eq $server.Hostname "_"}} default_server {{ if $all.Cfg.ReusePort }}reuseport{{ end }} backlog={{ $all.BacklogSize }}{{end}} ssl {{ if $all.Cfg.UseHTTP2 }}http2{{ end }}; {{ end }} {{ end }} {{/* comment PEM sha is required to detect changes in the generated configuration and force a reload */}} - # PEM sha: {{ $server.SSLPemChecksum }} - ssl_certificate {{ $server.SSLCertificate }}; - ssl_certificate_key {{ $server.SSLCertificate }}; - {{ if not (empty $server.SSLFullChainCertificate)}} - ssl_trusted_certificate {{ $server.SSLFullChainCertificate }}; + # PEM sha: {{ $server.SSLCert.PemSHA }} + ssl_certificate {{ $server.SSLCert.PemFileName }}; + ssl_certificate_key {{ $server.SSLCert.PemFileName }}; + {{ if not (empty $server.SSLCert.FullChainPemFileName)}} + ssl_trusted_certificate {{ $server.SSLCert.FullChainPemFileName }}; ssl_stapling on; ssl_stapling_verify on; {{ end }} @@ -912,7 +912,7 @@ stream { } {{ end }} - {{ if (and (not (empty $server.SSLCertificate)) $all.Cfg.HSTS) }} + {{ if (and (not (empty $server.SSLCert.PemFileName)) $all.Cfg.HSTS) }} if ($scheme = https) { more_set_headers "Strict-Transport-Security: max-age={{ $all.Cfg.HSTSMaxAge }}{{ if $all.Cfg.HSTSIncludeSubdomains }}; includeSubDomains{{ end }}{{ if $all.Cfg.HSTSPreload }}; preload{{ end }}"; } @@ -932,7 +932,7 @@ stream { set $proxy_upstream_name "{{ buildUpstreamName $server.Hostname $all.Backends $location $all.DynamicConfigurationEnabled }}"; {{/* redirect to HTTPS can be achieved forcing the redirect or having a SSL Certificate configured for the server */}} - {{ if (or $location.Rewrite.ForceSSLRedirect (and (not (empty $server.SSLCertificate)) $location.Rewrite.SSLRedirect)) }} + {{ if (or $location.Rewrite.ForceSSLRedirect (and (not (empty $server.SSLCert.PemFileName)) $location.Rewrite.SSLRedirect)) }} {{ if not (isLocationInLocationList $location $all.Cfg.NoTLSRedirectLocations) }} # enforce ssl on server side if ($redirect_to_https) {