Skip to content
Kenny Levinsen edited this page Sep 7, 2015 · 1 revision

SSH has builtin proxy support, but not in the usual fashion where you simply type a proxy address. Instead, SSH can call an external application, expecting it to make the connection to the destination host. After the connection is made, the application must expose the connection using stdin/stdout.

This feature is called ProxyCommand. ProxyCommand is usually configured through ssh_config (see the manpage), or through the "-o" option at the command line. An example of a ProxyCommand compatible application would be netcat. Using the following ProxyCommand is exactly equivalent to not using a ProxyCommand at all:

  ProxyCommand nc %h %p

In this case, %h and %p are replaced by the SSH client to indicate the intended destination. Netcat will connect to this host, and forward the connection using standard input/output to SSH, which will then perform the SSH handshake and give you a shell.

Now, more interestingly, you can use netcats SOCKS5 proxy feature to send SSH over a SOCKS5 proxy. Hell, you can make a small application that forwards traffic over snail mail or IP over avian carriers if you wanted, SSH only requires that it works and that the application will provide package delivery/order guarantees equivalent to raw TCP.

ssh -W

You can also use the SSH clients own "ssh -W" mode as a ProxyCommand. "ssh -W" works like netcat, in the sense that you tell it where to connect, and it will give you a connection to work with over stdin/stdout. The difference is that instead of your client making the connection, it will first establish a connection to an SSH server, and then ask for the SSH server to make the connection, forwarding the traffic back to your client.

This can be done with:

  ProxyCommand ssh -W %h:%p ssh_jump_host

Where ssh_jump_host is the SSH server you want to make the connection for you. This is most often used when you have a network with only 1 externally available SSH server, but with many SSH servers on the inside. On the outside (ssh -W uses a special channel rather than using a normal session channel), it is equivalent to ssh'ing to the ssh_jump_host and calling netcat:

  ProxyCommand ssh ssh_jump_host "nc %h %p"

Regardless of whether you ssh-then-netcat, or use ssh -W, the resulting connection is encrypted twice to the jump host, and once to the target:

─ One layer of encryption
═ Two layers of encryption
┏━━━━━━━━━━━━━━┓          ┏━━━━━━━━━━━━━┓          ┏━━━━━━━━━━━━━━━━━┓         
┃  SSH client  ┃══════════┃  Jump host  ┃──────────┃  Target server  ┃
┗━━━━━━━━━━━━━━┛          ┗━━━━━━━━━━━━━┛          ┗━━━━━━━━━━━━━━━━━┛
Clone this wiki locally