Use sslh behind traefik

Hello,

I'm trying to use a sslh container behind traefik. For example, I want to connect to a sftp container via traefik using https entrypoint (port 443)

Therefore that's my sample docker compose file:

version: '3'

services:
  sslh:
    image: pety3bi/sslh
    ports:
       - "7443:7443"
    networks:
       - traefik_reverse_proxy
    entrypoint: [ "sslh", "-f", "-u", "root", "-p", "0.0.0.0:7443", "--ssh", "0.0.0.0:2223", "--anyprot", "example.com:80" ]
    deploy:
      labels:
        - traefik.enable=true
        - traefik.http.routers.sshl.rule=Host(`test.example.com`)
        - traefik.http.routers.sshl.entrypoints=https
        - traefik.http.routers.sshl.service=sshl
        - traefik.http.routers.sshl.tls=true
        - traefik.http.routers.sshl.tls.certresolver=letsencrypt
        - traefik.http.services.sshl.loadbalancer.server.port=7443

  sslh-sftp:
    image: atmoz/sftp
    networks:
       - traefik_reverse_proxy
    ports:
        - "2223:22"
    command: foo:pass:1001
    
networks:
  traefik_reverse_proxy:
    external: true

If I connect locally (via localhost) using sftp to the sftp container via sslh (port 7443), the connection is established without problems. Even if I connect to the domain (test.example.com) via https I get example.com displayed correctly.
But when I try to connect to the sftp container via the domain using sftp (with port 443), the connection fails.

The domain is provided by cloudflare, cloudflare's proxy is disabled.
WinSCP used as sftp client.

What have I forgotten or done wrong?

Thanks

You have setup an http with TLS (hhtps) router.

As SFTP does not use TLS you cannot utilise HostSNI to route on hostname.
You would have to use a non-tls TCP router traefik.tcp.routers.sshl.HostSNI(`*`)

Alright, I am aware that sftp requires tcp.

In fact this is the main problem that I would like to route http and sftp traffic over port 443.

Due to the fact that sftp does not support HostSNI (cause it does not support tls), I should also not be able to use a Traeffic configuration like this:

traefik.tcp.routers.sshl-tcp.rule=HostSNI(`test.example.com`)

So to solve this problem, there are only three options in my mind:

  1. route all traffic over sslh to traefik (bad, causes huge overhead)
  2. open another port exclusive for sftp (in this environment not possible)
  3. use some technology to tunnle tcp over http (bad, cause the client needs to open a tunnle)

Are there any other (better) options then the three mentioned?

Thanks

Since you're wanting to route both SSH and HTTPS through the same port, you may want to consider using a proxy in front of Traefik which is capable of reading the stream to detect the SSL protocol and route based on the value detected.

stream {
    upstream ssh {
        server 192.0.2.1:22;
    }
    upstream traefik {
        server 192.0.2.2:443;
    }
    map $ssl_preread_protocol $upstream {
        default ssh;
        "TLSv1.2" traefik;
    }
    # SSH and SSL on the same port
    server {
        listen 443;
        proxy_pass $upstream;
        ssl_preread on;
    }
}

I believe this would be a great feature to add to Traefik, and we're always looking for contributions.

2 Likes

Thanks for contributing this idea. Actually this seems to be a viable solution to the problem, thanks for the link and the example.

In the context of traefik, this would definitely be a very useful feature.
@notsureifkevin:
Is this community also storage for new feature ideas - or should I rather switch to GitHub to contribute this idea over there?

We track feature requests on Github, please create an issue on our repository and feel free to reference this blog thread.