mirror of
https://github.com/traefik/traefik.git
synced 2025-05-05 23:43:01 +00:00
Allow root CA to be added through config maps
This commit is contained in:
parent
30fe11eccf
commit
ae4a00b4bc
@ -192,6 +192,8 @@ To be consistent with the naming and other metrics providers, the metric now rep
|
||||
|
||||
### Kubernetes CRD Provider
|
||||
|
||||
#### Load-Balancing
|
||||
|
||||
In `v3.4`, the HTTP service definition has been updated.
|
||||
The strategy field now supports two new values: `wrr` and `p2c` (please refer to the [HTTP Services Load Balancing documentation](../../routing/services/#load-balancing-strategy) for more details).
|
||||
|
||||
@ -202,3 +204,37 @@ kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.4/docs/con
|
||||
```
|
||||
|
||||
Please note that the `RoundRobin` strategy value is now deprecated, but still supported and equivalent to `wrr`, and will be removed in the next major release.
|
||||
|
||||
#### ServersTransport CA Certificate
|
||||
|
||||
In `v3.4`, a new `rootCAs` option has been added to the `ServersTransport` and `ServersTransportTCP` CRDs.
|
||||
It allows the configuration of CA certificates from both `ConfigMaps` and `Secrets`,
|
||||
and replaces the `rootCAsSecrets` option, as shown below:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: ServersTransport
|
||||
metadata:
|
||||
name: foo
|
||||
namespace: bar
|
||||
spec:
|
||||
rootCAs:
|
||||
- configMap: ca-config-map
|
||||
- secret: ca-secret
|
||||
|
||||
---
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: ServersTransportTCP
|
||||
metadata:
|
||||
name: foo
|
||||
namespace: bar
|
||||
spec:
|
||||
rootCAs:
|
||||
- configMap: ca-config-map
|
||||
- secret: ca-secret
|
||||
```
|
||||
|
||||
The `rootCAsSecrets` option, which allows only `Secrets` references,
|
||||
is still supported, but is now deprecated,
|
||||
and will be removed in the next major release.
|
||||
|
@ -2252,9 +2252,33 @@ spec:
|
||||
description: PeerCertURI defines the peer cert URI used to match against
|
||||
SAN URI during the peer certificate verification.
|
||||
type: string
|
||||
rootCAs:
|
||||
description: RootCAs defines a list of CA certificate Secrets or ConfigMaps
|
||||
used to validate server certificates.
|
||||
items:
|
||||
description: |-
|
||||
RootCA defines a reference to a Secret or a ConfigMap that holds a CA certificate.
|
||||
If both a Secret and a ConfigMap reference are defined, the Secret reference takes precedence.
|
||||
properties:
|
||||
configMap:
|
||||
description: |-
|
||||
ConfigMap defines the name of a ConfigMap that holds a CA certificate.
|
||||
The referenced ConfigMap must contain a certificate under either a tls.ca or a ca.crt key.
|
||||
type: string
|
||||
secret:
|
||||
description: |-
|
||||
Secret defines the name of a Secret that holds a CA certificate.
|
||||
The referenced Secret must contain a certificate under either a tls.ca or a ca.crt key.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-validations:
|
||||
- message: RootCA cannot have both Secret and ConfigMap defined.
|
||||
rule: has(self.secret) && has(self.configMap)
|
||||
type: array
|
||||
rootCAsSecrets:
|
||||
description: RootCAsSecrets defines a list of CA secret used to validate
|
||||
self-signed certificate.
|
||||
description: |-
|
||||
RootCAsSecrets defines a list of CA secret used to validate self-signed certificate.
|
||||
Deprecated: RootCAsSecrets is deprecated, please use the RootCAs option instead.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
@ -2373,9 +2397,33 @@ spec:
|
||||
MaxIdleConnsPerHost controls the maximum idle (keep-alive) to keep per-host.
|
||||
PeerCertURI defines the peer cert URI used to match against SAN URI during the peer certificate verification.
|
||||
type: string
|
||||
rootCAs:
|
||||
description: RootCAs defines a list of CA certificate Secrets
|
||||
or ConfigMaps used to validate server certificates.
|
||||
items:
|
||||
description: |-
|
||||
RootCA defines a reference to a Secret or a ConfigMap that holds a CA certificate.
|
||||
If both a Secret and a ConfigMap reference are defined, the Secret reference takes precedence.
|
||||
properties:
|
||||
configMap:
|
||||
description: |-
|
||||
ConfigMap defines the name of a ConfigMap that holds a CA certificate.
|
||||
The referenced ConfigMap must contain a certificate under either a tls.ca or a ca.crt key.
|
||||
type: string
|
||||
secret:
|
||||
description: |-
|
||||
Secret defines the name of a Secret that holds a CA certificate.
|
||||
The referenced Secret must contain a certificate under either a tls.ca or a ca.crt key.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-validations:
|
||||
- message: RootCA cannot have both Secret and ConfigMap defined.
|
||||
rule: has(self.secret) && has(self.configMap)
|
||||
type: array
|
||||
rootCAsSecrets:
|
||||
description: RootCAsSecrets defines a list of CA secret used to
|
||||
validate self-signed certificates.
|
||||
description: |-
|
||||
RootCAsSecrets defines a list of CA secret used to validate self-signed certificate.
|
||||
Deprecated: RootCAsSecrets is deprecated, please use the RootCAs option instead.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
|
@ -113,9 +113,33 @@ spec:
|
||||
description: PeerCertURI defines the peer cert URI used to match against
|
||||
SAN URI during the peer certificate verification.
|
||||
type: string
|
||||
rootCAs:
|
||||
description: RootCAs defines a list of CA certificate Secrets or ConfigMaps
|
||||
used to validate server certificates.
|
||||
items:
|
||||
description: |-
|
||||
RootCA defines a reference to a Secret or a ConfigMap that holds a CA certificate.
|
||||
If both a Secret and a ConfigMap reference are defined, the Secret reference takes precedence.
|
||||
properties:
|
||||
configMap:
|
||||
description: |-
|
||||
ConfigMap defines the name of a ConfigMap that holds a CA certificate.
|
||||
The referenced ConfigMap must contain a certificate under either a tls.ca or a ca.crt key.
|
||||
type: string
|
||||
secret:
|
||||
description: |-
|
||||
Secret defines the name of a Secret that holds a CA certificate.
|
||||
The referenced Secret must contain a certificate under either a tls.ca or a ca.crt key.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-validations:
|
||||
- message: RootCA cannot have both Secret and ConfigMap defined.
|
||||
rule: has(self.secret) && has(self.configMap)
|
||||
type: array
|
||||
rootCAsSecrets:
|
||||
description: RootCAsSecrets defines a list of CA secret used to validate
|
||||
self-signed certificate.
|
||||
description: |-
|
||||
RootCAsSecrets defines a list of CA secret used to validate self-signed certificate.
|
||||
Deprecated: RootCAsSecrets is deprecated, please use the RootCAs option instead.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
|
@ -89,9 +89,33 @@ spec:
|
||||
MaxIdleConnsPerHost controls the maximum idle (keep-alive) to keep per-host.
|
||||
PeerCertURI defines the peer cert URI used to match against SAN URI during the peer certificate verification.
|
||||
type: string
|
||||
rootCAs:
|
||||
description: RootCAs defines a list of CA certificate Secrets
|
||||
or ConfigMaps used to validate server certificates.
|
||||
items:
|
||||
description: |-
|
||||
RootCA defines a reference to a Secret or a ConfigMap that holds a CA certificate.
|
||||
If both a Secret and a ConfigMap reference are defined, the Secret reference takes precedence.
|
||||
properties:
|
||||
configMap:
|
||||
description: |-
|
||||
ConfigMap defines the name of a ConfigMap that holds a CA certificate.
|
||||
The referenced ConfigMap must contain a certificate under either a tls.ca or a ca.crt key.
|
||||
type: string
|
||||
secret:
|
||||
description: |-
|
||||
Secret defines the name of a Secret that holds a CA certificate.
|
||||
The referenced Secret must contain a certificate under either a tls.ca or a ca.crt key.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-validations:
|
||||
- message: RootCA cannot have both Secret and ConfigMap defined.
|
||||
rule: has(self.secret) && has(self.configMap)
|
||||
type: array
|
||||
rootCAsSecrets:
|
||||
description: RootCAsSecrets defines a list of CA secret used to
|
||||
validate self-signed certificates.
|
||||
description: |-
|
||||
RootCAsSecrets defines a list of CA secret used to validate self-signed certificate.
|
||||
Deprecated: RootCAsSecrets is deprecated, please use the RootCAs option instead.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
|
@ -1851,9 +1851,9 @@ Register the `TLSStore` kind in the Kubernetes cluster before creating `TLSStore
|
||||
spec:
|
||||
serverName: foobar # [1]
|
||||
insecureSkipVerify: true # [2]
|
||||
rootCAsSecrets: # [3]
|
||||
- foobar
|
||||
- foobar
|
||||
rootCAs: # [3]
|
||||
- configMap: foobar
|
||||
- secret: foobar
|
||||
certificatesSecrets: # [4]
|
||||
- foobar
|
||||
- foobar
|
||||
@ -1871,22 +1871,22 @@ Register the `TLSStore` kind in the Kubernetes cluster before creating `TLSStore
|
||||
trustDomain: "spiffe://trust-domain" # [14]
|
||||
```
|
||||
|
||||
| Ref | Attribute | Purpose |
|
||||
|------|-------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [1] | `serverName` | ServerName used to contact the server. |
|
||||
| [2] | `insecureSkipVerify` | Controls whether the server's certificate chain and host name is verified. |
|
||||
| [3] | `rootCAsSecrets` | Defines the set of root certificate authorities to use when verifying server certificates. The secret must contain a certificate under either a tls.ca or a ca.crt key. |
|
||||
| [4] | `certificatesSecrets` | Certificates to present to the server for mTLS. |
|
||||
| [5] | `maxIdleConnsPerHost` | Controls the maximum idle (keep-alive) connections to keep per-host. If zero, `defaultMaxIdleConnsPerHost` is used. |
|
||||
| [6] | `forwardingTimeouts` | Timeouts for requests forwarded to the servers. |
|
||||
| [7] | `dialTimeout` | The amount of time to wait until a connection to a server can be established. If zero, no timeout exists. |
|
||||
| [8] | `responseHeaderTimeout` | The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists. |
|
||||
| [9] | `idleConnTimeout` | The maximum amount of time an idle (keep-alive) connection will remain idle before closing itself. If zero, no timeout exists. |
|
||||
| [10] | `peerCertURI` | URI used to match against SAN URIs during the server's certificate verification. |
|
||||
| [11] | `disableHTTP2` | Disables HTTP/2 for connections with servers. |
|
||||
| [12] | `spiffe` | The spiffe configuration. |
|
||||
| [13] | `ids` | Defines the allowed SPIFFE IDs (takes precedence over the SPIFFE TrustDomain). |
|
||||
| [14] | `trustDomain` | Defines the allowed SPIFFE trust domain. |
|
||||
| Ref | Attribute | Purpose |
|
||||
|------|-------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [1] | `serverName` | ServerName used to contact the server. |
|
||||
| [2] | `insecureSkipVerify` | Controls whether the server's certificate chain and host name is verified. |
|
||||
| [3] | `rootCAs` | Defines the set of root certificate authorities to use when verifying server certificates. The referenced Secret or ConfigMap must contain a certificate under either a tls.ca or a ca.crt key. |
|
||||
| [4] | `certificatesSecrets` | Certificates to present to the server for mTLS. |
|
||||
| [5] | `maxIdleConnsPerHost` | Controls the maximum idle (keep-alive) connections to keep per-host. If zero, `defaultMaxIdleConnsPerHost` is used. |
|
||||
| [6] | `forwardingTimeouts` | Timeouts for requests forwarded to the servers. |
|
||||
| [7] | `dialTimeout` | The amount of time to wait until a connection to a server can be established. If zero, no timeout exists. |
|
||||
| [8] | `responseHeaderTimeout` | The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists. |
|
||||
| [9] | `idleConnTimeout` | The maximum amount of time an idle (keep-alive) connection will remain idle before closing itself. If zero, no timeout exists. |
|
||||
| [10] | `peerCertURI` | URI used to match against SAN URIs during the server's certificate verification. |
|
||||
| [11] | `disableHTTP2` | Disables HTTP/2 for connections with servers. |
|
||||
| [12] | `spiffe` | The spiffe configuration. |
|
||||
| [13] | `ids` | Defines the allowed SPIFFE IDs (takes precedence over the SPIFFE TrustDomain). |
|
||||
| [14] | `trustDomain` | Defines the allowed SPIFFE trust domain. |
|
||||
|
||||
!!! info "CA Secret"
|
||||
|
||||
@ -1960,9 +1960,9 @@ The `default@internal` serversTransportTCP is created from the [static configura
|
||||
serverName: foobar # [5]
|
||||
insecureSkipVerify: true # [6]
|
||||
peerCertURI: foobar # [7]
|
||||
rootCAsSecrets: # [8]
|
||||
- foobar
|
||||
- foobar
|
||||
rootCAs: # [8]
|
||||
- secret: foobar
|
||||
- configMap: foobar
|
||||
certificatesSecrets: # [9]
|
||||
- foobar
|
||||
- foobar
|
||||
@ -1982,7 +1982,7 @@ The `default@internal` serversTransportTCP is created from the [static configura
|
||||
| [5] | `serverName` | ServerName used to contact the server. |
|
||||
| [6] | `insecureSkipVerify` | Controls whether the server's certificate chain and host name is verified. |
|
||||
| [7] | `peerCertURI` | URI used to match against SAN URIs during the server's certificate verification. |
|
||||
| [8] | `rootCAsSecrets` | Defines the set of root certificate authorities to use when verifying server certificates. The secret must contain a certificate under either a tls.ca or a ca.crt key. |
|
||||
| [8] | `rootCAs` | Defines the set of root certificate authorities to use when verifying server certificates. The referenced Secret or ConfigMap must contain a certificate under either a tls.ca or a ca.crt key. |
|
||||
| [9] | `certificatesSecrets` | Certificates to present to the server for mTLS. |
|
||||
| [10] | `spiffe` | The SPIFFE configuration. |
|
||||
| [11] | `ids` | Defines the allowed SPIFFE IDs (takes precedence over the SPIFFE TrustDomain). |
|
||||
|
@ -2252,9 +2252,33 @@ spec:
|
||||
description: PeerCertURI defines the peer cert URI used to match against
|
||||
SAN URI during the peer certificate verification.
|
||||
type: string
|
||||
rootCAs:
|
||||
description: RootCAs defines a list of CA certificate Secrets or ConfigMaps
|
||||
used to validate server certificates.
|
||||
items:
|
||||
description: |-
|
||||
RootCA defines a reference to a Secret or a ConfigMap that holds a CA certificate.
|
||||
If both a Secret and a ConfigMap reference are defined, the Secret reference takes precedence.
|
||||
properties:
|
||||
configMap:
|
||||
description: |-
|
||||
ConfigMap defines the name of a ConfigMap that holds a CA certificate.
|
||||
The referenced ConfigMap must contain a certificate under either a tls.ca or a ca.crt key.
|
||||
type: string
|
||||
secret:
|
||||
description: |-
|
||||
Secret defines the name of a Secret that holds a CA certificate.
|
||||
The referenced Secret must contain a certificate under either a tls.ca or a ca.crt key.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-validations:
|
||||
- message: RootCA cannot have both Secret and ConfigMap defined.
|
||||
rule: has(self.secret) && has(self.configMap)
|
||||
type: array
|
||||
rootCAsSecrets:
|
||||
description: RootCAsSecrets defines a list of CA secret used to validate
|
||||
self-signed certificate.
|
||||
description: |-
|
||||
RootCAsSecrets defines a list of CA secret used to validate self-signed certificate.
|
||||
Deprecated: RootCAsSecrets is deprecated, please use the RootCAs option instead.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
@ -2373,9 +2397,33 @@ spec:
|
||||
MaxIdleConnsPerHost controls the maximum idle (keep-alive) to keep per-host.
|
||||
PeerCertURI defines the peer cert URI used to match against SAN URI during the peer certificate verification.
|
||||
type: string
|
||||
rootCAs:
|
||||
description: RootCAs defines a list of CA certificate Secrets
|
||||
or ConfigMaps used to validate server certificates.
|
||||
items:
|
||||
description: |-
|
||||
RootCA defines a reference to a Secret or a ConfigMap that holds a CA certificate.
|
||||
If both a Secret and a ConfigMap reference are defined, the Secret reference takes precedence.
|
||||
properties:
|
||||
configMap:
|
||||
description: |-
|
||||
ConfigMap defines the name of a ConfigMap that holds a CA certificate.
|
||||
The referenced ConfigMap must contain a certificate under either a tls.ca or a ca.crt key.
|
||||
type: string
|
||||
secret:
|
||||
description: |-
|
||||
Secret defines the name of a Secret that holds a CA certificate.
|
||||
The referenced Secret must contain a certificate under either a tls.ca or a ca.crt key.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-validations:
|
||||
- message: RootCA cannot have both Secret and ConfigMap defined.
|
||||
rule: has(self.secret) && has(self.configMap)
|
||||
type: array
|
||||
rootCAsSecrets:
|
||||
description: RootCAsSecrets defines a list of CA secret used to
|
||||
validate self-signed certificates.
|
||||
description: |-
|
||||
RootCAsSecrets defines a list of CA secret used to validate self-signed certificate.
|
||||
Deprecated: RootCAsSecrets is deprecated, please use the RootCAs option instead.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
|
@ -331,8 +331,8 @@ type HealthCheck struct{}
|
||||
type ServersTransport struct {
|
||||
ServerName string `description:"Defines the serverName used to contact the server." json:"serverName,omitempty" toml:"serverName,omitempty" yaml:"serverName,omitempty"`
|
||||
InsecureSkipVerify bool `description:"Disables SSL certificate verification." json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty" export:"true"`
|
||||
RootCAs []types.FileOrContent `description:"Defines a list of CA secret used to validate self-signed certificate" json:"rootCAs,omitempty" toml:"rootCAs,omitempty" yaml:"rootCAs,omitempty"`
|
||||
Certificates traefiktls.Certificates `description:"Defines a list of secret storing client certificates for mTLS." json:"certificates,omitempty" toml:"certificates,omitempty" yaml:"certificates,omitempty" export:"true"`
|
||||
RootCAs []types.FileOrContent `description:"Defines a list of CA certificates used to validate server certificates." json:"rootCAs,omitempty" toml:"rootCAs,omitempty" yaml:"rootCAs,omitempty"`
|
||||
Certificates traefiktls.Certificates `description:"Defines a list of client certificates for mTLS." json:"certificates,omitempty" toml:"certificates,omitempty" yaml:"certificates,omitempty" export:"true"`
|
||||
MaxIdleConnsPerHost int `description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used" json:"maxIdleConnsPerHost,omitempty" toml:"maxIdleConnsPerHost,omitempty" yaml:"maxIdleConnsPerHost,omitempty" export:"true"`
|
||||
ForwardingTimeouts *ForwardingTimeouts `description:"Defines the timeouts for requests forwarded to the backend servers." json:"forwardingTimeouts,omitempty" toml:"forwardingTimeouts,omitempty" yaml:"forwardingTimeouts,omitempty" export:"true"`
|
||||
DisableHTTP2 bool `description:"Disables HTTP/2 for connections with backend servers." json:"disableHTTP2,omitempty" toml:"disableHTTP2,omitempty" yaml:"disableHTTP2,omitempty" export:"true"`
|
||||
|
@ -159,8 +159,8 @@ type TCPServersTransport struct {
|
||||
type TLSClientConfig struct {
|
||||
ServerName string `description:"Defines the serverName used to contact the server." json:"serverName,omitempty" toml:"serverName,omitempty" yaml:"serverName,omitempty"`
|
||||
InsecureSkipVerify bool `description:"Disables SSL certificate verification." json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty" export:"true"`
|
||||
RootCAs []types.FileOrContent `description:"Defines a list of CA secret used to validate self-signed certificate" json:"rootCAs,omitempty" toml:"rootCAs,omitempty" yaml:"rootCAs,omitempty"`
|
||||
Certificates traefiktls.Certificates `description:"Defines a list of secret storing client certificates for mTLS." json:"certificates,omitempty" toml:"certificates,omitempty" yaml:"certificates,omitempty" export:"true"`
|
||||
RootCAs []types.FileOrContent `description:"Defines a list of CA certificates used to validate server certificates." json:"rootCAs,omitempty" toml:"rootCAs,omitempty" yaml:"rootCAs,omitempty"`
|
||||
Certificates traefiktls.Certificates `description:"Defines a list of client certificates for mTLS." json:"certificates,omitempty" toml:"certificates,omitempty" yaml:"certificates,omitempty" export:"true"`
|
||||
PeerCertURI string `description:"Defines the URI used to match against SAN URI during the peer certificate verification." json:"peerCertURI,omitempty" toml:"peerCertURI,omitempty" yaml:"peerCertURI,omitempty" export:"true"`
|
||||
Spiffe *Spiffe `description:"Defines the SPIFFE TLS configuration." json:"spiffe,omitempty" toml:"spiffe,omitempty" yaml:"spiffe,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ type Client interface {
|
||||
GetSecret(namespace, name string) (*corev1.Secret, bool, error)
|
||||
GetEndpointSlicesForService(namespace, serviceName string) ([]*discoveryv1.EndpointSlice, error)
|
||||
GetNodes() ([]*corev1.Node, bool, error)
|
||||
GetConfigMap(namespace, name string) (*corev1.ConfigMap, bool, error)
|
||||
}
|
||||
|
||||
// TODO: add tests for the clientWrapper (and its methods) itself.
|
||||
@ -227,6 +228,10 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (<
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = factoryKube.Core().V1().ConfigMaps().Informer().AddEventHandler(eventHandler)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
factorySecret := kinformers.NewSharedInformerFactoryWithOptions(c.csKube, resyncPeriod, kinformers.WithNamespace(ns), kinformers.WithTweakListOptions(notOwnedByHelm))
|
||||
_, err = factorySecret.Core().V1().Secrets().Informer().AddEventHandler(eventHandler)
|
||||
@ -478,6 +483,17 @@ func (c *clientWrapper) GetSecret(namespace, name string) (*corev1.Secret, bool,
|
||||
return secret, exist, err
|
||||
}
|
||||
|
||||
// GetConfigMap returns the named config map from the given namespace.
|
||||
func (c *clientWrapper) GetConfigMap(namespace, name string) (*corev1.ConfigMap, bool, error) {
|
||||
if !c.isWatchedNamespace(namespace) {
|
||||
return nil, false, fmt.Errorf("failed to get config map %s/%s: namespace is not within watched namespaces", namespace, name)
|
||||
}
|
||||
|
||||
configMap, err := c.factoriesKube[c.lookupNamespace(namespace)].Core().V1().ConfigMaps().Lister().ConfigMaps(namespace).Get(name)
|
||||
exist, err := translateNotFoundError(err)
|
||||
return configMap, exist, err
|
||||
}
|
||||
|
||||
func (c *clientWrapper) GetNodes() ([]*corev1.Node, bool, error) {
|
||||
nodes, err := c.clusterScopeFactory.Core().V1().Nodes().Lister().List(labels.Everything())
|
||||
exist, err := translateNotFoundError(err)
|
||||
|
@ -48,6 +48,26 @@ data:
|
||||
ca.crt: VEVTVFJPT1RDQVM0
|
||||
tls.ca: VEVTVFJPT1RDQVM1 # <-- This should be the preferred one.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: root-ca5
|
||||
namespace: foo
|
||||
|
||||
data:
|
||||
ca.crt: VEVTVFJPT1RDQVM2
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: root-ca6
|
||||
namespace: foo
|
||||
|
||||
data:
|
||||
ca.crt: VEVTVFJPT1RDQVM3
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
@ -82,6 +102,26 @@ data:
|
||||
tls.crt: VEVTVENFUlQz
|
||||
tls.key: VEVTVEtFWTM=
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: root-ca-as-config-map
|
||||
namespace: foo
|
||||
|
||||
data:
|
||||
ca.crt: "TESTROOTCASFROMCONFIGMAP"
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: root-ca-as-config-map-2
|
||||
namespace: foo
|
||||
|
||||
data:
|
||||
ca.crt: "TESTROOTCASFROMCONFIGMAP2"
|
||||
|
||||
---
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: ServersTransportTCP
|
||||
@ -101,6 +141,12 @@ spec:
|
||||
- root-ca3
|
||||
- root-ca4
|
||||
- allcerts
|
||||
rootCAs:
|
||||
- configMap: root-ca-as-config-map
|
||||
- secret: root-ca5
|
||||
# referencing both a ConfigMap and a Secret should fail.
|
||||
- configMap: root-ca-as-config-map-2
|
||||
secret: root-ca6
|
||||
certificatesSecrets:
|
||||
- mtls1
|
||||
- mtls2
|
||||
|
@ -1,4 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: foo
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: root-ca0
|
||||
@ -48,6 +54,26 @@ data:
|
||||
ca.crt: VEVTVFJPT1RDQVM0
|
||||
tls.ca: VEVTVFJPT1RDQVM1 # <-- This should be the preferred one.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: root-ca5
|
||||
namespace: foo
|
||||
|
||||
data:
|
||||
ca.crt: VEVTVFJPT1RDQVM2
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: root-ca6
|
||||
namespace: foo
|
||||
|
||||
data:
|
||||
ca.crt: VEVTVFJPT1RDQVM3
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
@ -82,6 +108,26 @@ data:
|
||||
tls.crt: VEVTVENFUlQz
|
||||
tls.key: VEVTVEtFWTM=
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: root-ca-as-config-map
|
||||
namespace: foo
|
||||
|
||||
data:
|
||||
ca.crt: "TESTROOTCASFROMCONFIGMAP"
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: root-ca-as-config-map-2
|
||||
namespace: foo
|
||||
|
||||
data:
|
||||
ca.crt: "TESTROOTCASFROMCONFIGMAP2"
|
||||
|
||||
---
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: ServersTransport
|
||||
@ -102,6 +148,12 @@ spec:
|
||||
- root-ca3
|
||||
- root-ca4
|
||||
- allcerts
|
||||
rootCAs:
|
||||
- configMap: root-ca-as-config-map
|
||||
- secret: root-ca5
|
||||
# referencing both a ConfigMap and a Secret should fail.
|
||||
- configMap: root-ca-as-config-map-2
|
||||
secret: root-ca6
|
||||
certificatesSecrets:
|
||||
- mtls1
|
||||
- mtls2
|
||||
|
@ -340,19 +340,61 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
|
||||
}
|
||||
|
||||
for _, serversTransport := range client.GetServersTransports() {
|
||||
logger := log.Ctx(ctx).With().Str(logs.ServersTransportName, serversTransport.Name).Logger()
|
||||
logger := log.Ctx(ctx).With().
|
||||
Str(logs.ServersTransportName, serversTransport.Name).
|
||||
Str("namespace", serversTransport.Namespace).
|
||||
Logger()
|
||||
|
||||
if len(serversTransport.Spec.RootCAsSecrets) > 0 {
|
||||
logger.Warn().Msg("RootCAsSecrets option is deprecated, please use the RootCA option instead.")
|
||||
}
|
||||
|
||||
var rootCAs []types.FileOrContent
|
||||
for _, secret := range serversTransport.Spec.RootCAsSecrets {
|
||||
caSecret, err := loadCASecret(serversTransport.Namespace, secret, client)
|
||||
if err != nil {
|
||||
logger.Error().Err(err).Msgf("Error while loading rootCAs %s", secret)
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("secret", secret).
|
||||
Msg("Error while loading CA Secret")
|
||||
continue
|
||||
}
|
||||
|
||||
rootCAs = append(rootCAs, types.FileOrContent(caSecret))
|
||||
}
|
||||
|
||||
for _, rootCA := range serversTransport.Spec.RootCAs {
|
||||
if rootCA.Secret != nil && rootCA.ConfigMap != nil {
|
||||
logger.Error().Msg("Error while loading CA: both Secret and ConfigMap are defined")
|
||||
continue
|
||||
}
|
||||
|
||||
if rootCA.Secret != nil {
|
||||
ca, err := loadCASecret(serversTransport.Namespace, *rootCA.Secret, client)
|
||||
if err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("secret", *rootCA.Secret).
|
||||
Msg("Error while loading CA Secret")
|
||||
continue
|
||||
}
|
||||
|
||||
rootCAs = append(rootCAs, types.FileOrContent(ca))
|
||||
continue
|
||||
}
|
||||
|
||||
ca, err := loadCAConfigMap(serversTransport.Namespace, *rootCA.ConfigMap, client)
|
||||
if err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("configMap", *rootCA.ConfigMap).
|
||||
Msg("Error while loading CA ConfigMap")
|
||||
continue
|
||||
}
|
||||
|
||||
rootCAs = append(rootCAs, types.FileOrContent(ca))
|
||||
}
|
||||
|
||||
var certs tls.Certificates
|
||||
for _, secret := range serversTransport.Spec.CertificatesSecrets {
|
||||
tlsSecret, tlsKey, err := loadAuthTLSSecret(serversTransport.Namespace, secret, client)
|
||||
@ -449,20 +491,56 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
|
||||
}
|
||||
|
||||
if serversTransportTCP.Spec.TLS != nil {
|
||||
if len(serversTransportTCP.Spec.TLS.RootCAsSecrets) > 0 {
|
||||
logger.Warn().Msg("RootCAsSecrets option is deprecated, please use the RootCA option instead.")
|
||||
}
|
||||
|
||||
var rootCAs []types.FileOrContent
|
||||
for _, secret := range serversTransportTCP.Spec.TLS.RootCAsSecrets {
|
||||
caSecret, err := loadCASecret(serversTransportTCP.Namespace, secret, client)
|
||||
if err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("rootCAs", secret).
|
||||
Msg("Error while loading rootCAs")
|
||||
Str("secret", secret).
|
||||
Msg("Error while loading CA Secret")
|
||||
continue
|
||||
}
|
||||
|
||||
rootCAs = append(rootCAs, types.FileOrContent(caSecret))
|
||||
}
|
||||
|
||||
for _, rootCA := range serversTransportTCP.Spec.TLS.RootCAs {
|
||||
if rootCA.Secret != nil && rootCA.ConfigMap != nil {
|
||||
logger.Error().Msg("Error while loading CA: both Secret and ConfigMap are defined")
|
||||
continue
|
||||
}
|
||||
|
||||
if rootCA.Secret != nil {
|
||||
ca, err := loadCASecret(serversTransportTCP.Namespace, *rootCA.Secret, client)
|
||||
if err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("secret", *rootCA.Secret).
|
||||
Msg("Error while loading CA Secret")
|
||||
continue
|
||||
}
|
||||
|
||||
rootCAs = append(rootCAs, types.FileOrContent(ca))
|
||||
continue
|
||||
}
|
||||
|
||||
ca, err := loadCAConfigMap(serversTransportTCP.Namespace, *rootCA.ConfigMap, client)
|
||||
if err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("configMap", *rootCA.ConfigMap).
|
||||
Msg("Error while loading CA ConfigMap")
|
||||
continue
|
||||
}
|
||||
|
||||
rootCAs = append(rootCAs, types.FileOrContent(ca))
|
||||
}
|
||||
|
||||
var certs tls.Certificates
|
||||
for _, secret := range serversTransportTCP.Spec.TLS.CertificatesSecrets {
|
||||
tlsCert, tlsKey, err := loadAuthTLSSecret(serversTransportTCP.Namespace, secret, client)
|
||||
@ -936,7 +1014,7 @@ func loadCASecret(namespace, secretName string, k8sClient Client) (string, error
|
||||
return tlsCAData, nil
|
||||
}
|
||||
|
||||
// TODO: remove this behavior in the next major version (v3)
|
||||
// TODO: remove this behavior in the next major version (v4)
|
||||
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 {
|
||||
@ -944,7 +1022,29 @@ func loadCASecret(namespace, secretName string, k8sClient Client) (string, error
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("could not find CA block: %w", err)
|
||||
return "", fmt.Errorf("secret '%s/%s' has no CA block: %w", namespace, secretName, err)
|
||||
}
|
||||
|
||||
func loadCAConfigMap(namespace, name string, k8sClient Client) (string, error) {
|
||||
configMap, ok, err := k8sClient.GetConfigMap(namespace, name)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to fetch configMap '%s/%s': %w", namespace, name, err)
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return "", fmt.Errorf("configMap '%s/%s' not found", namespace, name)
|
||||
}
|
||||
|
||||
if configMap == nil {
|
||||
return "", fmt.Errorf("data for configMap '%s/%s' must not be nil", namespace, name)
|
||||
}
|
||||
|
||||
tlsCAData, err := getCABlocksFromConfigMap(configMap, namespace, name)
|
||||
if err == nil {
|
||||
return tlsCAData, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("configMap '%s/%s' has no CA block: %w", namespace, name, err)
|
||||
}
|
||||
|
||||
func loadAuthTLSSecret(namespace, secretName string, k8sClient Client) (string, string, error) {
|
||||
@ -1384,6 +1484,20 @@ func getCABlocks(secret *corev1.Secret, namespace, secretName string) (string, e
|
||||
return "", fmt.Errorf("secret %s/%s contains neither tls.ca nor ca.crt", namespace, secretName)
|
||||
}
|
||||
|
||||
func getCABlocksFromConfigMap(configMap *corev1.ConfigMap, namespace, name string) (string, error) {
|
||||
tlsCrtData, tlsCrtExists := configMap.Data["tls.ca"]
|
||||
if tlsCrtExists {
|
||||
return tlsCrtData, nil
|
||||
}
|
||||
|
||||
tlsCrtData, tlsCrtExists = configMap.Data["ca.crt"]
|
||||
if tlsCrtExists {
|
||||
return tlsCrtData, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("config map %s/%s contains neither tls.ca nor ca.crt", namespace, name)
|
||||
}
|
||||
|
||||
func throttleEvents(ctx context.Context, throttleDuration time.Duration, pool *safe.Pool, eventsChan <-chan interface{}) chan interface{} {
|
||||
if throttleDuration == 0 {
|
||||
return nil
|
||||
|
@ -1491,7 +1491,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||
TLS: &dynamic.TLSClientConfig{
|
||||
ServerName: "test",
|
||||
InsecureSkipVerify: true,
|
||||
RootCAs: []types.FileOrContent{"TESTROOTCAS0", "TESTROOTCAS1", "TESTROOTCAS2", "TESTROOTCAS3", "TESTROOTCAS5", "TESTALLCERTS"},
|
||||
RootCAs: []types.FileOrContent{"TESTROOTCAS0", "TESTROOTCAS1", "TESTROOTCAS2", "TESTROOTCAS3", "TESTROOTCAS5", "TESTALLCERTS", "TESTROOTCASFROMCONFIGMAP", "TESTROOTCAS6"},
|
||||
Certificates: tls.Certificates{
|
||||
{CertFile: "TESTCERT1", KeyFile: "TESTKEY1"},
|
||||
{CertFile: "TESTCERT2", KeyFile: "TESTKEY2"},
|
||||
@ -4734,7 +4734,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
"foo-test": {
|
||||
ServerName: "test",
|
||||
InsecureSkipVerify: true,
|
||||
RootCAs: []types.FileOrContent{"TESTROOTCAS0", "TESTROOTCAS1", "TESTROOTCAS2", "TESTROOTCAS3", "TESTROOTCAS5", "TESTALLCERTS"},
|
||||
RootCAs: []types.FileOrContent{"TESTROOTCAS0", "TESTROOTCAS1", "TESTROOTCAS2", "TESTROOTCAS3", "TESTROOTCAS5", "TESTALLCERTS", "TESTROOTCASFROMCONFIGMAP", "TESTROOTCAS6"},
|
||||
Certificates: tls.Certificates{
|
||||
{CertFile: "TESTCERT1", KeyFile: "TESTKEY1"},
|
||||
{CertFile: "TESTCERT2", KeyFile: "TESTKEY2"},
|
||||
|
@ -31,7 +31,10 @@ type ServersTransportSpec struct {
|
||||
ServerName string `json:"serverName,omitempty"`
|
||||
// InsecureSkipVerify disables SSL certificate verification.
|
||||
InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"`
|
||||
// RootCAs defines a list of CA certificate Secrets or ConfigMaps used to validate server certificates.
|
||||
RootCAs []RootCA `json:"rootCAs,omitempty"`
|
||||
// RootCAsSecrets defines a list of CA secret used to validate self-signed certificate.
|
||||
// Deprecated: RootCAsSecrets is deprecated, please use the RootCAs option instead.
|
||||
RootCAsSecrets []string `json:"rootCAsSecrets,omitempty"`
|
||||
// CertificatesSecrets defines a list of secret storing client certificates for mTLS.
|
||||
CertificatesSecrets []string `json:"certificatesSecrets,omitempty"`
|
||||
@ -74,6 +77,20 @@ type ForwardingTimeouts struct {
|
||||
PingTimeout *intstr.IntOrString `json:"pingTimeout,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
|
||||
// RootCA defines a reference to a Secret or a ConfigMap that holds a CA certificate.
|
||||
// If both a Secret and a ConfigMap reference are defined, the Secret reference takes precedence.
|
||||
// +kubebuilder:validation:XValidation:rule="has(self.secret) && has(self.configMap)",message="RootCA cannot have both Secret and ConfigMap defined."
|
||||
type RootCA struct {
|
||||
// Secret defines the name of a Secret that holds a CA certificate.
|
||||
// The referenced Secret must contain a certificate under either a tls.ca or a ca.crt key.
|
||||
Secret *string `json:"secret,omitempty"`
|
||||
// ConfigMap defines the name of a ConfigMap that holds a CA certificate.
|
||||
// The referenced ConfigMap must contain a certificate under either a tls.ca or a ca.crt key.
|
||||
ConfigMap *string `json:"configMap,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ServersTransportList is a collection of ServersTransport resources.
|
||||
|
@ -49,7 +49,10 @@ type TLSClientConfig struct {
|
||||
ServerName string `json:"serverName,omitempty"`
|
||||
// InsecureSkipVerify disables TLS certificate verification.
|
||||
InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"`
|
||||
// RootCAsSecrets defines a list of CA secret used to validate self-signed certificates.
|
||||
// RootCAs defines a list of CA certificate Secrets or ConfigMaps used to validate server certificates.
|
||||
RootCAs []RootCA `json:"rootCAs,omitempty"`
|
||||
// RootCAsSecrets defines a list of CA secret used to validate self-signed certificate.
|
||||
// Deprecated: RootCAsSecrets is deprecated, please use the RootCAs option instead.
|
||||
RootCAsSecrets []string `json:"rootCAsSecrets,omitempty"`
|
||||
// CertificatesSecrets defines a list of secret storing client certificates for mTLS.
|
||||
CertificatesSecrets []string `json:"certificatesSecrets,omitempty"`
|
||||
|
@ -1162,6 +1162,32 @@ func (in *Retry) DeepCopy() *Retry {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RootCA) DeepCopyInto(out *RootCA) {
|
||||
*out = *in
|
||||
if in.Secret != nil {
|
||||
in, out := &in.Secret, &out.Secret
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.ConfigMap != nil {
|
||||
in, out := &in.ConfigMap, &out.ConfigMap
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RootCA.
|
||||
func (in *RootCA) DeepCopy() *RootCA {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RootCA)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Route) DeepCopyInto(out *Route) {
|
||||
*out = *in
|
||||
@ -1347,6 +1373,13 @@ func (in *ServersTransportList) DeepCopyObject() runtime.Object {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ServersTransportSpec) DeepCopyInto(out *ServersTransportSpec) {
|
||||
*out = *in
|
||||
if in.RootCAs != nil {
|
||||
in, out := &in.RootCAs, &out.RootCAs
|
||||
*out = make([]RootCA, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.RootCAsSecrets != nil {
|
||||
in, out := &in.RootCAsSecrets, &out.RootCAsSecrets
|
||||
*out = make([]string, len(*in))
|
||||
@ -1593,6 +1626,13 @@ func (in *TLS) DeepCopy() *TLS {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *TLSClientConfig) DeepCopyInto(out *TLSClientConfig) {
|
||||
*out = *in
|
||||
if in.RootCAs != nil {
|
||||
in, out := &in.RootCAs, &out.RootCAs
|
||||
*out = make([]RootCA, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.RootCAsSecrets != nil {
|
||||
in, out := &in.RootCAsSecrets, &out.RootCAsSecrets
|
||||
*out = make([]string, len(*in))
|
||||
|
Loading…
x
Reference in New Issue
Block a user