Proxy SSH server over WebSocket and Cloudflare
What’s the point of doing this?
Well you might end up in a place that only allows HTTP/HTTPS traffic which is pretty common in schools, universities, dorms, etc.
Once when I stayed in a dorm I noticed that most non-whitelisted ports and IP ranges were throttled.
Ok so let’s begin…
Requirements:
- WebSocat — Netcat, curl and socat for WebSockets.
- Nginx — High Performance Load Balancer, Web Server, & Reverse Proxy.
- OpenSSH — SSH Server / Client. Duhhh…
To build WebSocat run:
cargo build --release --features=ssl
Yes it is indeed written in Rust and requires Cargo build tool and package manager.
Note: This has to be done on both server and also the client.
Server-side setup
Create a Cron job to start WebSocat tcp -> ws proxy on boot.
Add this entry by running crontab -e.
@reboot ~/.cargo/bin/websocat --binary ws-l:127.0.0.1:8022 tcp:127.0.0.1:22
Time to configure our beloved Nginx proxy.
Add this to /etc/nginx/nginx.conf.
server {
    listen 80;
    server_name ws.doner.kernal.eu cf.ws.doner.kernal.eu;
    location / {
        proxy_pass http://127.0.0.1:8022;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
}
In this example I’m also adding a DNS record to proxy it through Cloudflare servers in case of IP address blacklist.
DNS records should look something like this.
DNS management panel — Cloudflare
Client-side setup
Edit ~/.ssh/config file accordingly.
host doner.kernal.eu
    HostName doner.kernal.eu
    IdentityFile ~/.ssh/id_ed25519_passless
host ws.doner.kernal.eu
    HostName ws.doner.kernal.eu
    ProxyCommand websocat --binary ws://ws.doner.kernal.eu
    IdentityFile ~/.ssh/id_ed25519_passless
host cf.ws.doner.kernal.eu
    HostName cf.ws.doner.kernal.eu
    ProxyCommand websocat --binary ws://cf.ws.doner.kernal.eu
    IdentityFile ~/.ssh/id_ed25519_passless
Done, everything works as expected
$ ssh cf.ws.doner.kernal.eu
Last login: Fri Aug 21 05:51:38 2020 from 127.0.0.1
[stnby@doner ~]$ exit
logout
Connection to cf.ws.doner.kernal.eu closed.