Skip to content

Commit

Permalink
Simplify handling of ssl certificates
Browse files Browse the repository at this point in the history
  • Loading branch information
aledbf committed Jul 12, 2017
1 parent 26fccdc commit 14a02d1
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 55 deletions.
4 changes: 3 additions & 1 deletion core/pkg/ingress/controller/backend_ssl.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,13 @@ func (ic *GenericController) syncSecret() {
}
glog.Infof("updating secret %v in the local store", key)
ic.sslCertTracker.Update(key, cert)
ic.reloadRequired = true
continue
}

glog.Infof("adding secret %v to the local store", key)
ic.sslCertTracker.Add(key, cert)
ic.reloadRequired = true
}
}

Expand All @@ -86,8 +88,8 @@ func (ic *GenericController) getPemCertificate(secretName string) (*ingress.SSLC

var s *ingress.SSLCert
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)
glog.V(3).Infof("found certificate and private key, configuring %v as a TLS Secret (CN: %v)", secretName, s.CN)
} else if ca != nil {
glog.V(3).Infof("found only ca.crt, configuring %v as an Certificate Authentication secret", secretName)
s, err = ssl.AddCertAuth(nsSecName, ca)
Expand Down
94 changes: 46 additions & 48 deletions core/pkg/ingress/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import (
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/flowcontrol"

"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/ingress/core/pkg/ingress"
"k8s.io/ingress/core/pkg/ingress/annotations/class"
"k8s.io/ingress/core/pkg/ingress/annotations/healthcheck"
Expand Down Expand Up @@ -113,8 +114,8 @@ type GenericController struct {
// runningConfig contains the running configuration in the Backend
runningConfig *ingress.Configuration

// configmapChanged indicates the configmap
configmapChanged bool
// reloadRequired indicates the configmap
reloadRequired bool
}

// Configuration contains all the settings required by an Ingress controller
Expand Down Expand Up @@ -262,7 +263,7 @@ func newIngressController(config *Configuration) *GenericController {
if mapKey == ic.cfg.ConfigMapName {
glog.V(2).Infof("adding configmap %v to backend", mapKey)
ic.cfg.Backend.SetConfig(upCmap)
ic.configmapChanged = true
ic.reloadRequired = true
}
},
UpdateFunc: func(old, cur interface{}) {
Expand All @@ -272,7 +273,7 @@ func newIngressController(config *Configuration) *GenericController {
if mapKey == ic.cfg.ConfigMapName {
glog.V(2).Infof("updating configmap backend (%v)", mapKey)
ic.cfg.Backend.SetConfig(upCmap)
ic.configmapChanged = true
ic.reloadRequired = true
}
// updates to configuration configmaps can trigger an update
if mapKey == ic.cfg.ConfigMapName || mapKey == ic.cfg.TCPConfigMapName || mapKey == ic.cfg.UDPConfigMapName {
Expand Down Expand Up @@ -419,7 +420,7 @@ func (ic *GenericController) syncIngress(key interface{}) error {
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)")
return nil
}
Expand All @@ -433,7 +434,7 @@ func (ic *GenericController) syncIngress(key interface{}) error {
return err
}

ic.configmapChanged = false
ic.reloadRequired = false
glog.Infof("ingress backend successfully reloaded...")
incReloadCount()
setSSLExpireTime(servers)
Expand Down Expand Up @@ -1018,55 +1019,52 @@ func (ic *GenericController) createServers(data []interface{},
}

// 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 == "" {
tlsSecretName := ""
found := false
for _, tls := range ing.Spec.TLS {
for _, tlsHost := range tls.Hosts {
if tlsHost == host {
tlsSecretName = tls.SecretName
found = true
break
}
}
}
if len(ing.Spec.TLS) == 0 || servers[host].SSLCertificate != "" {
continue
}

// the current ing.Spec.Rules[].Host doesn't have an entry at
// ing.Spec.TLS[].Hosts[], skipping to the next Rule
if !found {
continue
tlsSecretName := ""
found := false
for _, tls := range ing.Spec.TLS {
if sets.NewString(tls.Hosts...).Has(host) {
tlsSecretName = tls.SecretName
found = true
break
}
}

// Current Host listed on ing.Spec.TLS[].Hosts[]
// but TLS[].SecretName is empty; using default cert
if tlsSecretName == "" {
servers[host].SSLCertificate = defaultPemFileName
servers[host].SSLPemChecksum = defaultPemSHA
continue
}
// the current ing.Spec.Rules[].Host doesn't have an entry at
// ing.Spec.TLS[].Hosts[] skipping to the next Rule
if !found {
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)
}
if tlsSecretName == "" {
glog.Warningf("host %v is listed on tls section but secretName is empty. Using default cert", host)
servers[host].SSLCertificate = defaultPemFileName
servers[host].SSLPemChecksum = defaultPemSHA
continue
}

} else {
glog.Warningf("ssl certificate %v does not contain a common name for host %v", key, host)
}
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)
continue
}

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
}

glog.Infof("ssl certificate \"%v\" does not exist in local store", key)
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)
}
}
}
Expand Down
21 changes: 15 additions & 6 deletions core/pkg/net/ssl/ssl.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (

"github.com/golang/glog"

"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/ingress/core/pkg/ingress"
)

Expand Down Expand Up @@ -104,19 +105,27 @@ func AddOrUpdateCertAndKey(name string, cert, key, ca []byte) (*ingress.SSLCert,
return nil, err
}

cn := []string{pemCert.Subject.CommonName}
if len(pemCert.DNSNames) > 0 {
cn = append(cn, pemCert.DNSNames...)
cn := sets.NewString(pemCert.Subject.CommonName)
for _, dns := range pemCert.DNSNames {
if !cn.Has(dns) {
cn.Insert(dns)
}
}

if len(pemCert.Extensions) > 0 {
glog.V(3).Info("parsing ssl certificate extensions")
for _, ext := range getExtension(pemCert, oidExtensionSubjectAltName) {
dns, _, _, err := parseSANExtension(ext.Value)
if err != nil {
glog.Warningf("unexpected error parsing certificate extensions: %v", err)
continue
}
cn = append(cn, dns...)

for _, dns := range dns {
if !cn.Has(dns) {
cn.Insert(dns)
}
}
}
}

Expand Down Expand Up @@ -155,15 +164,15 @@ func AddOrUpdateCertAndKey(name string, cert, key, ca []byte) (*ingress.SSLCert,
CAFileName: pemFileName,
PemFileName: pemFileName,
PemSHA: PemSHA1(pemFileName),
CN: cn,
CN: cn.List(),
ExpireTime: pemCert.NotAfter,
}, nil
}

return &ingress.SSLCert{
PemFileName: pemFileName,
PemSHA: PemSHA1(pemFileName),
CN: cn,
CN: cn.List(),
ExpireTime: pemCert.NotAfter,
}, nil
}
Expand Down

0 comments on commit 14a02d1

Please sign in to comment.