My use case is that we want to have 2 TLSOptions. One enforces client cert verification (MTLS), while the other does not.
We are setting the former as default - i.e. we are checking client certs by default. So in the case we dont want a particular route to verify client certs, we should be able to associate our latter TLSOption with the httproute, which will not check client certs.
I see that, in the case of ingress routes, we can add an annotation to force the route to use a given TLSOption: traefik.ingress.kubernetes.io/router.tls.options: traefik-nomtls@kubernetescrd
Is there any such way to force an httproute to use a particular TLSOption?
1 Like
Hello Folks!
I have the same problem, just I'd also like to use a Middleware in addition to pass the client cert to the same backend service. I'm using traefik helm chart 35.1.0 with app version v3.3.6.
my traefik values.yaml:
providers:
kubernetesIngress:
enabled: false
# Enable the GatewayAPI provider
kubernetesGateway:
enabled: true
kubernetesCRD:
enabled: true
gateway:
# -- When providers.kubernetesGateway.enabled, deploy a default gateway
enabled: false
gatewayClass:
# -- When providers.kubernetesGateway.enabled and gateway.enabled, deploy a default gatewayClass
enabled: true
# -- Set a custom name to GatewayClass
name: gwc-provided-by-traefik
# -- Additional gatewayClass labels (e.g. for filtering gateway objects by custom labels)
labels: {}
ports:
web:
## -- Enable this entrypoint as a default entrypoint. When a service doesn't explicitly set an entrypoint it will only use this entrypoint.
# asDefault: true
port: 8000
websecure:
## -- Enable this entrypoint as a default entrypoint. When a service doesn't explicitly set an entrypoint it will only use this entrypoint.
# asDefault: true
port: 8443
# -- One can apply Middlewares on an entrypoint
# https://doc.traefik.io/traefik/middlewares/overview/
# https://doc.traefik.io/traefik/routing/entrypoints/#middlewares
# -- /!\ It introduces here a link between your static configuration and your dynamic configuration /!\
# It follows the provider naming convention: https://doc.traefik.io/traefik/providers/overview/#provider-namespace
# - namespace-name1@kubernetescrd
# - namespace-name2@kubernetescrd
middlewares: [] # have to add mtls-middleware here as well? not helm friendly
My gateway:
# Gateway
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
namespace: my-gateway-namespace
spec:
gatewayClassName: gwc-provided-by-traefik
listeners:
- name: http
port: 8000
protocol: HTTP
hostname: {{ printf "*.%s" .Values.domain | quote }}
allowedRoutes:
namespaces:
from: All
- name: https
port: 8443
protocol: HTTPS
hostname: {{ printf "*.%s" .Values.domain | quote }}
allowedRoutes:
namespaces:
from: All
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: {{ printf "%s-%s" .Values.environment.name .Values.domain | replace "." "-" }}
group: ""
namespace: my-gateway-namespace
## https://gateway-api.sigs.k8s.io/reference/spec/#gatewaytlsconfig states:
## FrontendValidation holds configuration information for validating the frontend (client).Setting this field will require clients to send a client certificate required for validation during the TLS handshake. In browsers this may result in a dialog appearing that requests a user to specify the client certificate...
## Still in Proposed status: https://gateway-api.sigs.k8s.io/geps/gep-2907/#1-validate-client-certificate-provided-by-frontend
# frontendValidation:
# caCertificateRefs:
# - kind: Secret
# name: I dont want to use this though since the "RequireAnyClientCert"
# group: ""
# namespace: my-gateway-namespace
My HTTPRoute, TLSOption and Middleware:
# HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-httproute
namespace: my-namespace
# annotations:
# traefik.ingress.kubernetes.io/router.tls.options: my-namespace-mtls-options@kubernetescrd
# traefik.ingress.kubernetes.io/router.middlewares: my-namespace-mtls-middleware@kubernetescrd
spec:
parentRefs:
- name: my-gateway
namespace: my-gateway-namespace
# ...hostnames for this route...
rules:
- matches:
- path:
type: PathPrefix
value: /path
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
- type: ExtensionRef
extensionRef:
group: traefik.io
kind: Middleware
name: mtls-middleware
backendRefs:
- name: my-backend
namespace: my-namespace
port: 80
---
# TLSOption for mTLS
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: mtls-options
namespace: my-namespace
spec:
clientAuth:
# requires a certificate but does not verify if it is signed by a CA listed in clientAuth.caFiles or in clientAuth.secretNames
clientAuthType: RequireAnyClientCert
secretNames:
# traefik pod logs a warning, but I wouldn't expect it to cause any issues due to the lack of cert verification
- not-used-does-not-exist
---
# Middleware for mTLS
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: mtls-middleware
namespace: my-namespace
spec:
passTLSClientCert:
pem: true
I've tried several combinations besides the above configs, eg. enabling ingress in the values.yaml, using the commented annotations, etc...
Effect: client cert not required, and in case I force use one with curl, its PEM content not getting forwarded.
If I name the TLSOption to default
, it works as expected. (w/ chart v35.2.0)