4 minutes
How To Use SSH Over An HTTP Proxy
ssh
is a very versatile tool that many of us depend on for everyday tasks. Other than the basic connection to a remote host and multiplexing the terminal with tmux or screen, it is also used
- together with
rsync
- to execute remote commands in scripts
- for port forwarding
- for an adhoc VPN of sorts
That’s a lot of functionality. Yet in some places the connection is restricted behind an HTTP proxy that won’t let ssh
do its magic. Fortunately, it’s still possible to configure ssh
for these cases and here we’ll be covering such a scenario. HTTP proxies usually only allow connections to specific ports such as 80 and 443, although they allow arbitrary TCP streams with the CONNECT method.
Linux, MacOS and Windows with WSL
We will be using netcat-openbsd
, as it’s called in Ubuntu and Debian. Apparently there are two implemenations of netcat and we want the one that supports the -x “connect to proxy” parameter. Here is how ~/.ssh/config
would look like:
Host otherside
HostName example.com
User torvalds
Port 443
IdentityFile ~/.ssh/id_ed25519
ProxyCommand nc -X connect -x 10.20.30.40:8080 %h %p
LocalForward 9999 127.0.0.1:5050
We are connecting to torvalds@example.com
over an HTTP proxy at 10.20.30.40:8080 . netcat also supports SOCKS proxies and authentication if you need them, but you’ll have to man nc
for more information on these topics. As a bonus, we forward the local port 9999 to port 5050 on the remote server.
The tricky part is that the ssh
server has to listen to port 443, which is normally used by HTTPS. Don’t worry about that, we’ll fix it later.
Windows native
Windows users are probably used to tools like PuTTY
and WinSCP
to handle their ssh
and sftp
connections. These programs do support proxy connections, forwarding ports and the like. One thing to keep in mind is that PuTTY
uses it’s own file format for ssh
key files, however it’s possible to import an existing openssh
key into it. We will not be covering their configuration here though. One limitation of them is that they cannot be used with Visual Studio Code
for remote development over ssh
and you don’t get the handy rsync
either.
Windows come with their own version of OpenSSH which can be enabled as an optional feature. Its configuration files can be found in C:\Users\username\.ssh
. We also need to install Nmap
, which comes with its own netcat-like program, called ncat
.
C:\Users\username\.ssh\config
:
Host otherside
HostName example.com
User torvalds
Port 443
IdentityFile C:\Users\torvalds\.ssh\id_ed25519
ProxyCommand C:\Program Files (x86)\Nmap\ncat.exe --proxy 10.20.30.40:8080 %h %p
LocalForward 9999 127.0.0.1:5050
It works the same as described in the previous section.
Some gotchas…
Nmap
needs Administrator rights in order to be installed and used, butncat
doesn’t. If you are unable to installNmap
, then I suggest that you install it on a computer where you do have Administrator rights, then copyncat.exe
, all DLLs andca-bundle.crt
. These are all the files you need.- Do not use an old, so-called portable version linked by ncat’s site.
- nmap 7.93 has a bug, use 7.92 or a later version instead.
DNAT the incoming connection on the server
As we mentioned before, the ssh
client has to connect to port 443 in order to pass through an HTTP proxy. The port may be already in use by a web server. We can work around this requirement by using a DNAT rule on the server.
sysctl net.ipv4.conf.$dev.forwarding=1
iptables -t nat -A PREROUTING -p tcp -i $dev --src $proxy_ip --dport 443 -j DNAT --to-destination $my_ip:$ssh_port
$proxy_ip is the outgoing IP of the HTTP proxy e.g. the address duckduckgo.com gives you when you search for “my ip”. $my_ip is the server’s IP and $ssh_port the port ssh
is normally listening to.
Note that both port 443 and $ssh_port must be open in the firewall rules or at least accept connections coming from $proxy_ip.
Final remarks
You may want to encrypt the connection with TLS. This mainly serves to obfuscate the headers sent by ssh
and make it look more like a common HTTPS connection. This will not be covered here; for more information, have a look at the program’s guide.
That’s it. Have fun.