My Experiences With SSH

Networking with SSH can be surmised in one word: Cool! There are very few protocol implementations that I am aware of that can match today's implementations of OpenSSH in the number of ways you can pass network traffic around through an SSH tunnel. When I first switched to Linux, SSH was one of the tools that kept me on the operating system because I could use it as a Swiss Army Knife for networking. Ahem netcat. My primary use case for SSH in more recent times is as a management utility for remote Linux systems. This is what SSH was designed for and it performs this function well. For me, this hasn't always been the case. I have used SSH for evading IP block blacklists, a poor-mans VPN, Accessing the internal LAN of an enterprise network, and forwarding remote ports to local ports (and in reverse). SSH is one of the few tools that I simply can't live without. But lets get to the meat of this post; lets dive into how Local Forwarding in SSH works and why we might want to use that over Dynamic Forwarding.

Practical Example in SSH Local Forwarding

Lets take an example organizations network consisting of a external client, DMZ segment, and internal LAN segment.

Example Network

In this diagram I need to access the LAN server of my organization but I can't do that directly because of the NAT firewall that's in place; but I can access the DMZ server. If I just wanted command line access to the LAN server I could use SSH's ProxyJump capability to get access through the DMZ server (the router would route the DMZ servers traffic to the LAN segment in this organizations configuration). That command would look something like this: ssh -J user@172.217.9.164 user@172.22.12.10. But because I need to access port 80 (HTTP) of the LAN server, I can not only use SSH's ProxyJump functionality because it only gets me command line access. I need to use something that will let me route my web browsers traffic (HTTP traffic) to the LAN server on Port 80 without unnecessarily routing additional traffic. For this we should use SSH's LocalForward with SSH's ProxyJump to simply forward a port on the Client to port 80 on the LAN server.

ssh -N -L 8080:localhost:80 -J user@172.217.9.164 user@172.22.12.10

This command accomplishes this. Lets dissect this command for a moment

  • -N Tells SSH that we don't intend to execute any commands on the LAN server
  • -L 8080:localhost:80 Tells SSH to open port 8080 on the Client and to forward all traffic sent to port 8080 directly to port 80 on the remote host. All traffic the server sends in response will be sent back down the ssh tunnel to us.
  • -J user@172.217.9.164 Tells SSH to use the DMZ server as a proxy to connect directly to the LAN server
  • user@172.22.12.10 is the destination LAN server we intend to connect to.

Alternatively, we could have used SSH's DynamicForward functionality to accomplish the same goal. Dynamic forwarding in this situation would look like this: ssh -D 8080 user@172.217.9.176. SSH's DynamicForward would establish a Socks5 proxy on our local machine that routes traffic through the SSH tunnel which has the effect of creating a 'poor-mans VPN'. This is a valid method especially when dealing with HTTPS because HTTPS is domain name sensitive. But with DynamicForwarding we also run the risk of routing all our browsers traffic through the DynamicForward tunnel. All of our requests for YouTube in addition to our work related network requests to the LAN server would be forwarded through our organizations DMZ! That is what makes SSH's LocalForward superior to DynamicForward in these cases. LocalForward allows us to tunnel traffic from machine to machine, granularly port by port.

Recap

I've shown you some very powerful features of SSH here. The ProxyHost command, DynamicForward command, and LocalForward command will let you jump into internal LAN's (like I showed you above), route your traffic around IP blacklists, and gain localhost port access to servers from different hosts.