# Why does TCP router try to perform SSL handshake even if TLS is set to false?

**URL:** <https://community.traefik.io/t/why-does-tcp-router-try-to-perform-ssl-handshake-even-if-tls-is-set-to-false/18710>\
**Category:** Traefik v2\
**Tags:** tcp, docker-swarm\
**Created:** [May 23, 2023, 12:43pm UTC](https://community.traefik.io/t/why-does-tcp-router-try-to-perform-ssl-handshake-even-if-tls-is-set-to-false/18710 "2023-05-23T12:43:15Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![aleksvujic](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/aleksvujic/32/4885_2.png) [@aleksvujic](https://community.traefik.io/u/aleksvujic)\
**Post date:** [May 23, 2023, 12:43pm UTC](https://community.traefik.io/t/why-does-tcp-router-try-to-perform-ssl-handshake-even-if-tls-is-set-to-false/18710/1 "2023-05-23T12:43:15Z")

</div>

### What did you do?

We are using Traefik v2.9.10. We would like to deploy an application which would respond to TCP requests on entrypoint 8093 (`backend-thrift-tcp`). It must work without TLS. Our Traefik is configured like this:

**`docker-compose-Traefik.yml`** :

```yaml
version: "3.7"

services:
  traefik:
    image: "traefik:v2.9.10"
    networks:
      - traefik-net
    ports:
      # Traefik
      - target: 9000
        published: 9000
        protocol: tcp
        mode: host
        
      # backend
      - target: 8082
        published: 8082
        protocol: tcp
        mode: host
        
      # backend-thrift
      - target: 8092
        published: 8092
        protocol: tcp
        mode: host
        
      # backend-thrift-tcp
      - target: 8093
        published: 8093
        protocol: tcp
        mode: host

    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./TraefikConfig/:/etc/traefik/"
      - "/var/log/traefik/:/var/log/"
    deploy:
      replicas: 1
      labels:
        # enable Traefik for this service
        - "traefik.enable=true"
        - "traefik.docker.network=traefik-net"

        # dashboard
        - "traefik.http.routers.traefik.rule=Host(`traefik.company.local`)"
        - "traefik.http.routers.traefik.entrypoints=traefik"
        - "traefik.http.routers.traefik.tls=true"
        - "traefik.http.routers.traefik.service=api@internal"

        # service
        - "traefik.http.services.traefik.loadbalancer.server.port=8080"
        - "traefik.http.services.traefik.loadbalancer.server.scheme=https"

networks:
  traefik-net:
    external: true
    name: traefik-net

```

**`traefik.yml`** :

```yaml
providers:
  file:
    directory: "/etc/traefik"
    watch: true
  docker:
    swarmMode: true
    exposedByDefault: false

entrypoints:
  traefik:
    address: ":9000"
  backend:
    address: ":8082"
  backend-thrift:
    address: ":8092"
  backend-thrift-tcp:
    address: ":8093"

```

**`dynamic_conf.yml`** :

```yaml
tls:
  stores:
    default:
      defaultCertificate:
        certFile: /cert/star.company.local.crt
        keyFile: /cert/star.company.local.key
  certificates:
    - certFile: /cert/star.company.local.crt
      keyFile: /cert/star.company.local.key
      stores:
        - default
  options:
    default:
      minVersion: VersionTLS12

http:
  routers:
    catch-all-fallback:
      rule: "HostRegexp(`{host:(app1|app2|app3)(-(dev|test|stage))?\\.company\\.(local|com)}`)"
      priority: 1
      middlewares:
        - "redirect-to-generic-error-page"
      tls: {}
      service: "noop@internal"
  middlewares:
    redirect-to-generic-error-page:
      redirectRegex:
        regex: "(.*)"
        replacement: "https://www.company.com/maintenance.html?returnURL=${1}"
        permanent: false

```

Then, we deployed the TCP service (application) with the following configuration:

```yaml
# docker-compose -f docker-compose-Prod.yml up
version: "3.7"
services:
  web:
    image: app:1.2.3
    networks:
      - traefik-net
    deploy:
      replicas: 1
      labels:
        # enable Traefik for this service
        - "traefik.enable=true"
        - "traefik.docker.network=traefik-net"

        # router
        - "traefik.http.routers.app-prod.tls=false"
        - "traefik.http.routers.app-prod.service=app-prod"
        - "traefik.http.routers.app-prod.entrypoints=backend"
        
        - "traefik.http.routers.app-prod-thrift.tls=false"
        - "traefik.http.routers.app-prod-thrift.service=app-prod-thrift"
        - "traefik.http.routers.app-prod-thrift.entrypoints=backend-thrift"

        - "traefik.tcp.routers.app-prod-thrift-tcp.tls=false"
        - "traefik.tcp.routers.app-prod-thrift-tcp.service=app-prod-thrift-tcp"
        - "traefik.tcp.routers.app-prod-thrift-tcp.entrypoints=backend-thrift-tcp"
        - "traefik.tcp.routers.app-prod-thrift-tcp.rule=HostSNI(`*`)"

        # service
        - "traefik.http.services.app-prod.loadbalancer.server.scheme=http"
        - "traefik.http.services.app-prod.loadbalancer.server.port=8082"

        - "traefik.http.services.app-prod-thrift.loadbalancer.server.scheme=http"
        - "traefik.http.services.app-prod-thrift.loadbalancer.server.port=8092"

        - "traefik.tcp.services.app-prod-thrift-tcp.loadbalancer.server.port=8093"
      restart_policy:
        condition: on-failure

networks:
  traefik-net:
    external: true
    name: traefik-net

```

### What did you see instead?

When we send a TCP request to `<host_IP>:8093` (entrypoint `backend-thrift-tcp`), we can see the following error in Traefik logs:

```auto
level=debug msg="http: TLS handshake error from 172.29.10.227:62608: tls: unsupported SSLv2 handshake received"

```

Why does Traefik even try to establish a TLS connection even though we explicitly told it not to with the following line?

```auto
traefik.tcp.routers.app-prod-thrift-tcp.tls=false

```

Interestingly, if we remove `tls: {}` line from `catch-all-fallback` HTTP router defined in static configuration, everything works fine.

### What version of Traefik are you using?

```auto
Version: 2.9.10
Codename: banon
Go version: go1.20.3
Built: 2023-04-06T16:15:08Z
OS/Arch: linux/amd64

```

---

<div class="post-metadata">

**Author:** ![bluepuma77](https://avatars.discourse-cdn.com/v4/letter/b/a9adbd/32.png) [@bluepuma77](https://community.traefik.io/u/bluepuma77)\
**Post date:** [May 23, 2023, 2:27pm UTC](https://community.traefik.io/t/why-does-tcp-router-try-to-perform-ssl-handshake-even-if-tls-is-set-to-false/18710/2 "2023-05-23T14:27:02Z")

</div>

> [@aleksvujic](#):
>
> ```auto
> http:
> routers:
> 
> ```

is dynamic configuration. It needs to go into a dynamic config file which has to be loaded in static config via `provider.file`.

---

<div class="post-metadata">

**Author:** ![aleksvujic](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/aleksvujic/32/4885_2.png) [@aleksvujic](https://community.traefik.io/u/aleksvujic)\
**Post date:** [May 23, 2023, 6:55pm UTC](https://community.traefik.io/t/why-does-tcp-router-try-to-perform-ssl-handshake-even-if-tls-is-set-to-false/18710/3 "2023-05-23T18:55:55Z")

</div>

It indeed is placed in the dynamic configuration. I made a mistake in my original question, I edited it now. The router and middleware are displayed in Traefik dashboard so the problem lies somewhere else.

---

<div class="post-metadata">

**Author:** ![bluepuma77](https://avatars.discourse-cdn.com/v4/letter/b/a9adbd/32.png) [@bluepuma77](https://community.traefik.io/u/bluepuma77)\
**Post date:** [May 23, 2023, 8:42pm UTC](https://community.traefik.io/t/why-does-tcp-router-try-to-perform-ssl-handshake-even-if-tls-is-set-to-false/18710/4 "2023-05-23T20:42:55Z")

</div>

Ok, but the entrypoints need to go into static config.

---

<div class="post-metadata">

**Author:** ![aleksvujic](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/aleksvujic/32/4885_2.png) [@aleksvujic](https://community.traefik.io/u/aleksvujic)\
**Post date:** [May 24, 2023, 5:59am UTC](https://community.traefik.io/t/why-does-tcp-router-try-to-perform-ssl-handshake-even-if-tls-is-set-to-false/18710/5 "2023-05-24T05:59:58Z")

</div>

I updated the question with all my configuration files for Traefik:

1. `docker-compose-Traefik.yml` which contains a definition for deploying Traefik Docker service
2. `traefik.yml` which contains static configuration
3. `dynamic_conf.yml` which contains dynamic configuration

The last two files are mounted to Traefik container inside `volumes` section in `docker-compose-Traefik.yml` (volume `./TraefikConfig/:/etc/traefik/`).

---

<div class="post-metadata">

**Author:** ![bluepuma77](https://avatars.discourse-cdn.com/v4/letter/b/a9adbd/32.png) [@bluepuma77](https://community.traefik.io/u/bluepuma77)\
**Post date:** [May 24, 2023, 6:27am UTC](https://community.traefik.io/t/why-does-tcp-router-try-to-perform-ssl-handshake-even-if-tls-is-set-to-false/18710/6 "2023-05-24T06:27:17Z")

</div>

Sorry to be PITA again, but `http.routers` should go into dynamic config.

To be clean you can use `provider.file` just with the dynamic file, not the full folder. Static file is read automatically.

Check Traefik dashboard and debug log for errors.

---

<div class="post-metadata">

**Author:** ![aleksvujic](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/aleksvujic/32/4885_2.png) [@aleksvujic](https://community.traefik.io/u/aleksvujic)\
**Post date:** [May 24, 2023, 8:29am UTC](https://community.traefik.io/t/why-does-tcp-router-try-to-perform-ssl-handshake-even-if-tls-is-set-to-false/18710/7 "2023-05-24T08:29:11Z")

</div>

You are correct, `http.routers` section should be placed in the dynamic configuration (`dynamic_conf.yml`). I updated the question with (I hope) correct configuration.

However, Traefik still wants to perform SSL handshake even if TLS for TCP router `app-prod-thrift-tcp` is set to false. If we remove `tls: {}` from `catch-all-fallback` router defined in `dynamic_conf.yml`, everything works okay.

Traefik dashboard doesn't show any errors. We can see the following error in Traefik log:

```auto
level=debug msg="http: TLS handshake error from 172.29.10.227:62608: tls: unsupported SSLv2 handshake received"

```

I don't understand why `tls: {}` in `catch-all-fallback` router has an effect on `app-prod-thrift-tcp` router. Is it because they listen on the same entrypoints? Is it a bug?

---

<div class="post-metadata">

**Author:** ![bluepuma77](https://avatars.discourse-cdn.com/v4/letter/b/a9adbd/32.png) [@bluepuma77](https://community.traefik.io/u/bluepuma77)\
**Post date:** [May 24, 2023, 12:04pm UTC](https://community.traefik.io/t/why-does-tcp-router-try-to-perform-ssl-handshake-even-if-tls-is-set-to-false/18710/8 "2023-05-24T12:04:13Z")

</div>

`catch-all-fallback` is not assigned to any entrypoint, so it is automatically assigned to all entrypoints and you then enable TLS.

Maybe try assigning it only to relevant entrypoints and if you want to use TLS and non-TLS, then use two catch-all, only one with TLS enabled.

---

<div class="post-metadata">

**Author:** ![aleksvujic](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/aleksvujic/32/4885_2.png) [@aleksvujic](https://community.traefik.io/u/aleksvujic)\
**Post date:** [May 24, 2023, 12:08pm UTC](https://community.traefik.io/t/why-does-tcp-router-try-to-perform-ssl-handshake-even-if-tls-is-set-to-false/18710/9 "2023-05-24T12:08:27Z")

</div>

Yes, `catch-all-fallback` automatically listens on all entrypoints, including the one that `app-prod-thrift-tcp` listens on. This is also visible in the Traefik dashboard.

However, I don't understand why a TLS setting of **HTTP** router (`catch-all-fallback`) has effect on **TCP** router (`app-prod-thrift-tcp`)? Is it because they use the same entrypoint? Is this documented somewhere?
