This tutorial is made for you to be able to test how to do SSH over a standard https SSL/TLS connection (at least for the CONNECT). the objective is to understand how it's working and to be able for you to make a POC if you want to. I'm not responsible for what purpose you are using it to. most of this tutorial was possible thanks to the hard work of

this tutorial is definitely doable on a Raspbeery Pi

 do not hesitate to let me a comment to ask questions.


2. HAProxy

configuration Haproxy

root@gatessh:/home/pi# cat /etc/haproxy/haproxy.cfg
# this config needs haproxy-1.1.28 or haproxy-1.2.1
        log   local0
        log   local1 notice
        #log loghost    local0 info
        maxconn 4096
        #chroot /usr/share/haproxy
        user haproxy
        group haproxy
        log     global
        mode    http
        option  httplog
        option  dontlognull
#       retries         3
#       option redispatch
        maxconn         2000
        contimeout      5000
        clitimeout      50000
        srvtimeout      50000
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http
        option forwardfor
        option http-server-close
backend secure_http
        reqadd X-Forwarded-Proto:\ https
        reqadd X-Scheme:\ https if { ssl_fc }
        rspadd Strict-Transport-Security:\ max-age=31536000
#       mode http
        option httplog
        option forwardfor
#       server local_http_server
        server local_http_server  ssl verify none
backend ssh
        mode tcp
        option tcplog
        server ssh
        timeout server 2h
frontend ssl
        bind :443 ssl crt /etc/nginx/ssl/nginx.pem
        mode tcp
        option tcplog
        tcp-request inspect-delay 5s
        tcp-request content accept if HTTP
        acl client_attempts_ssh payload(0,7) -m bin 5353482d322e30
        use_backend ssh if !HTTP
        use_backend ssh if client_attempts_ssh
        use_backend secure_http if HTTP


This magic come from the RFC 4253, section 4.2 states that clients must send a string that starts with 'SSH-2.0' (this is also how sslh does it). Moreover, 5353482d322e30 is the binary representation of the string 'SSH-2.0'. So everything is done by this line:

acl client_attempts_ssh payload(0,7) -m bin 5353482d322e30

When a new connection is made on the port 443, HAproxy decrypts the SSL layer, and checks whether the stream of data sent by the client starts with this string. We use the result of this condition to choose the backend. This handles the case of 'active' SSH clients (like openssh-client on linux), who send a packet as soon as they connect. There are also 'passive' SSH clients (like putty), who wait for the server to send a string. These clients will get that string after 5 seconds (the inspect-delay).


3. Nginx


the nginx conf is standard, you just have to listen on a different port than the 443, and of course the same as describe in HAproxy. In the example below you can see a conf using gateone but you could have a white pages, but you can do as you want. the important thing is haproxy. You could also have an apache if you prefer.

root@gatessh:/home/pi# cat /etc/nginx/sites-enabled/gateone
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
# HTTPS server
server {
        listen 444;
        ssl on;
        ssl_certificate /etc/nginx/ssl/nginx.crt;
        ssl_certificate_key /etc/nginx/ssl/nginx.key;
#       ssl_session_timeout 5m;
#       ssl_protocols SSLv2 SSLv3 TLSv1;
#       ssl_ciphers HIGH:!aNULL:!MD5;
#       ssl_prefer_server_ciphers on;
        location /gateone/ {
                auth_basic "Restricted";
                auth_basic_user_file /etc/nginx/.htpasswd;
                proxy_pass_header Server;
                proxy_set_header Host $http_host;
                proxy_redirect off;
                proxy_buffering                 off;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Scheme $scheme;
                proxy_set_header X-Forwarded-Host $host;
                proxy_set_header X-Forwarded-Server $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://localhost:8888;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection $connection_upgrade;


once everything is done, go look into the next article : ssh over ssl part 2 : client side



sources :


Add comment

Security code

Go to Top
Template by JoomlaShine