From 2751cbf06d83df196c3c925c532bf99a962ab24c Mon Sep 17 00:00:00 2001 From: Henry Tran Date: Mon, 11 Jun 2018 13:42:40 -0400 Subject: [PATCH] Refactor to add SSLCert as a field in server type --- internal/ingress/controller/controller.go | 19 +++++++++---------- internal/ingress/controller/metrics.go | 2 +- internal/ingress/types.go | 16 ++-------------- internal/ingress/types_equals.go | 13 +++++-------- rootfs/etc/nginx/template/nginx.tmpl | 20 ++++++++++---------- 5 files changed, 27 insertions(+), 43 deletions(-) diff --git a/internal/ingress/controller/controller.go b/internal/ingress/controller/controller.go index b543a332b..79519e77d 100644 --- a/internal/ingress/controller/controller.go +++ b/internal/ingress/controller/controller.go @@ -868,9 +868,11 @@ func (n *NGINXController) createServers(data []*extensions.Ingress, // initialize the default server servers[defServerName] = &ingress.Server{ - Hostname: defServerName, - SSLCertificate: defaultPemFileName, - SSLPemChecksum: defaultPemSHA, + Hostname: defServerName, + SSLCert: ingress.SSLCert{ + PemFileName: defaultPemFileName, + PemSHA: defaultPemSHA, + }, Locations: []*ingress.Location{ { Path: rootLocation, @@ -1000,7 +1002,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 } @@ -1013,8 +1015,8 @@ func (n *NGINXController) createServers(data []*extensions.Ingress, if tlsSecretName == "" { glog.V(3).Infof("host %v is listed on tls section but secretName is empty. Using default cert", host) - servers[host].SSLCertificate = defaultPemFileName - servers[host].SSLPemChecksum = defaultPemSHA + servers[host].SSLCert.PemFileName = defaultPemFileName + servers[host].SSLCert.PemSHA = defaultPemSHA continue } @@ -1038,10 +1040,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 host %v is about to expire in 10 days", host) diff --git a/internal/ingress/controller/metrics.go b/internal/ingress/controller/metrics.go index d6d842fc4..dae8f9a44 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 647bebeb2..28035a963 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" @@ -140,18 +138,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 359d74a11..b7be64408 100644 --- a/internal/ingress/types_equals.go +++ b/internal/ingress/types_equals.go @@ -262,18 +262,12 @@ func (s1 *Server) Equal(s2 *Server) bool { if s1.SSLPassthrough != s2.SSLPassthrough { return false } - if s1.SSLCertificate != s2.SSLCertificate { - return false - } - if s1.SSLPemChecksum != s2.SSLPemChecksum { + if !(&s1.SSLCert).Equal(&s2.SSLCert) { return false } if !(&s1.CertificateAuth).Equal(&s2.CertificateAuth) { return false } - if s1.SSLFullChainCertificate != s2.SSLFullChainCertificate { - return false - } if s1.RedirectFromToWWW != s2.RedirectFromToWWW { return false } @@ -481,7 +475,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 @@ -498,6 +492,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 c258ab2e3..50b3dc231 100644 --- a/rootfs/etc/nginx/template/nginx.tmpl +++ b/rootfs/etc/nginx/template/nginx.tmpl @@ -717,7 +717,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 }} @@ -725,17 +725,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 }} @@ -891,7 +891,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 }}"; } @@ -919,7 +919,7 @@ stream { set $service_name "{{ $ing.Service }}"; {{/* 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) {