Autossh with Traefik instead of nginx

I have followed this tutorial to enable access to my Home Assistant project using SSH connection and it works like a charm.

Now, I would like to do the same with the Traefik tool without Nginx. But I get an 502 - Bad Gateway error and the Home Assistant Add-on Autossh can't established the connection.

To do that, I have used this tutorial with this configuration :

[http]
  [http.services]
    [http.services.nas]
      [http.services.nas.loadBalancer]
        [[http.services.nas.loadBalancer.servers]]
          url = "http://localhost:44400"

Does my request is possible or not ?

Thanks.

You only have a service defined. You also need a router. As you're getting a 502 I suppose you have defined this but not shared it.

The example in the tutorial does not use localhost, for a good reason. Each container has it's own network namespace so localhost is the traefik container itself, not the docker host. So you need to use an ip address of the host.

This assumes that HomeAssistant is running native on the machine, not as a container.

Yes, this is all the Traefik config files :

docker-compose.yml

version: '3.7'

services:
  reverse-proxy:
    restart: always
    image: traefik:chevrotin
    ports:
    - "443:443"
    - "80:80"
    volumes:
    - /srv/traefik.toml:/etc/traefik/traefik.toml
    - /srv/services.toml:/etc/traefik/services.toml
    - /var/run/docker.sock:/var/run/docker.sock
    - /srv/acme.json:/acme.json
    labels:
    - "traefik.http.routers.api.rule=Host(`dashboard.domain.com`)"
    - "traefik.http.routers.api.service=api@internal"
    - "traefik.http.routers.api.entrypoints=http"

    - traefik.http.routers.nas.entrypoints=https
    - traefik.http.routers.nas.rule=Host(`home-assistant.domain.com`)
    - traefik.http.routers.nas.service=nas@file
    - traefik.http.routers.nas.tls=true
    - traefik.http.routers.nas.tls.certresolver=letsencrypt

traefik.toml

[entryPoints]
  [entryPoints.http]
  address = ":80"
  [entryPoints.https]
  address = ":443"

[api]

[providers.docker]
  endpoint = "unix:///var/run/docker.sock"

[providers.file]
  filename = "/etc/traefik/services.toml"

[certificatesResolvers.letsencrypt.acme]
  email = "contact@domain.com"
  storage = "acme.json"
  [certificatesResolvers.letsencrypt.acme.httpChallenge]
    entryPoint = "http"

services.toml

[http]
  [http.services]
    [http.services.nas]
      [http.services.nas.loadBalancer]
        [[http.services.nas.loadBalancer.servers]]
          url = "http://localhost:44400"

Ok, I understand but I only need to connect to the Traefik host machine. So with the ip address of the host machine (http://192.168.1.59:44400) this has to work ? (I tried it but get an Gateway Timeout).

Is the service bound to localhost only or is it listening on all interfaces ?

I don’t understand your question, sorry.
The raspberry where is hosted Traefik have the 80 and 443 ports open.
And the home assistant is on an another raspberry, not in the same local network.

That answers my question nicely.

This is one of the uses I use the file provider for myself, proxying for another host.

Is it routable from the docker host where traefik is running ?

Ok cool !
Yes, the raspberry where the traefik is running has the 80 and 443 opened ports on my internet box.
And I have configured a dyndns domain name to access the externally.

I don't know if I correctly answer to your question ?!

Hi, I just posted a full example of my configuration to a better comprehension on this website :

If somebody have any idea or maybe my wishes are not achievable ?!

https://stackoverflow.com/questions/63131431/localtunnel-with-traefik-and-ssh

Thanks for your help.

Please post the snippets here.

I'm looking for a solution with Traefik to do my own Ngrok alternative. I have multiple a home assistant with the Autossh plugin installed on an another server and would like to access to it by entered the url : home-assistant.server.com

Authssh is configured with the remote forwarding port : 44400:localhost:8123, on ssh port (22).

I found this Traefik configuration (Traefik V1) but would like to use Traefik V2. I obtain a Bad gateway with my new Traefik configuration.

My main objective is to connect multiple rapberrypi with home assistant.
Maybe this solution is not the best to do it and you could suggest me some alternatives.

Do you have any idea to resolve it ? Thanks.

Here, my Traefik V2 configuration :

traefik.toml

[entryPoints]
  [entryPoints.http]
  address = ":80"
  [entryPoints.https]
  address = ":443"

[api]

[providers.docker]
  endpoint = "unix:///var/run/docker.sock"

[providers.file]
  filename = "/etc/traefik/services.toml"

[certificatesResolvers.mycertificate.acme]
  email = "contact@server.com"
  storage = "acme.json"
  [certificatesResolvers.mycertificate.acme.httpChallenge]
    entryPoint = "http"

services.toml

[http]
  [http.services]
    [http.services.nas]
      [http.services.nas.loadBalancer]
        [[http.services.nas.loadBalancer.servers]]
          url = "http://localhost:44400"

docker-compose.yml

version: '3.7'

services:
  reverse-proxy:
    restart: always
    image: traefik:chevrotin
    ports:
    - "443:443"
    - "80:80"
    volumes:
    - /srv/traefik.toml:/etc/traefik/traefik.toml
    - /srv/services.toml:/etc/traefik/services.toml
    - /var/run/docker.sock:/var/run/docker.sock
    - /srv/acme.json:/acme.json
    labels:
    - traefik.http.routers.nas.entrypoints=https
    - traefik.http.routers.nas.rule=Host(`home-assistant.server.com`)
    - traefik.http.routers.nas.service=nas@file
    - traefik.http.routers.nas.tls=true
    - traefik.http.routers.nas.tls.certresolver=mycertificate

Localhost is the traefik container itself. Each container has it's own network namespace. This need to be either the ip of the docker host, or the ip of the docker network gateway()usually the x.x.x.1 of the docker network.

SSH is typically TCP and is does not use TLS as a transport protocol. So you likely want to be using a tcp router with rule HostSNI(`*`) .

The existing router you have is sufficient for the https access once you update the service url to a correct ip address.

Ok, thanks !
So, I found the ip of the docker host (172.17.0.1).

So, I don't understand very well why have I to use a TCP router.

To resume, I have a http connection from my browser on url : https://home-assistant.server.com
Then, this request is routing to the 44400 port through SSH.

So, I have tried this configuration, but an "Error while connection to backend: dial tcp 172.17.0.1:44400: connect: connection refused".

Here is my new configuration :

traefik.toml

[entryPoints]
  [entryPoints.http]
  address = ":80"
  [entryPoints.https]
  address = ":443"

[api]

[providers.docker]
  endpoint = "unix:///var/run/docker.sock"

[providers.file]
  filename = "/etc/traefik/services.toml"
  watch = true

[certificatesResolvers. mycertificate.acme]
  email = "contact@server.com"
  storage = "/acme.json"
  [certificatesResolvers. mycertificate.acme.httpChallenge]
    entryPoint = "http"

services.toml

[tcp.services]
  [tcp.services.my-service.loadBalancer]
     [[tcp.services.my-service.loadBalancer.servers]]
       address = "172.17.0.1:44400"

docker-compose.yml

version: '3.7'

services:
  reverse-proxy:
    restart: always
    image: traefik:chevrotin
    ports:
    - "443:443"
    - "80:80"
    volumes:
    - /srv/traefik.toml:/etc/traefik/traefik.toml
    - /srv/services.toml:/etc/traefik/services.toml
    - /var/run/docker.sock:/var/run/docker.sock
    - /srv/acme.json:/acme.json
    labels:
    - traefik.http.routers.nas.entrypoints=https
    - traefik.http.routers.nas.rule=Host(`home-assistant.server.com`)
    - traefik.http.routers.nas.service=my-service@file
    - traefik.tcp.routers.nas.tls=true
    - traefik.tcp.routers.nas.tls.certresolver= mycertificate

    - traefik.tcp.routers.nas.entrypoints=https
    - traefik.tcp.routers.nas.rule=HostSNI(`*`)
    - traefik.tcp.routers.nas.service=my-service@file

SSH is a TCP protocol, a http router won't work.

So something is rejecting the connection or the port is not bound/available in that ip.
If you are using a standard ssh forwarding that will only bind to 127.0.0.1, so you may have to change that.

Here is the difference between:
-L 3000:localhost:3000

ss -tnl 'sport = :3000'
State        Recv-Q        Send-Q                Local Address:Port               Peer Address:Port       
LISTEN       0             128                       127.0.0.1:3000                    0.0.0.0:*          

-gL 3000:localhost:3000

ss -tnl 'sport = :3000'
State        Recv-Q        Send-Q                Local Address:Port               Peer Address:Port       
LISTEN       0             128                         0.0.0.0:3000                    0.0.0.0:*          

-L 0.0.0.0:3000:localhost:3000

ss -tnlp 'sport = :3000'
State        Recv-Q        Send-Q                Local Address:Port               Peer Address:Port       
LISTEN       0             128                         0.0.0.0:3000                    0.0.0.0:*          

Ok so I understand, thanks.
I have deleted the http router inside the docker-compose.yml file :

version: '3.7'

services:
  reverse-proxy:
    restart: always
    image: traefik:chevrotin
    ports:
    - "443:443"
    - "80:80"
    volumes:
    - /srv/traefik.toml:/etc/traefik/traefik.toml
    - /srv/services.toml:/etc/traefik/services.toml
    - /var/run/docker.sock:/var/run/docker.sock
    - /srv/acme.json:/acme.json
    labels:
    - traefik.tcp.routers.nas.entrypoints=https
    - traefik.tcp.routers.nas.rule=HostSNI(`*`)
    - traefik.tcp.routers.nas.service=my-service@file
    - traefik.tcp.routers.nas.tls=true
    - traefik.tcp.routers.nas.tls.certresolver= mycertificate

On the home assistant, I use the Autossh plugin.
So, in the remote_forwarding config, I put this syntax : 0.0.0.0:44400:localhost:8123

Now, I have this new log errors :

"Error during connection: readfrom tcp 172.24.0.2:45190->172.17.0.1:44400: read tcp 172.24.0.2:443->93.22.149.46:55612: read: connection reset by peer"

"Error while terminating connection: write tcp 172.24.0.2:443->93.22.149.46:55612: write: broken pipe"

I thinking to be near the success but still not working :confused:

It works if I update the allowTcpForwarding yes.
But this is not the ideal and inside Home Assistant, the cameras and other http services are not displaying.

In more, inside a new anonymous browser tab, I can't request the interface...

Very strange cause with the nginx configuration, all is working !

Do you have some idea ? Thanks...

I did a lot of tests.
Now with this new configuration, I can access to the first server home-assistant.server.com but the second (home-assistant-1.server.com) is returning a Bad Gateway response.

Do you have a suggestion or is it a bad way ? Thanks

services.toml

[http]
  [http.routers]
    [http.routers.homeassistant]
      entryPoints = ["https"]
      rule = "Host(`home-assistant.server.com`)"
      service = "homeassistant"
      [http.routers.homeassistant.tls]
        certResolver = "mycertificate"

    [http.routers.home-assistant-1]
      entryPoints = ["https"]
      rule = "Host(`home-assistant-1.server.com`)"
      service = "home-assistant-1"
      [http.routers.home-assistant-1.tls]
        certResolver = "mycertificate"

  [http.services]
    [http.services.homeassistant]
      [[http.services.homeassistant.loadBalancer.servers]]
        url = "http://172.17.0.1:44400"

    [http.services.home-assistant-1]
      [[http.services.home-assistant-1.loadBalancer.servers]]
        url = "http://172.17.0.1:44500"

  [tcp.services.homeassistant]
    [[tcp.services.homeassistant.loadBalancer.servers]]
      address = "172.17.0.1:44400"

  [tcp.services.home-assistant-1]
    [[tcp.services.home-assistant-1.loadBalancer.servers]]
      address = "172.17.0.1:44500"

  [http.middlewares]
    [http.middlewares.homeassistant.headers]
      browserXSSFilter = true
      contentTypeNosniff = true
      forceSTSHeader = true
      SSLHost = "server.com"
      SSLRedirect = true
      STSIncludeSubdomains = true
      STSPreload = true
      STSSeconds = 315360000

    [http.middlewares.home-assistant-1.headers]
      browserXSSFilter = true
      contentTypeNosniff = true
      forceSTSHeader = true
      SSLHost = "server.com"
      SSLRedirect = true
      STSIncludeSubdomains = true
      STSPreload = true
      STSSeconds = 315360000