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
pid=
client=yes
foreground=yes
[ssh]
accept=4444
connect=ssh.example.com:443
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 115.0.0.0:443
2014.08.15 10:26:05 LOG5[5598]: Service [ssh] connected remote server from 10.0.0.0:45343
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
global
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
daemon
maxconn 500
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-RSA-RC4-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES128-SHA:AES256-SHA256:AES256-SHA:RC4-SHA
defaults
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]: 203.0.0.0:52385 [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 ...
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:
I hope that somebody finds this useful.
I managed to get it to select the ssh backend by using
ssl_fc_sni
instead ofhdr(host)