Answers: <p>There is 4th way:</p>
  <ul>
  <li>Instruct Kube dashboard to use your CA cert (not self-generated ones):
  Delete kube dashboard own certs:</li>
  </ul>
  <pre><code>kubectl -n kubernetes-dashboard delete secret kubernetes-dashboard-certs  
  </code></pre>
  <ul>
  <li>Add cert from your CA: (note that the one of the dns name must be kubernetes-dashboard.kubernetes-dashboard.svc.cluster.local )</li>
  </ul>
  <pre><code>kubectl -n kubernetes-dashboard create secret tls kubernetes-dashboard-certs --cert=&lt;your cert open key pem&gt; --key=&lt;your cert private key&gt;
  </code></pre>
  <ul>
  <li>Edit kube dashboard deployment file for using your key:</li>
  </ul>
  <pre><code>kubectl edit -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.6.0/aio/deploy/recommended.yaml 
  </code></pre>
  <ul>
  <li>add tls-cert-file/tls-key-file to container spec as shown below:</li>
  </ul>
  <pre><code>      spec:
          containers:
          - args:
            - --auto-generate-certificates
            - --namespace=kubernetes-dashboard
            - --tls-cert-file=/tls.crt
            - --tls-key-file=/tls.key
  </code></pre>
  <ul>
  <li>Instruct Traefik to use your CA to check Kube dashboard certs (should go to kube-system namespace with key name ca.crt).</li>
  </ul>
  <pre><code>kubectl -n kube-system create secret generic &lt;yourca&gt; --from-file=ca.crt=&lt;your ca open pem key&gt;
  </code></pre>
  <ul>
  <li>Modify ServerTransport</li>
  </ul>
  <pre><code>---
  apiVersion: traefik.containo.us/v1alpha1
  kind: ServersTransport
  metadata:
    name: mytransport
    namespace: kube-system
  spec:
    serverName: kubernetes-dashboard.kubernetes-dashboard.svc.cluster.local
    rootCAsSecrets:
    - &lt;yourca&gt;
  </code></pre>
  <ul>
  <li>Use that transport in IngressRoute</li>
  </ul>
  <pre><code>---
  apiVersion: traefik.containo.us/v1alpha1
  kind: IngressRoute
  metadata:
    name: kube-dashboard
    namespace: kubernetes-dashboard
  spec:
  ...
  routes:
  ...
      services:
      - name: kubernetes-dashboard
        namespace: kubernetes-dashboard
        port: 443
        serversTransport: mytransport
  </code></pre>
  
Answers: CC BY-SA 4.0
Answers: 2022-06-15T14:14:58.727Z
Answers: 2023-04-04T12:30:58.157Z
Answers: 2023-04-04T12:30:58.157Z
Answers: barzog
Answers: <p>If you want to use <code>PathPrefix</code> to distinguish services, beware that you may need to strip the prefix.</p>
  <pre class="lang-yaml prettyprint-override"><code>apiVersion: traefik.containo.us/v1alpha1
  kind: ServersTransport
  metadata:
    name: skip-verify
    namespace: kube-system
  spec:
    insecureSkipVerify: true
  ---
  apiVersion: traefik.containo.us/v1alpha1
  kind: Middleware
  metadata:
    name: kubernetes-dashboard-strip-prefix
    namespace: kube-system
  spec:
    stripPrefix:
      prefixes:
        - /kubernetes-dashboard
  ---
  apiVersion: traefik.containo.us/v1alpha1
  kind: IngressRoute
  metadata:
    name: kubernetes-dashboard
    namespace: kube-system
  spec:
    entryPoints:
      - websecure
    routes:
      - match: PathPrefix(`/kubernetes-dashboard`)
        kind: Rule
        services:
          - name: kubernetes-dashboard
            port: 443
            serversTransport: skip-verify
        middlewares:
          - name: kubernetes-dashboard-strip-prefix
  </code></pre>
  
Answers: CC BY-SA 4.0
Answers: 2023-01-17T13:25:06.873Z
Answers: 2023-01-17T13:25:06.873Z
Answers: BubbleQuote
Answers: <p>There are multiple ways to expose Dashboard through traefik.</p>
  <ol>
  <li>Traefik terminates HTTPS from client and as client opens new HTTPS request to Dashboard. <br/></li>
  </ol>
  <pre><code>     +-------------+       HTTPS       +-------------+        HTTPS      +-------------+ 
       |  Client     -----(session 1)-----  Traefik    ------(session 2)---- Dashboard   | 
       +-------------+                   +-------------+                   +-------------+
  </code></pre>
  <p>This is what you are using. The problem with your configuration is, on second session, Traefik will verify Dashboard's TLS certificate. <br/>
  When Dashboard certificate is not signed by any of CA in Traefik list, it closes connection, then Dashboard raises error message.<br/>
  If you want to use this scenario, you need to skip Dashboard certificate verification, or add Dashboard certificate to Traefik list of trusted CA.<br/>
  Below configuration works by skipping Dashboard certificate verification.</p>
  <pre><code>    apiVersion: traefik.containo.us/v1alpha1
      kind: ServersTransport
      metadata:
        name: mytransport
        namespace: kube-system
      spec:
        serverName: &quot;k.example.com&quot;
        insecureSkipVerify: true
      ---
      apiVersion: traefik.containo.us/v1alpha1
      kind: IngressRoute
      metadata:
        name: dashboard-k8s
        namespace: kube-system
      spec:
        entryPoints:
          - websecure
        routes:
          - match: &quot;Host(`k.example.com`)&quot;
            kind: Rule
            services:
            - name: kubernetes-dashboard
              port: 443
              serversTransport: mytransport
        tls:
          secretName: k8s-dashboard-http-cert
  </code></pre>
  <ol start="2">
  <li>Traefik passes the TLS traffic to Dashboard without any processing.</li>
  </ol>
  <pre><code>     +-------------+                   +-------------+                   +-------------+ 
       |  Client     -------HTTPS-------Traefik(passthrough)---------------- Dashboard   | 
       +-------------+                   +-------------+                   +-------------+ 
  </code></pre>
  <p>In this scenario, Traefik does not do any TLS termination, the traffic passes as it is to Dashboard.<br/>
  This works for me.</p>
  <pre><code>    apiVersion: traefik.containo.us/v1alpha1
      kind: IngressRouteTCP
      metadata:
        name: dashboard-k8s
        namespace: kube-system
      spec:
        entryPoints:
          - websecure
        routes:
          - match: HostSNI(`k.example.com`)
            services:
            - name: kubernetes-dashboard
              namespace: kubernetes-dashboard
              port: 443
        tls:
          passthrough: true
  </code></pre>
  <ol start="3">
  <li>Traefik terminates HTTPS from client and open new plain HTTP request to Dashboard. <br/></li>
  </ol>
  <pre><code>     +-------------+                   +-------------+                   +-------------+ 
       |  Client     -------HTTPS---------  Traefik    ---------HTTP-------- Dashboard   | 
       +-------------+                   +-------------+                   +-------------+ 
  </code></pre>
  <p>In this scenario, Dashboard need to provide plain HTTP termination.<br />
  I am not sure whether Dashboard support it.</p>
  
Answers: CC BY-SA 4.0
Answers: 2022-03-09T18:32:34.553Z
Answers: Thank you!!!!!!
Answers: FooBar
Answers: CC BY-SA 4.0
Answers: 2024-02-25T20:21:05.637Z
Answers: This is a great answer thank you very much! Just a quick note for people that just want to expose the dashboard in an internal network with no SSL, option 2 is what you want. On that case be sure to remove any other regular k8s ingress you have and just use the IngressRouteTCP!
  I had one created before and took me forever to realize it was still using the regular ingress and not the traefik one.
Answers: danielfrg
Answers: CC BY-SA 4.0
Answers: 2021-07-27T06:42:27.077Z
Answers: 2021-07-27T06:42:27.077Z
Answers: opris
Body: <p>I'm configuring a kubernetes cluster (using microk8s) and cert-manager. Certificates work fine to traefik dashboard and to other sites but I have an issue with kubernates dashboard as it's already server via SSL (service is on port 443) and I currently expose a Let'sEncrypt certificate.</p>
  <p>When I try to reach the dashboard the dashboard's pod logs:</p>
  <pre><code>2021/06/17 07:43:20 http: TLS handshake error from 213.215.191.83:39484: remote error: tls: bad certificate
  2021/06/17 07:43:23 http: TLS handshake error from 213.215.191.83:39500: remote error: tls: bad certificate
  
  </code></pre>
  <p>The <code>IngressRoute</code> I'm using is:</p>
  <pre><code>apiVersion: traefik.containo.us/v1alpha1
  kind: IngressRoute
  metadata:
    name: dashboard-k8s
    namespace: kube-system
  spec:
    entryPoints:
      - websecure
    routes:
      - match: &quot;Host(`k.example.com`)&quot;
        kind: Rule
        services:
        - name: kubernetes-dashboard
          port: 443
    tls:
      secretName: k8s-dashboard-http-cert
  </code></pre>
  <p>I have no clear idea of how should SSL work in this scenario.
  Would it be safe to have dashboard served on 80 and SSL terminated on traefik?</p>
  
Tags: <kubernetes><traefik>
Title: SSL issue while reaching kubernetes dashboard
UserDisplayName: Alessandro Dentella
ThreadText: # SSL issue while reaching kubernetes dashboard
  
  (Asked by: username_0 on 2021-06-17)
  
  I'm configuring a kubernetes cluster (using microk8s) and cert-manager. Certificates work fine to traefik dashboard and to other sites but I have an issue with kubernates dashboard as it's already server via SSL (service is on port 443) and I currently expose a Let'sEncrypt certificate.
  
  When I try to reach the dashboard the dashboard's pod logs:
  
  ```
  2021/06/17 07:43:20 http: TLS handshake error from 213.215.191.83:39484: remote error: tls: bad certificate
  2021/06/17 07:43:23 http: TLS handshake error from 213.215.191.83:39500: remote error: tls: bad certificate
  
  ```
  
  The `IngressRoute` I'm using is:
  
  ```
  apiVersion: traefik.containo.us/v1alpha1
  kind: IngressRoute
  metadata:
    name: dashboard-k8s
    namespace: kube-system
  spec:
    entryPoints:
      - websecure
    routes:
      - match: "Host(`k.example.com`)"
        kind: Rule
        services:
        - name: kubernetes-dashboard
          port: 443
    tls:
      secretName: k8s-dashboard-http-cert
  
  ```
  
  I have no clear idea of how should SSL work in this scenario.
  Would it be safe to have dashboard served on 80 and SSL terminated on traefik?
  
  **Tags:** kubernetes, traefik
  
  
  ---
  
  ## 3 answers
  
  ### Answer by username_3 on 2021-07-27. Score: 7 | Accepted answer
  
  There are multiple ways to expose Dashboard through traefik.
  
  1. Traefik terminates HTTPS from client and as client opens new HTTPS request to Dashboard.
  
  ```
       +-------------+       HTTPS       +-------------+        HTTPS      +-------------+ 
       |  Client     -----(session 1)-----  Traefik    ------(session 2)---- Dashboard   | 
       +-------------+                   +-------------+                   +-------------+
  
  ```
  
  This is what you are using. The problem with your configuration is, on second session, Traefik will verify Dashboard's TLS certificate.   
  When Dashboard certificate is not signed by any of CA in Traefik list, it closes connection, then Dashboard raises error message.  
  If you want to use this scenario, you need to skip Dashboard certificate verification, or add Dashboard certificate to Traefik list of trusted CA.  
  Below configuration works by skipping Dashboard certificate verification.
  
  ```
      apiVersion: traefik.containo.us/v1alpha1
      kind: ServersTransport
      metadata:
        name: mytransport
        namespace: kube-system
      spec:
        serverName: "k.example.com"
        insecureSkipVerify: true
      ---
      apiVersion: traefik.containo.us/v1alpha1
      kind: IngressRoute
      metadata:
        name: dashboard-k8s
        namespace: kube-system
      spec:
        entryPoints:
          - websecure
        routes:
          - match: "Host(`k.example.com`)"
            kind: Rule
            services:
            - name: kubernetes-dashboard
              port: 443
              serversTransport: mytransport
        tls:
          secretName: k8s-dashboard-http-cert
  
  ```
  
  2. Traefik passes the TLS traffic to Dashboard without any processing.
  
  ```
       +-------------+                   +-------------+                   +-------------+ 
       |  Client     -------HTTPS-------Traefik(passthrough)---------------- Dashboard   | 
       +-------------+                   +-------------+                   +-------------+ 
  
  ```
  
  In this scenario, Traefik does not do any TLS termination, the traffic passes as it is to Dashboard.  
  This works for me.
  
  ```
      apiVersion: traefik.containo.us/v1alpha1
      kind: IngressRouteTCP
      metadata:
        name: dashboard-k8s
        namespace: kube-system
      spec:
        entryPoints:
          - websecure
        routes:
          - match: HostSNI(`k.example.com`)
            services:
            - name: kubernetes-dashboard
              namespace: kubernetes-dashboard
              port: 443
        tls:
          passthrough: true
  
  ```
  
  3. Traefik terminates HTTPS from client and open new plain HTTP request to Dashboard.
  
  ```
       +-------------+                   +-------------+                   +-------------+ 
       |  Client     -------HTTPS---------  Traefik    ---------HTTP-------- Dashboard   | 
       +-------------+                   +-------------+                   +-------------+ 
  
  ```
  
  In this scenario, Dashboard need to provide plain HTTP termination.  
  I am not sure whether Dashboard support it.
  
  > **Comments:**
  > **username_4**: Thank you!!!!!!  
  > **username_5**: This is a great answer thank you very much! Just a quick note for people that just want to expose the dashboard in an internal network with no SSL, option 2 is what you want. On that case be sure to remove any other regular k8s ingress you have and just use the IngressRouteTCP! I had one created before and took me forever to realize it was still using the regular ingress and not the traefik one.  
  
  ---
  
  ### Answer by username_1 on 2022-06-15. Score: 1
  
  There is 4th way:
  
  * Instruct Kube dashboard to use your CA cert (not self-generated ones):
    Delete kube dashboard own certs:
  
  ```
  kubectl -n kubernetes-dashboard delete secret kubernetes-dashboard-certs  
  
  ```
  
  * Add cert from your CA: (note that the one of the dns name must be kubernetes-dashboard.kubernetes-dashboard.svc.cluster.local )
  
  ```
  kubectl -n kubernetes-dashboard create secret tls kubernetes-dashboard-certs --cert=<your cert open key pem> --key=<your cert private key>
  
  ```
  
  * Edit kube dashboard deployment file for using your key:
  
  ```
  kubectl edit -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.6.0/aio/deploy/recommended.yaml 
  
  ```
  
  * add tls-cert-file/tls-key-file to container spec as shown below:
  
  ```
        spec:
          containers:
          - args:
            - --auto-generate-certificates
            - --namespace=kubernetes-dashboard
            - --tls-cert-file=/tls.crt
            - --tls-key-file=/tls.key
  
  ```
  
  * Instruct Traefik to use your CA to check Kube dashboard certs (should go to kube-system namespace with key name ca.crt).
  
  ```
  kubectl -n kube-system create secret generic <yourca> --from-file=ca.crt=<your ca open pem key>
  
  ```
  
  * Modify ServerTransport
  
  ```
  ---
  apiVersion: traefik.containo.us/v1alpha1
  kind: ServersTransport
  metadata:
    name: mytransport
    namespace: kube-system
  spec:
    serverName: kubernetes-dashboard.kubernetes-dashboard.svc.cluster.local
    rootCAsSecrets:
    - <yourca>
  
  ```
  
  * Use that transport in IngressRoute
  
  ```
  ---
  apiVersion: traefik.containo.us/v1alpha1
  kind: IngressRoute
  metadata:
    name: kube-dashboard
    namespace: kubernetes-dashboard
  spec:
  ...
  routes:
  ...
      services:
      - name: kubernetes-dashboard
        namespace: kubernetes-dashboard
        port: 443
        serversTransport: mytransport
  
  ```
  
  
  ---
  
  ### Answer by username_2 on 2023-01-17. Score: 0
  
  If you want to use `PathPrefix` to distinguish services, beware that you may need to strip the prefix.
  
  ```yaml
  apiVersion: traefik.containo.us/v1alpha1
  kind: ServersTransport
  metadata:
    name: skip-verify
    namespace: kube-system
  spec:
    insecureSkipVerify: true
  ---
  apiVersion: traefik.containo.us/v1alpha1
  kind: Middleware
  metadata:
    name: kubernetes-dashboard-strip-prefix
    namespace: kube-system
  spec:
    stripPrefix:
      prefixes:
        - /kubernetes-dashboard
  ---
  apiVersion: traefik.containo.us/v1alpha1
  kind: IngressRoute
  metadata:
    name: kubernetes-dashboard
    namespace: kube-system
  spec:
    entryPoints:
      - websecure
    routes:
      - match: PathPrefix(`/kubernetes-dashboard`)
        kind: Rule
        services:
          - name: kubernetes-dashboard
            port: 443
            serversTransport: skip-verify
        middlewares:
          - name: kubernetes-dashboard-strip-prefix
  
  ```
  
  
  ---
  
  