I'm trying to setup an ssh over https connection using haproxy. I haven't found any working examples, so any help would be appreciated!

client config;

~$ cat ~/.stunnel/stunnel.conf

client output;

~$ stunnel ~/.stunnel/stunnel.conf 
2014.08.15 10:16:50 LOG5[5454]: stunnel 5.02 on x86_64-unknown-linux-gnu platform
2014.08.15 10:26:05 LOG5[5598]: s_connect: connected
2014.08.15 10:26:05 LOG5[5598]: Service [ssh] connected remote server from
2014.08.15 10:26:05 LOG5[5598]: Connection closed: 23 byte(s) sent to SSL, 188 byte(s) sent to socket

~$ ssh -v -p 4444 user@localhost
debug1: Local version string SSH-2.0-OpenSSH_6.6.1
debug1: ssh_exchange_identification: HTTP/1.0 400 Bad request

server config;

~$ cat /etc/haproxy/haproxy.cfg

    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    maxconn 500
    ca-base /etc/ssl/certs
    crt-base /etc/ssl/private

    log global
    mode http
    option tcplog
    timeout connect 20s
    timeout client 50s
    timeout server 50s
    timeout tunnel 1h

frontend public
    mode tcp
    bind :443 ssl crt example.pem no-tls-tickets

    tcp-request inspect-delay 5s
    tcp-request content accept if HTTP

    use_backend ssh if !HTTP
    use_backend ssh if { hdr(host) -i ssh.example.com }
    use_backend btsync if { hdr(host) -i btsync.example.com }

    default_backend nginx

backend nginx
    reqadd X-Forwarded-Proto:\ https
    server nginx localhost:8001 check

backend btsync
    server btsync localhost:8888 check

backend ssh
    mode tcp
    server ssh localhost:22
    timeout server 2h

server output;

~$ tail -f /var/log/haproxy.log
Aug 15 16:10:20 localhost haproxy[42548]: [15/Aug/2014:16:10:20.278] public~ nginx/<NOSRV> -1/-1/83 187 PR 0/0/0/0/3 0/0

As far as I can tell stunnel isn't actually connecting to the ssh.example.com subdomain, it simply does a lookup and connects via ip, thus the route within haproxy is going to the main nginx block ...

  • How is "ssh over https" a useful scheme? – Felix Frank Aug 15 '14 at 21:26

I did not manage to use ssl_fc_sni for that, so I used another method. Basically, it consists in checking if the first packet of the connection starts with the string 'SSH-2.0'. This translates to:

acl client_attempts_ssh payload(0,7) -m bin 5353482d322e30
use_backend ssh if !HTTP
use_backend ssh if client_attempts_ssh

I hope that somebody finds this useful.

  • It keeps refusing to work for me. :] – tisc0 May 26 '19 at 21:02

I managed to get it to select the ssh backend by using ssl_fc_sni instead of hdr(host)

use_backend ssh if { ssl_fc_sni ssh.ceaseless.info }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.