Skip to content

Commit

Permalink
feat: Skip synchronisation of expired CA certificates (#3063)
Browse files Browse the repository at this point in the history
CA certificate expiration validation is introduced. Once it fails, synchronization to the data plane is skipped (analogically to the other already existing validations against CA certificate secrets). It also adds logging of affected plugins for better context.
  • Loading branch information
czeslavo authored Oct 18, 2022
1 parent 99e3e64 commit 77c5f32
Show file tree
Hide file tree
Showing 6 changed files with 239 additions and 159 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ Adding a new version? You'll need three changes:
- Added `--cache-sync-timeout` flag allowing to change the default controllers'
cache synchronisation timeout.
[#3013](https:/Kong/kubernetes-ingress-controller/pull/3013)
- Secrets validation introduced: CA certificates won't be synchronized
to Kong if the certificate is expired.
[#3063](https:/Kong/kubernetes-ingress-controller/pull/3063)

### Fixed

Expand Down
10 changes: 3 additions & 7 deletions internal/dataplane/kong_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,13 +311,9 @@ func (c *KongClient) Update(ctx context.Context) error {
}

// parse the Kubernetes objects from the storer into Kong configuration
kongstate, err := p.Build()
if err != nil {
c.prometheusMetrics.TranslationCount.With(prometheus.Labels{
metrics.SuccessKey: metrics.SuccessFalse,
}).Inc()
return err
}
kongstate := p.Build()
// todo: does it still make sense to report TranslationCount when Build no longer returns an error?
// https:/Kong/kubernetes-ingress-controller/issues/1892
c.prometheusMetrics.TranslationCount.With(prometheus.Labels{
metrics.SuccessKey: metrics.SuccessTrue,
}).Inc()
Expand Down
59 changes: 3 additions & 56 deletions internal/dataplane/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package parser
import (
"bytes"
"crypto/tls"
"crypto/x509"
"encoding/pem"
"fmt"
"reflect"
"sort"
Expand Down Expand Up @@ -73,8 +71,7 @@ func NewParser(

// Build creates a Kong configuration from Ingress and Custom resources
// defined in Kubernetes.
// It throws an error if there is an error returned from client-go.
func (p *Parser) Build() (*kongstate.KongState, error) {
func (p *Parser) Build() *kongstate.KongState {
// parse and merge all rules together from all Kubernetes API sources
ingressRules := mergeIngressRules(
p.ingressRulesFromIngressV1beta1(),
Expand Down Expand Up @@ -121,14 +118,9 @@ func (p *Parser) Build() (*kongstate.KongState, error) {
result.Certificates = mergeCerts(p.logger, ingressCerts, gatewayCerts)

// populate CA certificates in Kong
var err error
caCertSecrets, err := p.storer.ListCACerts()
if err != nil {
return nil, err
}
result.CACertificates = toCACerts(p.logger, caCertSecrets)
result.CACertificates = getCACerts(p.logger, p.storer, result.Plugins)

return &result, nil
return &result
}

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -186,51 +178,6 @@ func (p *Parser) EnableRegexPathPrefix() {
// Parser - Private Methods
// -----------------------------------------------------------------------------

func toCACerts(log logrus.FieldLogger, caCertSecrets []*corev1.Secret) []kong.CACertificate {
var caCerts []kong.CACertificate
for _, certSecret := range caCertSecrets {
secretName := certSecret.Namespace + "/" + certSecret.Name

idbytes, idExists := certSecret.Data["id"]
log = log.WithFields(logrus.Fields{
"secret_name": secretName,
"secret_namespace": certSecret.Namespace,
})
if !idExists {
log.Errorf("invalid CA certificate: missing 'id' field in data")
continue
}

caCertbytes, certExists := certSecret.Data["cert"]
if !certExists {
log.Errorf("invalid CA certificate: missing 'cert' field in data")
continue
}

pemBlock, _ := pem.Decode(caCertbytes)
if pemBlock == nil {
log.Errorf("invalid CA certificate: invalid PEM block")
continue
}
x509Cert, err := x509.ParseCertificate(pemBlock.Bytes)
if err != nil {
log.WithError(err).Errorf("invalid CA certificate: failed to parse certificate")
continue
}
if !x509Cert.IsCA {
log.WithError(err).Errorf("invalid CA certificate: certificate is missing the 'CA' basic constraint")
continue
}

caCerts = append(caCerts, kong.CACertificate{
ID: kong.String(string(idbytes)),
Cert: kong.String(string(caCertbytes)),
})
}

return caCerts
}

func knativeIngressToNetworkingTLS(tls []knative.IngressTLS) []netv1beta1.IngressTLS {
var result []netv1beta1.IngressTLS

Expand Down
Loading

0 comments on commit 77c5f32

Please sign in to comment.