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

CC BY-SA 4.0
2022-06-15T14:14:58.727Z
2023-04-04T12:30:58.157Z
2023-04-04T12:30:58.157Z
barzog
<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>

CC BY-SA 4.0
2023-01-17T13:25:06.873Z
2023-01-17T13:25:06.873Z
BubbleQuote
<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>

CC BY-SA 4.0
2022-03-09T18:32:34.553Z
Thank you!!!!!!
FooBar
CC BY-SA 4.0
2024-02-25T20:21:05.637Z
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.
danielfrg
CC BY-SA 4.0
2021-07-27T06:42:27.077Z
2021-07-27T06:42:27.077Z
opris
<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>

<kubernetes><traefik>
SSL issue while reaching kubernetes dashboard
Alessandro Dentella
# 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.

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


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


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= --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  --from-file=ca.crt=


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


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.
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


---

