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…


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: tcp:

Time to configure our beloved Nginx proxy.
Add this to /etc/nginx/nginx.conf.

server {
    listen 80;
    location / {
        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.

    IdentityFile ~/.ssh/id_ed25519_passless

    ProxyCommand websocat --binary ws://
    IdentityFile ~/.ssh/id_ed25519_passless

    ProxyCommand websocat --binary ws://
    IdentityFile ~/.ssh/id_ed25519_passless

Done, everything works as expected

$ ssh
Last login: Fri Aug 21 05:51:38 2020 from
[stnby@doner ~]$ exit
Connection to closed.