Dear all,
I am scratching my head if this is possible.
I am trying to configure traefik that is
Listens to a SSL enabled port
asks for a X509 client cert
forward the information of this client certificate to the backend.
I tried with v1 and now with v2 but couldn't get it to run. My current traefik.toms looks like this:
[global]
checkNewVersion = false
sendAnonymousUsage = false
[log]
level="DEBUG"
[accessLog]
[entryPoints]
[entryPoints.https]
address = ":443"
[entryPoints.achtzwei]
address = ":8082"
[entryPoints.achtzwei.forwardedHeaders]
insecure = true
[providers.file]
[tls]
[tls.options]
[tls.options.default]
[tls.options.default.clientCA]
# in PEM format. each file can contain multiple CAs.
#files = ["tests/clientca1.crt", "tests/clientca2.crt"]
optional = true
[http]
[http.routers]
[http.routers.router0]
entryPoints="achtzwei"
middlewares="test-passtlsclientcert"
rule="Host(`XXX`)"
service="service1"
[http.routers.router0.tls]
options="default"
[http.services]
[http.services.service1.loadBalancer]
[[http.services.service1.loadBalancer.servers]]
url = "http://localhost:8080"
[http.middlewares]
[http.middlewares.test-passtlsclientcert]
[http.middlewares.test-passtlsclientcert.passTLSClientCert]
[http.middlewares.test-passtlsclientcert.passTLSClientCert.info]
notAfter = true
notBefore = true
sans = true
[http.middlewares.test-passtlsclientcert.passTLSClientCert.info.subject]
country = true
province = true
locality = true
organization = true
commonName = true
serialNumber = true
domainComponent = true
[http.middlewares.test-passtlsclientcert.passTLSClientCert.info.issuer]
country = true
province = true
locality = true
organization = true
commonName = true
serialNumber = true
domainComponent = true
[acme]
email = "XXX"
onHostRule = false
storage = "/tmp/acme.json"
entryPoint = "https"
[acme.tlsChallenge]
[[acme.domains]]
main = "XXX"
(hostname and mail address "XXX"ed).
But connecting to the created port 8082, I only get a 404 page not found and the request is not forwarded to the backend at all. Presenting the letsecrypt certificate, however, works ok.
I am somehow lost and hope someone has an idea.
Thanks a lot!
jbd
July 4, 2019, 12:46pm
2
Hi harenber,
I'm not sure to really understand your use case.
Do you want to pass the certificate given by let's encrypt to the backends?
Could you please provide us more details about your need?
Hi jbd,
no.. I want the user to authorize (log in) using a client certificate and want the DN of this certificate to be passed to the backend. I thought passTLSClientCert is exacly this feature.
Hope that is clearer??
Thanks!!!
jbd
July 4, 2019, 2:10pm
4
Ok, let's try this simple v2 configuration :
# static configuration
[global]
checkNewVersion = false
sendAnonymousUsage = false
[log]
level="DEBUG"
[api]
[entryPoints]
[entryPoints.https]
address = ":443"
[providers.file]
# dynamic configuration
[tls.options.default.clientCA]
files = ["/app/certs/ca/MyRootCA.pem"]
optional = true
[http.routers.router0]
middlewares=["test-passtlsclientcert"]
rule="Host(`XXX`)"
service="service1"
[http.routers.router0.tls]
[[http.services.service1.loadBalancer.servers]]
url = "http://10.0.1.12:80"
[http.middlewares.test-passtlsclientcert.passTLSClientCert.info]
notAfter = true
notBefore = true
sans = true
[http.middlewares.test-passtlsclientcert.passTLSClientCert.info.subject]
country = true
province = true
locality = true
organization = true
commonName = true
serialNumber = true
domainComponent = true
[http.middlewares.test-passtlsclientcert.passTLSClientCert.info.issuer]
country = true
province = true
locality = true
organization = true
commonName = true
serialNumber = true
domainComponent = true
I used the containous/whoami as backend and the following request:
curl -kvvv https://whoami --cert certs/client.pem --key certs/client.key
The request worked and I had a X-Forwarded-Tls-Client-Cert-Info
header with all the specified fields.
Note that the clientCA must be able to validate the certificate passed by the client.
I hope this will help you
For more details see the official documentation .
Wow.. Thanks @jbd . Works like a charm That was exactly what I was looking for.
1 Like
unfortunately for me - this isn't working.
i.e. - I can't get the certificate information to show up in "x-forwarded-tls-client-cert-info"
I am using the kubernetes-CRD and there are no examples on how to integrate the static file configuration or where to put the CA-certificate to validate against...
currently I have the following setup - where the file-config (supplied as configMap - as I had working with traefik 1.7) is not commented out:
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: kube-system
name: traefik
labels:
app: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
volumes:
- name: ssl
secret:
secretName: ssl
- name: config
configMap:
name: traefik-config
containers:
- name: traefik
image: traefik:v2.0.2
args:
- --api.insecure=true
- --api.dashboard=true
- --ping=true
- --log.level=INFO
- --accesslog
- --metrics.prometheus=true
- --metrics.prometheus.entryPoint=metrics
- --entrypoints.http.Address=:80
- --entrypoints.https.Address=:443
- --providers.kubernetescrd
- --providers.kubernetescrd.certauthfilepath="ssl/ca.crt"
# - --providers.file.directory=/config
# - --providers.file.filename=traefik.toml
# - --providers.file.watch=true
ports:
- name: http
containerPort: 80
- name: admin
containerPort: 8080
- name: https
containerPort: 443
volumeMounts:
- mountPath: "/ssl"
name: ssl
- mountPath: "/config"
name: config
My ingress routes contain a middleware for passing the certificate information (into x-forwarded-tls-client-cert-info - not infos(!) as with 1.7):
kind: Middleware
apiVersion: traefik.containo.us/v1alpha1
metadata:
name: passtlscert
namespace: default
spec:
passTLSClientCert: #add to the <<X-Forwarded-Tls-Client-Cert-Info>> header:
# pem: false
infos:
notafter: true
notbefore: true
sans: false
subject:
country: false
province: false
locality: false
commonname: true
serialnumber: false
domaincomponent: false
issuer:
country: false
province: false
locality: false
organization: false
commonname: false
serialnumber: false
domaincomponent: false
the TLSOption is like this:
apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
name: authtlsoption
namespace: default
spec:
minVersion: VersionTLS12
clientAuth:
caSecret: sslv2
secretNames:
- sslv2
clientAuthType: RequireAndVerifyClientCert
here there is very little documentation as to how this works in kubernetes... I'm pretty sure caSecret or secretNames should be a either-or...
lastly I put all this into the ingressroute definition like so:
# FRONTEND
kind: IngressRoute
apiVersion: traefik.containo.us/v1alpha1
metadata:
name: fe-ingress
namespace: default
spec:
entryPoints:
- https
routes:
- match: Host(`test.com`) && PathPrefix(`/`)
kind: Rule
services:
- name: fe
port: 443
middlewares:
- name: passtlscert
tls:
options:
name: authtlsoption
namespace: default
secretName: ssl
very simple solution to my own problem:
ADD "insecureSkipVerify=true" to deployment of traefik
CHANGE "passTLSClientCert" from "infos" as has been the traefik default so far - to "info" (singular!)
system
Closed
October 8, 2020, 1:35pm
8
This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.