Simplify handling of ssl certificates
This commit is contained in:
parent
26fccdc48b
commit
14a02d128c
3 changed files with 66 additions and 57 deletions
|
@ -57,11 +57,13 @@ func (ic *GenericController) syncSecret() {
|
||||||
}
|
}
|
||||||
glog.Infof("updating secret %v in the local store", key)
|
glog.Infof("updating secret %v in the local store", key)
|
||||||
ic.sslCertTracker.Update(key, cert)
|
ic.sslCertTracker.Update(key, cert)
|
||||||
|
ic.reloadRequired = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
glog.Infof("adding secret %v to the local store", key)
|
glog.Infof("adding secret %v to the local store", key)
|
||||||
ic.sslCertTracker.Add(key, cert)
|
ic.sslCertTracker.Add(key, cert)
|
||||||
|
ic.reloadRequired = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,8 +88,8 @@ func (ic *GenericController) getPemCertificate(secretName string) (*ingress.SSLC
|
||||||
|
|
||||||
var s *ingress.SSLCert
|
var s *ingress.SSLCert
|
||||||
if okcert && okkey {
|
if okcert && okkey {
|
||||||
glog.V(3).Infof("found certificate and private key, configuring %v as a TLS Secret", secretName)
|
|
||||||
s, err = ssl.AddOrUpdateCertAndKey(nsSecName, cert, key, ca)
|
s, err = ssl.AddOrUpdateCertAndKey(nsSecName, cert, key, ca)
|
||||||
|
glog.V(3).Infof("found certificate and private key, configuring %v as a TLS Secret (CN: %v)", secretName, s.CN)
|
||||||
} else if ca != nil {
|
} else if ca != nil {
|
||||||
glog.V(3).Infof("found only ca.crt, configuring %v as an Certificate Authentication secret", secretName)
|
glog.V(3).Infof("found only ca.crt, configuring %v as an Certificate Authentication secret", secretName)
|
||||||
s, err = ssl.AddCertAuth(nsSecName, ca)
|
s, err = ssl.AddCertAuth(nsSecName, ca)
|
||||||
|
|
|
@ -42,6 +42,7 @@ import (
|
||||||
"k8s.io/client-go/tools/record"
|
"k8s.io/client-go/tools/record"
|
||||||
"k8s.io/client-go/util/flowcontrol"
|
"k8s.io/client-go/util/flowcontrol"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/ingress/core/pkg/ingress"
|
"k8s.io/ingress/core/pkg/ingress"
|
||||||
"k8s.io/ingress/core/pkg/ingress/annotations/class"
|
"k8s.io/ingress/core/pkg/ingress/annotations/class"
|
||||||
"k8s.io/ingress/core/pkg/ingress/annotations/healthcheck"
|
"k8s.io/ingress/core/pkg/ingress/annotations/healthcheck"
|
||||||
|
@ -113,8 +114,8 @@ type GenericController struct {
|
||||||
// runningConfig contains the running configuration in the Backend
|
// runningConfig contains the running configuration in the Backend
|
||||||
runningConfig *ingress.Configuration
|
runningConfig *ingress.Configuration
|
||||||
|
|
||||||
// configmapChanged indicates the configmap
|
// reloadRequired indicates the configmap
|
||||||
configmapChanged bool
|
reloadRequired bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configuration contains all the settings required by an Ingress controller
|
// Configuration contains all the settings required by an Ingress controller
|
||||||
|
@ -262,7 +263,7 @@ func newIngressController(config *Configuration) *GenericController {
|
||||||
if mapKey == ic.cfg.ConfigMapName {
|
if mapKey == ic.cfg.ConfigMapName {
|
||||||
glog.V(2).Infof("adding configmap %v to backend", mapKey)
|
glog.V(2).Infof("adding configmap %v to backend", mapKey)
|
||||||
ic.cfg.Backend.SetConfig(upCmap)
|
ic.cfg.Backend.SetConfig(upCmap)
|
||||||
ic.configmapChanged = true
|
ic.reloadRequired = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
UpdateFunc: func(old, cur interface{}) {
|
UpdateFunc: func(old, cur interface{}) {
|
||||||
|
@ -272,7 +273,7 @@ func newIngressController(config *Configuration) *GenericController {
|
||||||
if mapKey == ic.cfg.ConfigMapName {
|
if mapKey == ic.cfg.ConfigMapName {
|
||||||
glog.V(2).Infof("updating configmap backend (%v)", mapKey)
|
glog.V(2).Infof("updating configmap backend (%v)", mapKey)
|
||||||
ic.cfg.Backend.SetConfig(upCmap)
|
ic.cfg.Backend.SetConfig(upCmap)
|
||||||
ic.configmapChanged = true
|
ic.reloadRequired = true
|
||||||
}
|
}
|
||||||
// updates to configuration configmaps can trigger an update
|
// updates to configuration configmaps can trigger an update
|
||||||
if mapKey == ic.cfg.ConfigMapName || mapKey == ic.cfg.TCPConfigMapName || mapKey == ic.cfg.UDPConfigMapName {
|
if mapKey == ic.cfg.ConfigMapName || mapKey == ic.cfg.TCPConfigMapName || mapKey == ic.cfg.UDPConfigMapName {
|
||||||
|
@ -419,7 +420,7 @@ func (ic *GenericController) syncIngress(key interface{}) error {
|
||||||
PassthroughBackends: passUpstreams,
|
PassthroughBackends: passUpstreams,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ic.configmapChanged && (ic.runningConfig != nil && ic.runningConfig.Equal(&pcfg)) {
|
if !ic.reloadRequired && (ic.runningConfig != nil && ic.runningConfig.Equal(&pcfg)) {
|
||||||
glog.V(3).Infof("skipping backend reload (no changes detected)")
|
glog.V(3).Infof("skipping backend reload (no changes detected)")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -433,7 +434,7 @@ func (ic *GenericController) syncIngress(key interface{}) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ic.configmapChanged = false
|
ic.reloadRequired = false
|
||||||
glog.Infof("ingress backend successfully reloaded...")
|
glog.Infof("ingress backend successfully reloaded...")
|
||||||
incReloadCount()
|
incReloadCount()
|
||||||
setSSLExpireTime(servers)
|
setSSLExpireTime(servers)
|
||||||
|
@ -1018,55 +1019,52 @@ func (ic *GenericController) createServers(data []interface{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// only add a certificate if the server does not have one previously configured
|
// only add a certificate if the server does not have one previously configured
|
||||||
// TODO: TLS without secret?
|
if len(ing.Spec.TLS) == 0 || servers[host].SSLCertificate != "" {
|
||||||
if len(ing.Spec.TLS) > 0 && servers[host].SSLCertificate == "" {
|
continue
|
||||||
tlsSecretName := ""
|
}
|
||||||
found := false
|
|
||||||
for _, tls := range ing.Spec.TLS {
|
tlsSecretName := ""
|
||||||
for _, tlsHost := range tls.Hosts {
|
found := false
|
||||||
if tlsHost == host {
|
for _, tls := range ing.Spec.TLS {
|
||||||
tlsSecretName = tls.SecretName
|
if sets.NewString(tls.Hosts...).Has(host) {
|
||||||
found = true
|
tlsSecretName = tls.SecretName
|
||||||
break
|
found = true
|
||||||
}
|
break
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// the current ing.Spec.Rules[].Host doesn't have an entry at
|
// the current ing.Spec.Rules[].Host doesn't have an entry at
|
||||||
// ing.Spec.TLS[].Hosts[], skipping to the next Rule
|
// ing.Spec.TLS[].Hosts[] skipping to the next Rule
|
||||||
if !found {
|
if !found {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Current Host listed on ing.Spec.TLS[].Hosts[]
|
if tlsSecretName == "" {
|
||||||
// but TLS[].SecretName is empty; using default cert
|
glog.Warningf("host %v is listed on tls section but secretName is empty. Using default cert", host)
|
||||||
if tlsSecretName == "" {
|
servers[host].SSLCertificate = defaultPemFileName
|
||||||
servers[host].SSLCertificate = defaultPemFileName
|
servers[host].SSLPemChecksum = defaultPemSHA
|
||||||
servers[host].SSLPemChecksum = defaultPemSHA
|
continue
|
||||||
continue
|
}
|
||||||
}
|
|
||||||
|
|
||||||
key := fmt.Sprintf("%v/%v", ing.Namespace, tlsSecretName)
|
|
||||||
bc, exists := ic.sslCertTracker.Get(key)
|
|
||||||
if exists {
|
|
||||||
cert := bc.(*ingress.SSLCert)
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
|
key := fmt.Sprintf("%v/%v", ing.Namespace, tlsSecretName)
|
||||||
|
bc, exists := ic.sslCertTracker.Get(key)
|
||||||
|
if !exists {
|
||||||
glog.Infof("ssl certificate \"%v\" does not exist in local store", key)
|
glog.Infof("ssl certificate \"%v\" does not exist in local store", key)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
cert := bc.(*ingress.SSLCert)
|
||||||
|
if !isHostValid(host, cert) {
|
||||||
|
glog.Warningf("ssl certificate %v does not contain a common name for host %v", key, host)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ import (
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/ingress/core/pkg/ingress"
|
"k8s.io/ingress/core/pkg/ingress"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -104,19 +105,27 @@ func AddOrUpdateCertAndKey(name string, cert, key, ca []byte) (*ingress.SSLCert,
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cn := []string{pemCert.Subject.CommonName}
|
cn := sets.NewString(pemCert.Subject.CommonName)
|
||||||
if len(pemCert.DNSNames) > 0 {
|
for _, dns := range pemCert.DNSNames {
|
||||||
cn = append(cn, pemCert.DNSNames...)
|
if !cn.Has(dns) {
|
||||||
|
cn.Insert(dns)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(pemCert.Extensions) > 0 {
|
if len(pemCert.Extensions) > 0 {
|
||||||
|
glog.V(3).Info("parsing ssl certificate extensions")
|
||||||
for _, ext := range getExtension(pemCert, oidExtensionSubjectAltName) {
|
for _, ext := range getExtension(pemCert, oidExtensionSubjectAltName) {
|
||||||
dns, _, _, err := parseSANExtension(ext.Value)
|
dns, _, _, err := parseSANExtension(ext.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Warningf("unexpected error parsing certificate extensions: %v", err)
|
glog.Warningf("unexpected error parsing certificate extensions: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
cn = append(cn, dns...)
|
|
||||||
|
for _, dns := range dns {
|
||||||
|
if !cn.Has(dns) {
|
||||||
|
cn.Insert(dns)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +164,7 @@ func AddOrUpdateCertAndKey(name string, cert, key, ca []byte) (*ingress.SSLCert,
|
||||||
CAFileName: pemFileName,
|
CAFileName: pemFileName,
|
||||||
PemFileName: pemFileName,
|
PemFileName: pemFileName,
|
||||||
PemSHA: PemSHA1(pemFileName),
|
PemSHA: PemSHA1(pemFileName),
|
||||||
CN: cn,
|
CN: cn.List(),
|
||||||
ExpireTime: pemCert.NotAfter,
|
ExpireTime: pemCert.NotAfter,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -163,7 +172,7 @@ func AddOrUpdateCertAndKey(name string, cert, key, ca []byte) (*ingress.SSLCert,
|
||||||
return &ingress.SSLCert{
|
return &ingress.SSLCert{
|
||||||
PemFileName: pemFileName,
|
PemFileName: pemFileName,
|
||||||
PemSHA: PemSHA1(pemFileName),
|
PemSHA: PemSHA1(pemFileName),
|
||||||
CN: cn,
|
CN: cn.List(),
|
||||||
ExpireTime: pemCert.NotAfter,
|
ExpireTime: pemCert.NotAfter,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue