SSH forwarding with reverse proxy (Traefik)

Hello all,

The setup:

I have a proxmox with some underlying containers (everything running linux). One of the containers is running traefik for routing all the data to other containers. I have a domain name which points to the proxmox machine (the top one and not the container). Port 80 and port 443 are routed to port 80 and 443 of the container which is running traefik so it can handle the incoming requests properly. Everything is working correctly with HTTP web applications.

For the SSH purpose, I have also forwarded port 2000 of the parent machine to the port 2000 of the container which is running the traefik.

What I am trying to do:

I am trying to forward SSH connections with subdomains instead of ports. Some of the machines which I would like to access are in LAN of the traefik container and others are outside LAN (some other IPs and domains). I have a domain name A record abc.com (just for example) which points to the top level machine IP of the proxmox and I have setup CNAME record c1.abc.com which points to the abc.com.

Reverse Proxy (Traefik) Setup

I have double checked the traefik configuration and according to documentation (to the extent which I understood) and according to my knowledge, the configuration is correct but still I am going to post the configuration here.

I am using traefik configuration provider as directory (which means there is a top level yaml configuration file traefik.yaml having some top level configurations and it points to a directory having some additional dynamic configuration files).

Following is my top-level traefik.yaml:

providers:
  file:
    directory: traefik/config # Checking for config files in config directory
    watch: true

entryPoints:
  ssh:
    address: ":2000"  # Traefik will listen on port 2000 for SSH connections
  web:
    address: ":80"
    http:
      redirections:
          entryPoint:
            to: web-secure
            scheme: https
            permanent: true
  web-secure:
    address: ":443"
  

certificatesResolvers:
  letsencrypt:
    acme:
      storage: acme.json
      httpChallenge:
        entryPoint: web

api:
  dashboard: true
  insecure: true

log:
  level: INFO

Following is the configuration for SSH:

tcp:
  routers:
    ssh-router:
      entryPoints:
        - ssh
      rule: "HostSNI(`*`)"
      service: ssh-service
      tls:
        passthrough: true  # Required for SSH to work properly

  services:
    ssh-service:
      loadBalancer:
        servers:
          - address: "192.168.1.13:22"  # Forwarding traffic to SSH container in the inner LAN where I can already SSH through the machine on which traefik is running



The issue:

The TCP connection is established but it finishes up immediately as can be seen by following logs:

$ ssh user1@c1.abc.com -p 2000 -v   
OpenSSH_8.9p1 Ubuntu-3ubuntu0.10, OpenSSL 3.0.2 15 Mar 2022
debug1: Reading configuration data .ssh/config
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: include /etc/ssh/ssh_config.d/*.conf matched no files
debug1: /etc/ssh/ssh_config line 21: Applying options for *
debug1: Connecting to c1.abc.com [targetIP] port 2000.
debug1: Connection established.
debug1: identity file .ssh/id_rsa type 0
debug1: identity file /home/ali/.ssh/id_rsa-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.10
debug1: kex_exchange_identification: banner line 0: HTTP/1.1 400 Bad Request
debug1: kex_exchange_identification: banner line 1: Content-Type: text/plain; charset=utf-8
debug1: kex_exchange_identification: banner line 2: Connection: close
debug1: kex_exchange_identification: banner line 3: 
kex_exchange_identification: Connection closed by remote host
Connection closed by <targetIP> port 2000

As far as I understand this issue, traefik is handling the tcp request as HTTP request but there is no HTTP router with that port 2000 inside traefik so I am currently at dead end here.

Can someone check what is the issue going on here?

That does not work. SSH does not use TLS with HostSNI, so it can’t be done.


And this is not required. SSH does not use TLS, so you should use plain TCP without ever activating TLS on the Traefik entrypoint or router. TCP router will forward data as is.

 tls:
   passthrough: true

I eventually discovered that SSH forwarding only works with wildcard HostSNI in traefik and this cannot be categorized based on subdomain. So this will not work.

BTW, thanks for the response @bluepuma77

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