From d9cf04355292f98ba4f971c032d9de2b76ce6523 Mon Sep 17 00:00:00 2001 From: Giancarlo Rubio Date: Mon, 12 Jun 2017 14:45:08 +0200 Subject: [PATCH] Instrument nginx to expose metric "ssl certficate expiration time " Add a console warning message 10 days before the certificate expire --- core/pkg/ingress/controller/controller.go | 8 +++++++ core/pkg/ingress/controller/metrics.go | 28 ++++++++++++++++++++--- core/pkg/ingress/sort_ingress.go | 3 +++ core/pkg/ingress/types.go | 3 +++ core/pkg/net/ssl/ssl.go | 2 ++ 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/core/pkg/ingress/controller/controller.go b/core/pkg/ingress/controller/controller.go index cfa672dfc6..7f2b8a36bc 100644 --- a/core/pkg/ingress/controller/controller.go +++ b/core/pkg/ingress/controller/controller.go @@ -380,6 +380,7 @@ func (ic *GenericController) syncIngress(key interface{}) error { upstreams, servers := ic.getBackendServers() var passUpstreams []*ingress.SSLPassthroughBackend + for _, server := range servers { if !server.SSLPassthrough { continue @@ -416,6 +417,7 @@ func (ic *GenericController) syncIngress(key interface{}) error { glog.Infof("ingress backend successfully reloaded...") incReloadCount() + setSSLExpireTime(servers) return nil } @@ -1008,6 +1010,12 @@ func (ic *GenericController) createServers(data []interface{}, if isHostValid(host, cert) { servers[host].SSLCertificate = cert.PemFileName servers[host].SSLPemChecksum = cert.PemSHA + servers[host].SSLExpireTime = cert.ExpireTime + + 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) + } + } else { glog.Warningf("ssl certificate %v does not contain a common name for host %v", key, host) } diff --git a/core/pkg/ingress/controller/metrics.go b/core/pkg/ingress/controller/metrics.go index de3acbd20b..cc16a1a3e2 100644 --- a/core/pkg/ingress/controller/metrics.go +++ b/core/pkg/ingress/controller/metrics.go @@ -18,17 +18,22 @@ package controller import ( "github.com/prometheus/client_golang/prometheus" + "k8s.io/ingress/core/pkg/ingress" ) const ( - ns = "ingress_controller" - operation = "count" - reloadLabel = "reloads" + ns = "ingress_controller" + operation = "count" + reloadLabel = "reloads" + sslLabelExpire = "ssl_expire_time_seconds" + sslLabelHost = "host" ) func init() { prometheus.MustRegister(reloadOperation) prometheus.MustRegister(reloadOperationErrors) + prometheus.MustRegister(sslExpireTime) + } var ( @@ -48,6 +53,15 @@ var ( }, []string{operation}, ) + sslExpireTime = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: ns, + Name: sslLabelExpire, + Help: "Number of seconds since 1970 to the SSL Certificate expire. An example to check if this " + + "certificate will expire in 10 days is: \"ingress_controller_ssl_expire_time_seconds < (time() + (10 * 24 * 3600))\"", + }, + []string{sslLabelHost}, + ) ) func incReloadCount() { @@ -57,3 +71,11 @@ func incReloadCount() { func incReloadErrorCount() { reloadOperationErrors.WithLabelValues(reloadLabel).Inc() } + +func setSSLExpireTime(servers []*ingress.Server) { + + for _, s := range servers { + sslExpireTime.WithLabelValues(s.Hostname).Set(float64(s.SSLExpireTime.Unix())) + } + +} diff --git a/core/pkg/ingress/sort_ingress.go b/core/pkg/ingress/sort_ingress.go index 5498468444..a777683a11 100644 --- a/core/pkg/ingress/sort_ingress.go +++ b/core/pkg/ingress/sort_ingress.go @@ -19,6 +19,7 @@ package ingress import ( meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" + "time" ) // BackendByNameServers sorts upstreams by name @@ -79,6 +80,8 @@ type SSLCert struct { PemSHA string `json:"pemSha"` // CN contains all the common names defined in the SSL certificate CN []string `json:"cn"` + // ExpiresTime contains the expiration of this SSL certificate in timestamp format + ExpireTime time.Time `json:"expires"` } // GetObjectKind implements the ObjectKind interface as a noop diff --git a/core/pkg/ingress/types.go b/core/pkg/ingress/types.go index f0f75c8757..10aa86416b 100644 --- a/core/pkg/ingress/types.go +++ b/core/pkg/ingress/types.go @@ -33,6 +33,7 @@ import ( "k8s.io/ingress/core/pkg/ingress/defaults" "k8s.io/ingress/core/pkg/ingress/resolver" "k8s.io/ingress/core/pkg/ingress/store" + "time" ) var ( @@ -203,6 +204,8 @@ type Server struct { SSLPassthrough bool `json:"sslPassthrough"` // SSLCertificate path to the SSL certificate on disk SSLCertificate string `json:"sslCertificate"` + // 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 checksim can be // used to determine if the secret changed without the use of file diff --git a/core/pkg/net/ssl/ssl.go b/core/pkg/net/ssl/ssl.go index 70ed504340..0b2ad5bbb5 100644 --- a/core/pkg/net/ssl/ssl.go +++ b/core/pkg/net/ssl/ssl.go @@ -131,6 +131,7 @@ func AddOrUpdateCertAndKey(name string, cert, key, ca []byte) (*ingress.SSLCert, PemFileName: pemFileName, PemSHA: PemSHA1(pemFileName), CN: cn, + ExpireTime: pemCert.NotAfter, }, nil } @@ -138,6 +139,7 @@ func AddOrUpdateCertAndKey(name string, cert, key, ca []byte) (*ingress.SSLCert, PemFileName: pemFileName, PemSHA: PemSHA1(pemFileName), CN: cn, + ExpireTime: pemCert.NotAfter, }, nil }