Improve CA certificate loading from kubernetes secret
This commit is contained in:
parent
a758d18e51
commit
0a3e40332a
7 changed files with 98 additions and 30 deletions
|
@ -1,11 +1,21 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: rootCas0
|
||||
namespace: foo
|
||||
|
||||
data:
|
||||
foobar: VEVTVFJPT1RDQVMw
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: rootCas1
|
||||
namespace: foo
|
||||
|
||||
data:
|
||||
tls.ca: VEVTVFJPT1RDQVM=
|
||||
tls.ca: VEVTVFJPT1RDQVMx
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
|
@ -17,6 +27,27 @@ metadata:
|
|||
data:
|
||||
tls.ca: VEVTVFJPT1RDQVMy
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: rootCas3
|
||||
namespace: foo
|
||||
|
||||
data:
|
||||
ca.crt: VEVTVFJPT1RDQVMz
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: rootCas4
|
||||
namespace: foo
|
||||
|
||||
data:
|
||||
ca.crt: VEVTVFJPT1RDQVM0
|
||||
tls.ca: VEVTVFJPT1RDQVM1 # <-- This should be the prefered one.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
|
@ -39,6 +70,18 @@ data:
|
|||
tls.crt: VEVTVENFUlQy
|
||||
tls.key: VEVTVEtFWTI=
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: allcerts
|
||||
namespace: foo
|
||||
|
||||
data:
|
||||
ca.crt: VEVTVEFMTENFUlRT
|
||||
tls.crt: VEVTVENFUlQz
|
||||
tls.key: VEVTVEtFWTM=
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: ServersTransport
|
||||
|
@ -51,11 +94,16 @@ spec:
|
|||
insecureSkipVerify: true
|
||||
maxIdleConnsPerHost: 42
|
||||
rootCAsSecrets:
|
||||
- rootCas0
|
||||
- rootCas1
|
||||
- rootCas2
|
||||
- rootCas3
|
||||
- rootCas4
|
||||
- allcerts
|
||||
certificatesSecrets:
|
||||
- mtls1
|
||||
- mtls2
|
||||
- allcerts
|
||||
forwardingTimeouts:
|
||||
dialTimeout: 42
|
||||
responseHeaderTimeout: 42s
|
||||
|
|
|
@ -15,7 +15,7 @@ metadata:
|
|||
namespace: default
|
||||
|
||||
data:
|
||||
tls.ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
|
||||
ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
|
|
|
@ -508,20 +508,29 @@ func loadCASecret(namespace, secretName string, k8sClient Client) (string, error
|
|||
if err != nil {
|
||||
return "", fmt.Errorf("failed to fetch secret '%s/%s': %w", namespace, secretName, err)
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return "", fmt.Errorf("secret '%s/%s' not found", namespace, secretName)
|
||||
}
|
||||
|
||||
if secret == nil {
|
||||
return "", fmt.Errorf("data for secret '%s/%s' must not be nil", namespace, secretName)
|
||||
}
|
||||
if len(secret.Data) != 1 {
|
||||
return "", fmt.Errorf("found %d elements for secret '%s/%s', must be single element exactly", len(secret.Data), namespace, secretName)
|
||||
|
||||
tlsCAData, err := getCABlocks(secret, namespace, secretName)
|
||||
if err == nil {
|
||||
return tlsCAData, nil
|
||||
}
|
||||
|
||||
for _, v := range secret.Data {
|
||||
return string(v), nil
|
||||
// TODO: remove this behavior in the next major version (v3)
|
||||
if len(secret.Data) == 1 {
|
||||
// For backwards compatibility, use the only available secret data as CA if both 'ca.crt' and 'tls.ca' are missing.
|
||||
for _, v := range secret.Data {
|
||||
return string(v), nil
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
|
||||
return "", fmt.Errorf("could not find CA block: %w", err)
|
||||
}
|
||||
|
||||
func loadAuthTLSSecret(namespace, secretName string, k8sClient Client) (string, string, error) {
|
||||
|
@ -529,15 +538,14 @@ func loadAuthTLSSecret(namespace, secretName string, k8sClient Client) (string,
|
|||
if err != nil {
|
||||
return "", "", fmt.Errorf("failed to fetch secret '%s/%s': %w", namespace, secretName, err)
|
||||
}
|
||||
|
||||
if !exists {
|
||||
return "", "", fmt.Errorf("secret '%s/%s' does not exist", namespace, secretName)
|
||||
}
|
||||
|
||||
if secret == nil {
|
||||
return "", "", fmt.Errorf("data for secret '%s/%s' must not be nil", namespace, secretName)
|
||||
}
|
||||
if len(secret.Data) != 2 {
|
||||
return "", "", fmt.Errorf("found %d elements for secret '%s/%s', must be two elements exactly", len(secret.Data), namespace, secretName)
|
||||
}
|
||||
|
||||
return getCertificateBlocks(secret, namespace, secretName)
|
||||
}
|
||||
|
@ -869,16 +877,16 @@ func getCertificateBlocks(secret *corev1.Secret, namespace, secretName string) (
|
|||
|
||||
func getCABlocks(secret *corev1.Secret, namespace, secretName string) (string, error) {
|
||||
tlsCrtData, tlsCrtExists := secret.Data["tls.ca"]
|
||||
if !tlsCrtExists {
|
||||
return "", fmt.Errorf("the tls.ca entry is missing from secret %s/%s", namespace, secretName)
|
||||
if tlsCrtExists {
|
||||
return string(tlsCrtData), nil
|
||||
}
|
||||
|
||||
cert := string(tlsCrtData)
|
||||
if cert == "" {
|
||||
return "", fmt.Errorf("the tls.ca entry in secret %s/%s is empty", namespace, secretName)
|
||||
tlsCrtData, tlsCrtExists = secret.Data["ca.crt"]
|
||||
if tlsCrtExists {
|
||||
return string(tlsCrtData), nil
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
return "", fmt.Errorf("secret %s/%s contains neither tls.ca nor ca.crt", namespace, secretName)
|
||||
}
|
||||
|
||||
func throttleEvents(ctx context.Context, throttleDuration time.Duration, pool *safe.Pool, eventsChan <-chan interface{}) chan interface{} {
|
||||
|
|
|
@ -3444,10 +3444,11 @@ func TestLoadIngressRoutes(t *testing.T) {
|
|||
"test": {
|
||||
ServerName: "test",
|
||||
InsecureSkipVerify: true,
|
||||
RootCAs: []tls.FileOrContent{"TESTROOTCAS", "TESTROOTCAS2"},
|
||||
RootCAs: []tls.FileOrContent{"TESTROOTCAS0", "TESTROOTCAS1", "TESTROOTCAS2", "TESTROOTCAS3", "TESTROOTCAS5", "TESTALLCERTS"},
|
||||
Certificates: tls.Certificates{
|
||||
{CertFile: "TESTCERT1", KeyFile: "TESTKEY1"},
|
||||
{CertFile: "TESTCERT2", KeyFile: "TESTKEY2"},
|
||||
{CertFile: "TESTCERT3", KeyFile: "TESTKEY3"},
|
||||
},
|
||||
MaxIdleConnsPerHost: 42,
|
||||
ForwardingTimeouts: &dynamic.ForwardingTimeouts{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue