SSH Tunneling Summary
There are three types of SSH port forwarding:
-
Forwards a connection from the client host to the SSH server host and then to the destination host port.
-
Forwards a port from the server host to the client host and then to the destination host port.
-
Creates a SOCKS proxy server that allows communication across a range of ports.
1 Roles
- Client: Any machine where you can
ssh
to enable Port Forwarding - SSH Server: A machine that can be SSHed into by Client
- Target Server: A machine to which you want to establish a connection, usually to open services on this machine to the outside world.
Notice: both Client and SSH Server can be Target Server, it doesn’t really need three machines to perform Port Forwarding! However, Dynamic Port Forwarding will not be only one Target Server, but it can be dynamically determined.
2 Local Port Forwarding
ssh -L [local_bind_address:]<local_port>:<target_ip>:<target_port> <SSH Server>
Open bind_address:port
on the Client to wait for connection, when someone connects, transfer all data to host:host_port
. (Note that host is relative to the address of SSH Server, not Client!)
2.1 Example: Connect to a service on a development server behind a firewall
ssh -L 9090:localhost:8080 username@my-server
(*Notice that port 22 is implicit in forwarding command)
2.2 Example: Through the machine behind the firewall, connect to the specific service behind the firewall
ssh -L 9090:192.168.1.101:8080 username@my-server
3 Remote Port Forwarding
Open bind_address:port
on the SSH Server to wait for connection, when someone connects, transfer all data to host:host_port
. (Note that host is relative to the address of Client, not SSH Server!)
ssh -R [server_bind_address:]<server_port>:<target_ip>:<target_port> <SSH Server>
3.1 Example: A service that allows others to connect to your computer through an external machine
ssh -R 0.0.0.0:9090:localhost:8080 username@external-server
- Cautious
For security reasons, Remote Forwarding can only be bound on the localhost of the SSH Server by default, so the above commands alone cannot open Port 9090 to external connections. You must adjust the configuration file of the SSH service on the SSH Server (usually in
/etc/ssh/sshd_config
) to add the GatewayPorts setting so that everyone can connect to:GatewayPorts yes
There are three options here:no
(defaul), that is, the only specified localhost;yes
, the only specified wildcard (0.0.0.0);clientspecified
, the client that starts Remote Forwarding can specify itself.
3.2 Example: Through the external machine, connect back to the service on the internal network from the outside
ssh -R 0.0.0.0:9090:192.168.1.100:8080 username@external-server
Target Server: 192.168.1.100:8080
4 Dynamic Port Forwarding
Start a SOCKS proxy server on the SSH Server, and at the same time open bind_address:port
on the Client to wait for the connection. When someone connects, transfer all the data to this SOCKS proxy server and start the corresponding connection request. Ordinary Port Forwarding can only forward one Port on one IP. When you have many IPs or many Ports that you want to forward, you can only open them one by one, which is very inconvenient. In contrast, Dynamic Port Forwarding can directly set up a proxy server. As long as the program you use supports the SOCKS protocol, you can forward it whenever you want through this proxy server.
ssh -D [bind_address:]<port> <SSH Server>
4.1 Example: Create an HTTP proxy server to connect to all HTTP(S) services on the intranet
ssh -D 9090 username@internal-machine
5 Tips and Tools
5.1 Commonly used SSH command parameters
-N
Do not execute a remote command. This is useful for just forwarding ports (protocol version 2 only).-f
Let the ssh command execute in the background, allowing you to continue doing things with the shell. Usually used with-N
above.