SSH over HTTPS with proxytunnel and nginx

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

~$ cat .ssh/config
Host example.net
  Hostname example.net
  ProtocolKeepAlives 30
  DynamicForward 8118
  ProxyCommand /usr/bin/proxytunnel -p ssh.example.net:443 -d localhost:22 -E -v -H "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Win32)"

~$ ssh [email protected]
Local proxy ssh.example.net resolves to 115.xxx.xxx.xxx
Connected to ssh.example.net:443 (local proxy)

Tunneling to localhost:22 (destination)
Communication with local proxy:
 -> CONNECT localhost:22 HTTP/1.0
 -> Proxy-Connection: Keep-Alive
 -> User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Win32)
 <- <html>
 <- <head><title>400 Bad Request</title></head>
 <- <body bgcolor="white">
 <- <center><h1>400 Bad Request</h1></center>
 <- <hr><center>nginx/1.0.5</center>
 <- </body>
 <- </html>
analyze_HTTP: readline failed: Connection closed by remote host
ssh_exchange_identification: Connection closed by remote host

Nginx config on the server;

~$ cat /etc/nginx/sites-enabled/ssh 
upstream tunnel {
    server localhost:22;
}
server {
    listen 443;
    server_name ssh.example.net;

    location / {
            proxy_pass http://tunnel;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_redirect off;
    }

    ssl on;
    ssl_certificate /etc/ssl/certs/server.cer;
    ssl_certificate_key /etc/ssl/private/server.key;
}

~$ tail /var/log/nginx/access.log
203.xxx.xxx.xxx - - [08/Feb/2012:15:17:39 +1100] "CONNECT localhost:22 HTTP/1.0" 400 173 "-" "-"

Nginx doesn't support forward proxy requests (the HTTP CONNECT method), which is why you get the "Bad request" response from Nginx. Proxytunnel is able to connect to Nginx, but from there it stops. AFAIF the Nginx authors have no plans to support forward proxy requests, as they like to be specialized in serving HTTP really well. Apache has modules for everything else, giving you the freedom to use those exotic features.

You can look at sslh, which can multiplex the incoming traffic at port 443 to either Nginx (listening at 127.0.0.1:443), SSH or OpenVPN. Make sure you let sslh listen at the public IP address, and not on 0.0.0.0 as that overlaps with 127.0.0.1:433 where Nginx is listening.

Another options is using Squid, but I have no experience there.


This is old question, but still actual :-)

As others mentioned this setup is hardly to be available due to lacking HTTP CONNECT method available in Nginx.

NOTE: Apache web server supports this setup.

But, for Nginx there is solution without sslh I think in form of custom Nginx module which implements HTTP CONNECT: https://github.com/chobits/ngx_http_proxy_connect_module

By using this you should be able to use in your ssh config only ProxyCommand properly.