mirror of
https://github.com/traefik/traefik
synced 2026-02-03 12:20:33 +00:00
Support auth-tls-secret and auth-tls-verify-client annotations
This commit is contained in:
@@ -268,7 +268,7 @@ The following annotations are organized by category for easier navigation.
|
|||||||
### SSL/TLS
|
### SSL/TLS
|
||||||
|
|
||||||
| Annotation | Limitations / Notes |
|
| Annotation | Limitations / Notes |
|
||||||
|-------------------------------------------------------|--------------------------------------------------------------------------------------------|
|
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
|
||||||
| <a id="opt-nginx-ingress-kubernetes-iossl-redirect" href="#opt-nginx-ingress-kubernetes-iossl-redirect" title="#opt-nginx-ingress-kubernetes-iossl-redirect">`nginx.ingress.kubernetes.io/ssl-redirect`</a> | Cannot opt-out per route if enabled globally. |
|
| <a id="opt-nginx-ingress-kubernetes-iossl-redirect" href="#opt-nginx-ingress-kubernetes-iossl-redirect" title="#opt-nginx-ingress-kubernetes-iossl-redirect">`nginx.ingress.kubernetes.io/ssl-redirect`</a> | Cannot opt-out per route if enabled globally. |
|
||||||
| <a id="opt-nginx-ingress-kubernetes-ioforce-ssl-redirect" href="#opt-nginx-ingress-kubernetes-ioforce-ssl-redirect" title="#opt-nginx-ingress-kubernetes-ioforce-ssl-redirect">`nginx.ingress.kubernetes.io/force-ssl-redirect`</a> | Cannot opt-out per route if enabled globally. |
|
| <a id="opt-nginx-ingress-kubernetes-ioforce-ssl-redirect" href="#opt-nginx-ingress-kubernetes-ioforce-ssl-redirect" title="#opt-nginx-ingress-kubernetes-ioforce-ssl-redirect">`nginx.ingress.kubernetes.io/force-ssl-redirect`</a> | Cannot opt-out per route if enabled globally. |
|
||||||
| <a id="opt-nginx-ingress-kubernetes-iossl-passthrough" href="#opt-nginx-ingress-kubernetes-iossl-passthrough" title="#opt-nginx-ingress-kubernetes-iossl-passthrough">`nginx.ingress.kubernetes.io/ssl-passthrough`</a> | Some differences in SNI/default backend handling. |
|
| <a id="opt-nginx-ingress-kubernetes-iossl-passthrough" href="#opt-nginx-ingress-kubernetes-iossl-passthrough" title="#opt-nginx-ingress-kubernetes-iossl-passthrough">`nginx.ingress.kubernetes.io/ssl-passthrough`</a> | Some differences in SNI/default backend handling. |
|
||||||
@@ -276,6 +276,8 @@ The following annotations are organized by category for easier navigation.
|
|||||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-ssl-name" href="#opt-nginx-ingress-kubernetes-ioproxy-ssl-name" title="#opt-nginx-ingress-kubernetes-ioproxy-ssl-name">`nginx.ingress.kubernetes.io/proxy-ssl-name`</a> | |
|
| <a id="opt-nginx-ingress-kubernetes-ioproxy-ssl-name" href="#opt-nginx-ingress-kubernetes-ioproxy-ssl-name" title="#opt-nginx-ingress-kubernetes-ioproxy-ssl-name">`nginx.ingress.kubernetes.io/proxy-ssl-name`</a> | |
|
||||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-ssl-verify" href="#opt-nginx-ingress-kubernetes-ioproxy-ssl-verify" title="#opt-nginx-ingress-kubernetes-ioproxy-ssl-verify">`nginx.ingress.kubernetes.io/proxy-ssl-verify`</a> | |
|
| <a id="opt-nginx-ingress-kubernetes-ioproxy-ssl-verify" href="#opt-nginx-ingress-kubernetes-ioproxy-ssl-verify" title="#opt-nginx-ingress-kubernetes-ioproxy-ssl-verify">`nginx.ingress.kubernetes.io/proxy-ssl-verify`</a> | |
|
||||||
| <a id="opt-nginx-ingress-kubernetes-ioproxy-ssl-secret" href="#opt-nginx-ingress-kubernetes-ioproxy-ssl-secret" title="#opt-nginx-ingress-kubernetes-ioproxy-ssl-secret">`nginx.ingress.kubernetes.io/proxy-ssl-secret`</a> | |
|
| <a id="opt-nginx-ingress-kubernetes-ioproxy-ssl-secret" href="#opt-nginx-ingress-kubernetes-ioproxy-ssl-secret" title="#opt-nginx-ingress-kubernetes-ioproxy-ssl-secret">`nginx.ingress.kubernetes.io/proxy-ssl-secret`</a> | |
|
||||||
|
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-secret" href="#opt-nginx-ingress-kubernetes-ioauth-tls-secret" title="#opt-nginx-ingress-kubernetes-ioauth-tls-secret">`nginx.ingress.kubernetes.io/auth-tls-secret`</a> | When validation fails, the rejection happens during the TLS handshake rather than returning a 400 Bad Request. |
|
||||||
|
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-verify-client" href="#opt-nginx-ingress-kubernetes-ioauth-tls-verify-client" title="#opt-nginx-ingress-kubernetes-ioauth-tls-verify-client">`nginx.ingress.kubernetes.io/auth-tls-verify-client`</a> | When validation fails, the rejection happens during the TLS handshake rather than returning a 400 Bad Request. |
|
||||||
|
|
||||||
### Session Affinity
|
### Session Affinity
|
||||||
|
|
||||||
@@ -363,10 +365,8 @@ The following annotations are organized by category for easier navigation.
|
|||||||
|
|
||||||
| Annotation | Notes |
|
| Annotation | Notes |
|
||||||
|-----------------------------------------------------------------------------|------------------------------------------------------|
|
|-----------------------------------------------------------------------------|------------------------------------------------------|
|
||||||
| <a id="opt-nginx-ingress-kubernetes-ioaffinity-canary-behavior" href="#opt-nginx-ingress-kubernetes-ioaffinity-canary-behavior" title="#opt-nginx-ingress-kubernetes-ioaffinity-canary-behavior">`nginx.ingress.kubernetes.io/affinity-canary-behavior`</a> | |
|
| <a id="opt-nginx-ingress-kubernetes-ioaffinity-canary-behavior" href="#opt-nginx-ingress-kubernetes-ioaffinity-canary-behavior" title="#opt-nginx-ingress-kubernetes-ioaffinity-canary-behavior">`nginx.ingress.kubernetes.io/affinity-canary-behavior`</a> | | |
|
||||||
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-secret" href="#opt-nginx-ingress-kubernetes-ioauth-tls-secret" title="#opt-nginx-ingress-kubernetes-ioauth-tls-secret">`nginx.ingress.kubernetes.io/auth-tls-secret`</a> | |
|
|
||||||
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-verify-depth" href="#opt-nginx-ingress-kubernetes-ioauth-tls-verify-depth" title="#opt-nginx-ingress-kubernetes-ioauth-tls-verify-depth">`nginx.ingress.kubernetes.io/auth-tls-verify-depth`</a> | |
|
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-verify-depth" href="#opt-nginx-ingress-kubernetes-ioauth-tls-verify-depth" title="#opt-nginx-ingress-kubernetes-ioauth-tls-verify-depth">`nginx.ingress.kubernetes.io/auth-tls-verify-depth`</a> | |
|
||||||
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-verify-client" href="#opt-nginx-ingress-kubernetes-ioauth-tls-verify-client" title="#opt-nginx-ingress-kubernetes-ioauth-tls-verify-client">`nginx.ingress.kubernetes.io/auth-tls-verify-client`</a> | |
|
|
||||||
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-error-page" href="#opt-nginx-ingress-kubernetes-ioauth-tls-error-page" title="#opt-nginx-ingress-kubernetes-ioauth-tls-error-page">`nginx.ingress.kubernetes.io/auth-tls-error-page`</a> | |
|
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-error-page" href="#opt-nginx-ingress-kubernetes-ioauth-tls-error-page" title="#opt-nginx-ingress-kubernetes-ioauth-tls-error-page">`nginx.ingress.kubernetes.io/auth-tls-error-page`</a> | |
|
||||||
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-pass-certificate-to-upstream" href="#opt-nginx-ingress-kubernetes-ioauth-tls-pass-certificate-to-upstream" title="#opt-nginx-ingress-kubernetes-ioauth-tls-pass-certificate-to-upstream">`nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream`</a> | |
|
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-pass-certificate-to-upstream" href="#opt-nginx-ingress-kubernetes-ioauth-tls-pass-certificate-to-upstream" title="#opt-nginx-ingress-kubernetes-ioauth-tls-pass-certificate-to-upstream">`nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream`</a> | |
|
||||||
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-match-cn" href="#opt-nginx-ingress-kubernetes-ioauth-tls-match-cn" title="#opt-nginx-ingress-kubernetes-ioauth-tls-match-cn">`nginx.ingress.kubernetes.io/auth-tls-match-cn`</a> | |
|
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-match-cn" href="#opt-nginx-ingress-kubernetes-ioauth-tls-match-cn" title="#opt-nginx-ingress-kubernetes-ioauth-tls-match-cn">`nginx.ingress.kubernetes.io/auth-tls-match-cn`</a> | |
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ type ingressConfig struct {
|
|||||||
AuthSignin *string `annotation:"nginx.ingress.kubernetes.io/auth-signin"`
|
AuthSignin *string `annotation:"nginx.ingress.kubernetes.io/auth-signin"`
|
||||||
AuthResponseHeaders *string `annotation:"nginx.ingress.kubernetes.io/auth-response-headers"`
|
AuthResponseHeaders *string `annotation:"nginx.ingress.kubernetes.io/auth-response-headers"`
|
||||||
|
|
||||||
|
AuthTLSSecret *string `annotation:"nginx.ingress.kubernetes.io/auth-tls-secret"`
|
||||||
|
AuthTLSVerifyClient *string `annotation:"nginx.ingress.kubernetes.io/auth-tls-verify-client"`
|
||||||
|
|
||||||
ForceSSLRedirect *bool `annotation:"nginx.ingress.kubernetes.io/force-ssl-redirect"`
|
ForceSSLRedirect *bool `annotation:"nginx.ingress.kubernetes.io/force-ssl-redirect"`
|
||||||
SSLRedirect *bool `annotation:"nginx.ingress.kubernetes.io/ssl-redirect"`
|
SSLRedirect *bool `annotation:"nginx.ingress.kubernetes.io/ssl-redirect"`
|
||||||
|
|
||||||
|
|||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: ingress-with-auth-tls-secret
|
||||||
|
namespace: default
|
||||||
|
annotations:
|
||||||
|
nginx.ingress.kubernetes.io/auth-tls-secret: "default/ca-secret"
|
||||||
|
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- auth-tls-secret.localhost
|
||||||
|
- secretName: whoami-tls
|
||||||
|
rules:
|
||||||
|
- host: auth-tls-secret.localhost
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Exact
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: whoami
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: ingress-with-auth-tls-verify-client
|
||||||
|
namespace: default
|
||||||
|
annotations:
|
||||||
|
nginx.ingress.kubernetes.io/auth-tls-secret: "default/ca-secret"
|
||||||
|
nginx.ingress.kubernetes.io/auth-tls-verify-client: "optional"
|
||||||
|
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- auth-tls-verify-client.localhost
|
||||||
|
- secretName: whoami-tls
|
||||||
|
rules:
|
||||||
|
- host: auth-tls-verify-client.localhost
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Exact
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: whoami
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
@@ -7,3 +7,13 @@ metadata:
|
|||||||
data:
|
data:
|
||||||
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t
|
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t
|
||||||
tls.key: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t
|
tls.key: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Secret
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
namespace: default
|
||||||
|
name: ca-secret
|
||||||
|
|
||||||
|
data:
|
||||||
|
ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t
|
||||||
@@ -267,6 +267,7 @@ func (p *Provider) loadConfiguration(ctx context.Context) *dynamic.Configuration
|
|||||||
ingresses := p.k8sClient.ListIngresses()
|
ingresses := p.k8sClient.ListIngresses()
|
||||||
|
|
||||||
uniqCerts := make(map[string]*tls.CertAndStores)
|
uniqCerts := make(map[string]*tls.CertAndStores)
|
||||||
|
tlsOptions := make(map[string]tls.Options)
|
||||||
for _, ingress := range ingresses {
|
for _, ingress := range ingresses {
|
||||||
logger := log.Ctx(ctx).With().Str("ingress", ingress.Name).Str("namespace", ingress.Namespace).Logger()
|
logger := log.Ctx(ctx).With().Str("ingress", ingress.Name).Str("namespace", ingress.Namespace).Logger()
|
||||||
ctxIngress := logger.WithContext(ctx)
|
ctxIngress := logger.WithContext(ctx)
|
||||||
@@ -294,6 +295,23 @@ func (p *Provider) loadConfiguration(ctx context.Context) *dynamic.Configuration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var clientAuthTLSOptionName string
|
||||||
|
if ingressConfig.AuthTLSSecret != nil {
|
||||||
|
tlsOptName := provider.Normalize(ingress.Namespace + "-" + ingress.Name + "-" + *ingressConfig.AuthTLSSecret)
|
||||||
|
|
||||||
|
if _, exists := tlsOptions[tlsOptName]; !exists {
|
||||||
|
tlsOpt, err := p.buildClientAuthTLSOption(ingress.Namespace, ingressConfig)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error().Err(err).Msg("Error configuring client auth TLS")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsOptions[tlsOptName] = tlsOpt
|
||||||
|
}
|
||||||
|
|
||||||
|
clientAuthTLSOptionName = tlsOptName
|
||||||
|
}
|
||||||
|
|
||||||
namedServersTransport, err := p.buildServersTransport(ingress.Namespace, ingress.Name, ingressConfig)
|
namedServersTransport, err := p.buildServersTransport(ingress.Namespace, ingress.Name, ingressConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error().Err(err).Msg("Ignoring Ingress cannot create proxy SSL configuration")
|
logger.Error().Err(err).Msg("Ignoring Ingress cannot create proxy SSL configuration")
|
||||||
@@ -336,6 +354,9 @@ func (p *Provider) loadConfiguration(ctx context.Context) *dynamic.Configuration
|
|||||||
Service: defaultBackendName,
|
Service: defaultBackendName,
|
||||||
TLS: &dynamic.RouterTLSConfig{},
|
TLS: &dynamic.RouterTLSConfig{},
|
||||||
}
|
}
|
||||||
|
if clientAuthTLSOptionName != "" {
|
||||||
|
rtTLS.TLS.Options = clientAuthTLSOptionName
|
||||||
|
}
|
||||||
|
|
||||||
if err := p.applyMiddlewares(ingress.Namespace, defaultBackendTLSName, "", ingressConfig, false, rtTLS, conf); err != nil {
|
if err := p.applyMiddlewares(ingress.Namespace, defaultBackendTLSName, "", ingressConfig, false, rtTLS, conf); err != nil {
|
||||||
logger.Error().Err(err).Msg("Error applying middlewares")
|
logger.Error().Err(err).Msg("Error applying middlewares")
|
||||||
@@ -427,6 +448,9 @@ func (p *Provider) loadConfiguration(ctx context.Context) *dynamic.Configuration
|
|||||||
Service: key,
|
Service: key,
|
||||||
TLS: &dynamic.RouterTLSConfig{},
|
TLS: &dynamic.RouterTLSConfig{},
|
||||||
}
|
}
|
||||||
|
if clientAuthTLSOptionName != "" {
|
||||||
|
rtTLS.TLS.Options = clientAuthTLSOptionName
|
||||||
|
}
|
||||||
|
|
||||||
if err := p.applyMiddlewares(ingress.Namespace, key+"-tls", "", ingressConfig, false, rtTLS, conf); err != nil {
|
if err := p.applyMiddlewares(ingress.Namespace, key+"-tls", "", ingressConfig, false, rtTLS, conf); err != nil {
|
||||||
logger.Error().Err(err).Msg("Error applying middlewares")
|
logger.Error().Err(err).Msg("Error applying middlewares")
|
||||||
@@ -481,6 +505,10 @@ func (p *Provider) loadConfiguration(ctx context.Context) *dynamic.Configuration
|
|||||||
}
|
}
|
||||||
if hasTLS {
|
if hasTLS {
|
||||||
rt.TLS = &dynamic.RouterTLSConfig{}
|
rt.TLS = &dynamic.RouterTLSConfig{}
|
||||||
|
|
||||||
|
if clientAuthTLSOptionName != "" {
|
||||||
|
rt.TLS.Options = clientAuthTLSOptionName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
routerKey := provider.Normalize(fmt.Sprintf("%s-%s-rule-%d-path-%d", ingress.Namespace, ingress.Name, ri, pi))
|
routerKey := provider.Normalize(fmt.Sprintf("%s-%s-rule-%d-path-%d", ingress.Namespace, ingress.Name, ri, pi))
|
||||||
@@ -502,6 +530,7 @@ func (p *Provider) loadConfiguration(ctx context.Context) *dynamic.Configuration
|
|||||||
|
|
||||||
conf.TLS = &dynamic.TLSConfiguration{
|
conf.TLS = &dynamic.TLSConfiguration{
|
||||||
Certificates: slices.Collect(maps.Values(uniqCerts)),
|
Certificates: slices.Collect(maps.Values(uniqCerts)),
|
||||||
|
Options: tlsOptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
return conf
|
return conf
|
||||||
@@ -1298,3 +1327,61 @@ func throttleEvents(ctx context.Context, throttleDuration time.Duration, pool *s
|
|||||||
|
|
||||||
return eventsChanBuffered
|
return eventsChanBuffered
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Provider) buildClientAuthTLSOption(ingressNamespace string, config ingressConfig) (tls.Options, error) {
|
||||||
|
secretParts := strings.SplitN(*config.AuthTLSSecret, "/", 2)
|
||||||
|
if len(secretParts) != 2 {
|
||||||
|
return tls.Options{}, errors.New("auth-tls-secret is not in a correct namespace/name format")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expected format: namespace/name.
|
||||||
|
secretNamespace := secretParts[0]
|
||||||
|
secretName := secretParts[1]
|
||||||
|
|
||||||
|
if secretNamespace == "" {
|
||||||
|
return tls.Options{}, errors.New("auth-tls-secret has empty namespace")
|
||||||
|
}
|
||||||
|
if secretName == "" {
|
||||||
|
return tls.Options{}, errors.New("auth-tls-secret has empty name")
|
||||||
|
}
|
||||||
|
// Cross-namespace secrets are not supported.
|
||||||
|
if secretNamespace != ingressNamespace {
|
||||||
|
return tls.Options{}, fmt.Errorf("cross-namespace auth-tls-secret is not supported: secret namespace %q does not match ingress namespace %q", secretNamespace, ingressNamespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
blocks, err := p.certificateBlocks(secretNamespace, secretName)
|
||||||
|
if err != nil {
|
||||||
|
return tls.Options{}, fmt.Errorf("reading client certificate: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if blocks.CA == nil {
|
||||||
|
return tls.Options{}, errors.New("secret does not contain a CA certificate")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default verifyClient value is "on" on ingress-nginx.
|
||||||
|
// on means that client certificate is required and must be signed by a trusted CA certificate.
|
||||||
|
clientAuthType := tls.RequireAndVerifyClientCert
|
||||||
|
if config.AuthTLSVerifyClient != nil {
|
||||||
|
switch *config.AuthTLSVerifyClient {
|
||||||
|
// off means that client certificate is not requested and no verification will be passed.
|
||||||
|
case "off":
|
||||||
|
clientAuthType = tls.NoClientCert
|
||||||
|
// optional means that the client certificate is requested, but not required.
|
||||||
|
// If the certificate is present, it needs to be verified.
|
||||||
|
case "optional":
|
||||||
|
clientAuthType = tls.VerifyClientCertIfGiven
|
||||||
|
// optional_no_ca means that the client certificate is requested, but does not require it to be signed by a trusted CA certificate.
|
||||||
|
case "optional_no_ca":
|
||||||
|
clientAuthType = tls.RequestClientCert
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsOpt := tls.Options{}
|
||||||
|
tlsOpt.SetDefaults()
|
||||||
|
tlsOpt.ClientAuth = tls.ClientAuth{
|
||||||
|
CAFiles: []types.FileOrContent{*blocks.CA},
|
||||||
|
ClientAuthType: clientAuthType,
|
||||||
|
}
|
||||||
|
|
||||||
|
return tlsOpt, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-acme/lego/v4/challenge/tlsalpn01"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
ptypes "github.com/traefik/paerser/types"
|
ptypes "github.com/traefik/paerser/types"
|
||||||
@@ -46,7 +47,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
Services: map[string]*dynamic.Service{},
|
Services: map[string]*dynamic.Service{},
|
||||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -105,7 +108,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -182,6 +187,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -244,7 +250,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -305,7 +313,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -452,6 +462,7 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -496,7 +507,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
Services: map[string]*dynamic.Service{},
|
Services: map[string]*dynamic.Service{},
|
||||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -561,7 +574,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -617,7 +632,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -681,7 +698,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -730,7 +749,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -789,7 +810,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -841,7 +864,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -901,7 +926,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -961,7 +988,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1013,7 +1042,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1066,7 +1097,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1125,7 +1158,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1184,7 +1219,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1243,7 +1280,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1296,7 +1335,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1357,7 +1398,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1418,7 +1461,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1479,7 +1524,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1540,7 +1587,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1601,7 +1650,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1662,7 +1713,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1723,7 +1776,9 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1771,7 +1826,216 @@ func TestLoadIngresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TLS: &dynamic.TLSConfiguration{},
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Options: map[string]tls.Options{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "Auth TLS secret",
|
||||||
|
paths: []string{
|
||||||
|
"services.yml",
|
||||||
|
"secrets.yml",
|
||||||
|
"ingressclasses.yml",
|
||||||
|
"ingresses/20-ingress-with-auth-tls-secret.yml",
|
||||||
|
},
|
||||||
|
expected: &dynamic.Configuration{
|
||||||
|
TCP: &dynamic.TCPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.TCPRouter{},
|
||||||
|
Services: map[string]*dynamic.TCPService{},
|
||||||
|
},
|
||||||
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.Router{
|
||||||
|
"default-ingress-with-auth-tls-secret-rule-0-path-0": {
|
||||||
|
Rule: "Host(`auth-tls-secret.localhost`) && Path(`/`)",
|
||||||
|
RuleSyntax: "default",
|
||||||
|
Service: "default-ingress-with-auth-tls-secret-whoami-80",
|
||||||
|
TLS: &dynamic.RouterTLSConfig{
|
||||||
|
Options: "default-ingress-with-auth-tls-secret-default-ca-secret",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"default-ingress-with-auth-tls-secret-rule-0-path-0-http": {
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Rule: "Host(`auth-tls-secret.localhost`) && Path(`/`)",
|
||||||
|
RuleSyntax: "default",
|
||||||
|
Middlewares: []string{"default-ingress-with-auth-tls-secret-rule-0-path-0-redirect-scheme"},
|
||||||
|
Service: "noop@internal",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Middlewares: map[string]*dynamic.Middleware{
|
||||||
|
"default-ingress-with-auth-tls-secret-rule-0-path-0-redirect-scheme": {
|
||||||
|
RedirectScheme: &dynamic.RedirectScheme{
|
||||||
|
Scheme: "https",
|
||||||
|
ForcePermanentRedirect: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Services: map[string]*dynamic.Service{
|
||||||
|
"default-ingress-with-auth-tls-secret-whoami-80": {
|
||||||
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||||
|
Servers: []dynamic.Server{
|
||||||
|
{
|
||||||
|
URL: "http://10.10.0.1:80",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
URL: "http://10.10.0.2:80",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Strategy: "wrr",
|
||||||
|
PassHostHeader: ptr.To(true),
|
||||||
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||||
|
FlushInterval: dynamic.DefaultFlushInterval,
|
||||||
|
},
|
||||||
|
ServersTransport: "default-ingress-with-auth-tls-secret",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{
|
||||||
|
"default-ingress-with-auth-tls-secret": {
|
||||||
|
ForwardingTimeouts: &dynamic.ForwardingTimeouts{
|
||||||
|
DialTimeout: ptypes.Duration(60 * time.Second),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Certificates: []*tls.CertAndStores{
|
||||||
|
{
|
||||||
|
Certificate: tls.Certificate{
|
||||||
|
CertFile: "-----BEGIN CERTIFICATE-----",
|
||||||
|
KeyFile: "-----BEGIN CERTIFICATE-----",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Options: map[string]tls.Options{
|
||||||
|
"default-ingress-with-auth-tls-secret-default-ca-secret": {
|
||||||
|
ClientAuth: tls.ClientAuth{
|
||||||
|
CAFiles: []types.FileOrContent{"-----BEGIN CERTIFICATE-----"},
|
||||||
|
ClientAuthType: "RequireAndVerifyClientCert",
|
||||||
|
},
|
||||||
|
CipherSuites: []string{
|
||||||
|
"TLS_AES_128_GCM_SHA256",
|
||||||
|
"TLS_AES_256_GCM_SHA384",
|
||||||
|
"TLS_CHACHA20_POLY1305_SHA256",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
|
||||||
|
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
|
||||||
|
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
||||||
|
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
|
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
||||||
|
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
|
||||||
|
},
|
||||||
|
ALPNProtocols: []string{"h2", "http/1.1", tlsalpn01.ACMETLS1Protocol},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
desc: "Auth TLS verify client",
|
||||||
|
paths: []string{
|
||||||
|
"services.yml",
|
||||||
|
"secrets.yml",
|
||||||
|
"ingressclasses.yml",
|
||||||
|
"ingresses/21-ingress-with-auth-tls-verify-client.yml",
|
||||||
|
},
|
||||||
|
expected: &dynamic.Configuration{
|
||||||
|
TCP: &dynamic.TCPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.TCPRouter{},
|
||||||
|
Services: map[string]*dynamic.TCPService{},
|
||||||
|
},
|
||||||
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.Router{
|
||||||
|
"default-ingress-with-auth-tls-verify-client-rule-0-path-0": {
|
||||||
|
Rule: "Host(`auth-tls-verify-client.localhost`) && Path(`/`)",
|
||||||
|
RuleSyntax: "default",
|
||||||
|
Service: "default-ingress-with-auth-tls-verify-client-whoami-80",
|
||||||
|
TLS: &dynamic.RouterTLSConfig{
|
||||||
|
Options: "default-ingress-with-auth-tls-verify-client-default-ca-secret",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"default-ingress-with-auth-tls-verify-client-rule-0-path-0-http": {
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Rule: "Host(`auth-tls-verify-client.localhost`) && Path(`/`)",
|
||||||
|
RuleSyntax: "default",
|
||||||
|
Middlewares: []string{"default-ingress-with-auth-tls-verify-client-rule-0-path-0-redirect-scheme"},
|
||||||
|
Service: "noop@internal",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Middlewares: map[string]*dynamic.Middleware{
|
||||||
|
"default-ingress-with-auth-tls-verify-client-rule-0-path-0-redirect-scheme": {
|
||||||
|
RedirectScheme: &dynamic.RedirectScheme{
|
||||||
|
Scheme: "https",
|
||||||
|
ForcePermanentRedirect: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Services: map[string]*dynamic.Service{
|
||||||
|
"default-ingress-with-auth-tls-verify-client-whoami-80": {
|
||||||
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||||
|
Servers: []dynamic.Server{
|
||||||
|
{
|
||||||
|
URL: "http://10.10.0.1:80",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
URL: "http://10.10.0.2:80",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Strategy: "wrr",
|
||||||
|
PassHostHeader: ptr.To(true),
|
||||||
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||||
|
FlushInterval: dynamic.DefaultFlushInterval,
|
||||||
|
},
|
||||||
|
ServersTransport: "default-ingress-with-auth-tls-verify-client",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ServersTransports: map[string]*dynamic.ServersTransport{
|
||||||
|
"default-ingress-with-auth-tls-verify-client": {
|
||||||
|
ForwardingTimeouts: &dynamic.ForwardingTimeouts{
|
||||||
|
DialTimeout: ptypes.Duration(60 * time.Second),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TLS: &dynamic.TLSConfiguration{
|
||||||
|
Certificates: []*tls.CertAndStores{
|
||||||
|
{
|
||||||
|
Certificate: tls.Certificate{
|
||||||
|
CertFile: "-----BEGIN CERTIFICATE-----",
|
||||||
|
KeyFile: "-----BEGIN CERTIFICATE-----",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Options: map[string]tls.Options{
|
||||||
|
"default-ingress-with-auth-tls-verify-client-default-ca-secret": {
|
||||||
|
ClientAuth: tls.ClientAuth{
|
||||||
|
CAFiles: []types.FileOrContent{"-----BEGIN CERTIFICATE-----"},
|
||||||
|
ClientAuthType: "VerifyClientCertIfGiven",
|
||||||
|
},
|
||||||
|
CipherSuites: []string{
|
||||||
|
"TLS_AES_128_GCM_SHA256",
|
||||||
|
"TLS_AES_256_GCM_SHA384",
|
||||||
|
"TLS_CHACHA20_POLY1305_SHA256",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
|
||||||
|
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
|
||||||
|
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
||||||
|
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
|
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
||||||
|
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
|
||||||
|
},
|
||||||
|
ALPNProtocols: []string{"h2", "http/1.1", tlsalpn01.ACMETLS1Protocol},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,30 @@ import "github.com/traefik/traefik/v3/pkg/types"
|
|||||||
|
|
||||||
const certificateHeader = "-----BEGIN CERTIFICATE-----\n"
|
const certificateHeader = "-----BEGIN CERTIFICATE-----\n"
|
||||||
|
|
||||||
|
const (
|
||||||
|
// NoClientCert indicates that no client certificate should be requested
|
||||||
|
// during the handshake, and if any certificates are sent they will not
|
||||||
|
// be verified.
|
||||||
|
NoClientCert = "NoClientCert"
|
||||||
|
// RequestClientCert indicates that a client certificate should be requested
|
||||||
|
// during the handshake, but does not require that the client send any
|
||||||
|
// certificates.
|
||||||
|
RequestClientCert = "RequestClientCert"
|
||||||
|
// RequireAnyClientCert indicates that a client certificate should be requested
|
||||||
|
// during the handshake, and that at least one certificate is required to be
|
||||||
|
// sent by the client, but that certificate is not required to be valid.
|
||||||
|
RequireAnyClientCert = "RequireAnyClientCert"
|
||||||
|
// VerifyClientCertIfGiven indicates that a client certificate should be requested
|
||||||
|
// during the handshake, but does not require that the client sends a
|
||||||
|
// certificate. If the client does send a certificate it is required to be
|
||||||
|
// valid.
|
||||||
|
VerifyClientCertIfGiven = "VerifyClientCertIfGiven"
|
||||||
|
// RequireAndVerifyClientCert indicates that a client certificate should be requested
|
||||||
|
// during the handshake, and that at least one valid certificate is required
|
||||||
|
// to be sent by the client.
|
||||||
|
RequireAndVerifyClientCert = "RequireAndVerifyClientCert"
|
||||||
|
)
|
||||||
|
|
||||||
// +k8s:deepcopy-gen=true
|
// +k8s:deepcopy-gen=true
|
||||||
|
|
||||||
// ClientAuth defines the parameters of the client authentication part of the TLS connection, if any.
|
// ClientAuth defines the parameters of the client authentication part of the TLS connection, if any.
|
||||||
|
|||||||
@@ -460,15 +460,15 @@ func buildTLSConfig(tlsOption Options) (*tls.Config, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch clientAuthType {
|
switch clientAuthType {
|
||||||
case "NoClientCert":
|
case NoClientCert:
|
||||||
conf.ClientAuth = tls.NoClientCert
|
conf.ClientAuth = tls.NoClientCert
|
||||||
case "RequestClientCert":
|
case RequestClientCert:
|
||||||
conf.ClientAuth = tls.RequestClientCert
|
conf.ClientAuth = tls.RequestClientCert
|
||||||
case "RequireAnyClientCert":
|
case RequireAnyClientCert:
|
||||||
conf.ClientAuth = tls.RequireAnyClientCert
|
conf.ClientAuth = tls.RequireAnyClientCert
|
||||||
case "VerifyClientCertIfGiven":
|
case VerifyClientCertIfGiven:
|
||||||
conf.ClientAuth = tls.VerifyClientCertIfGiven
|
conf.ClientAuth = tls.VerifyClientCertIfGiven
|
||||||
case "RequireAndVerifyClientCert":
|
case RequireAndVerifyClientCert:
|
||||||
conf.ClientAuth = tls.RequireAndVerifyClientCert
|
conf.ClientAuth = tls.RequireAndVerifyClientCert
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unknown client auth type %q", clientAuthType)
|
return nil, fmt.Errorf("unknown client auth type %q", clientAuthType)
|
||||||
|
|||||||
Reference in New Issue
Block a user