# Authorize with X509 client cert and include cert info in Header of non-TLS service

**URL:** <https://community.traefik.io/t/authorize-with-x509-client-cert-and-include-cert-info-in-header-of-non-tls-service/784>\
**Category:** Traefik v2\
**Tags:** file\
**Created:** [July 4, 2019, 11:35am UTC](https://community.traefik.io/t/authorize-with-x509-client-cert-and-include-cert-info-in-header-of-non-tls-service/784 "2019-07-04T11:35:44Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![harenber](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/harenber/32/419_2.png) [@harenber](https://community.traefik.io/u/harenber)\
**Post date:** [July 4, 2019, 11:35am UTC](https://community.traefik.io/t/authorize-with-x509-client-cert-and-include-cert-info-in-header-of-non-tls-service/784/1 "2019-07-04T11:35:44Z")

</div>

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:

```auto
[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!

---

<div class="post-metadata">

**Author:** ![jbd](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/jbd/32/341_2.png) [@jbd](https://community.traefik.io/u/jbd)\
**Post date:** [July 4, 2019, 12:46pm UTC](https://community.traefik.io/t/authorize-with-x509-client-cert-and-include-cert-info-in-header-of-non-tls-service/784/2 "2019-07-04T12:46:21Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![harenber](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/harenber/32/419_2.png) [@harenber](https://community.traefik.io/u/harenber)\
**Post date:** [July 4, 2019, 12:50pm UTC](https://community.traefik.io/t/authorize-with-x509-client-cert-and-include-cert-info-in-header-of-non-tls-service/784/3 "2019-07-04T12:50:10Z")

</div>

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](https://docs.traefik.io/v2.0/middlewares/passtlsclientcert/) is exacly this feature.

Hope that is clearer??

Thanks!!!

---

<div class="post-metadata">

**Author:** ![jbd](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/jbd/32/341_2.png) [@jbd](https://community.traefik.io/u/jbd)\
**Post date:** [July 4, 2019, 2:10pm UTC](https://community.traefik.io/t/authorize-with-x509-client-cert-and-include-cert-info-in-header-of-non-tls-service/784/4 "2019-07-04T14:10:18Z")

</div>

Ok, let's try this simple v2 configuration :

```auto
# 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](https://docs.traefik.io/v2.0/middlewares/passtlsclientcert/).

---

<div class="post-metadata">

**Author:** ![harenber](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/harenber/32/419_2.png) [@harenber](https://community.traefik.io/u/harenber)\
**Post date:** [July 5, 2019, 11:07am UTC](https://community.traefik.io/t/authorize-with-x509-client-cert-and-include-cert-info-in-header-of-non-tls-service/784/5 "2019-07-05T11:07:28Z")

</div>

Wow.. Thanks @jbd . Works like a charm 🙂 That was exactly what I was looking for.

---

<div class="post-metadata">

**Author:** ![dash042](https://avatars.discourse-cdn.com/v4/letter/d/7ab992/32.png) [@dash042](https://community.traefik.io/u/dash042)\
**Post date:** [October 25, 2019, 1:46pm UTC](https://community.traefik.io/t/authorize-with-x509-client-cert-and-include-cert-info-in-header-of-non-tls-service/784/6 "2019-10-25T13:46:06Z")

</div>

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:

```auto
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):

```auto
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:

```auto
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:

```auto
# 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

```

---

<div class="post-metadata">

**Author:** ![dash042](https://avatars.discourse-cdn.com/v4/letter/d/7ab992/32.png) [@dash042](https://community.traefik.io/u/dash042)\
**Post date:** [October 25, 2019, 5:07pm UTC](https://community.traefik.io/t/authorize-with-x509-client-cert-and-include-cert-info-in-header-of-non-tls-service/784/7 "2019-10-25T17:07:01Z")

</div>

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!)

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex020/uploads/containo/original/2X/b/bd81ebdb578656e76e56ff3cc3eed021d3ba132d.png) [@system](https://community.traefik.io/u/system)\
**Post date:** [October 8, 2020, 1:35pm UTC](https://community.traefik.io/t/authorize-with-x509-client-cert-and-include-cert-info-in-header-of-non-tls-service/784/8 "2020-10-08T13:35:37Z")

</div>

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.
