Ruben Laguna's blog

Jun 10, 2014 - 3 minute read - linux

SSH Port forwarding through multiple hops [.ssh/config]

Anybody that have to work with lab at work knows the pain of connecting to them. Usually labs don’t have direct connectivity to the “regular” network and to connect to them involves a series of jumps though different machines. Just SSH connectivity is painful in those scenarios let alone port forwarding. Fortunately you can setup your ~/.ssh/config in such a way that will automate most of it, if not all.

So let’s imagine that you want to forward your local port 8090 to destination:8090 but your local machine doesn’t have direct connectivity to destination you must go though hop1 and hop2 in that order.

localhost:8090 --SSH:22--> hop1 --SSH:22--> hop2 --> destination:8090

We want to set up the port forwarding the regular way with a single command ssh -f -N -L 8090:destination:8090 user2@hop2 but that won’t work because we dont’t have connectivity to hop2 either. But we can tell SSH how to get to hop2 in the ~/.ssh/config like so:

# $HOME/.ssh/config
Host *
  ServerAliveCountMax 4
  ServerAliveInterval 15
  ForwardAgent yes # So that the keys in your localmachine are used across hops

Host hop2
  HostName # Sometimes hop machines are not resolvable via DNS
  User user2 # if different account in hop2
  ProxyCommand ssh user1@hop1 -W %h:%p

Ok, assuming that you could login to hop1 with ssh user1@hop1 then the above will allow you to just ssh user2@hop2. I’m also assuming that you have setup passwordless ssh login (ssh-keygen -t rsa and ssh-copy-id are your friends)

So now ssh -f -N -L 8090:destination:8090 user2@hop2 will setup the port forwarding through hop1 and hop2. It will try to go to hop2 and since we have that ProxyCommand for hop2 it will use hop1 to get to hop2.

Shorten the command

ssh -f -N -L 8090:destination:8090 user2@hop2 is not that easy to remember. So you can just create an alias for it in your shell or add the following to ~/.ssh/config:

# $HOME/.ssh/config
Host setupPF # this is a copy of Host hop2 + LocalForward
  HostName # Sometimes hop machines are not resolvable via DNS
  ProxyCommand ssh user1@hop1 -W %h:%p
  User user2
  LocalForward 8090 destination:8090

So now a simple ssh -f -N setupPF will be enough to setup the port forwarding.

Bonus: SSH access to destination via hop1 and hop2

Chances are that you will also want to ssh into destination in addition to the port forwarding thing. You can just ssh destination to it if you add the following to the ~/.ssh/config

# $HOME/.ssh/config
Host destination
  User user3 # so you can type ssh destination instead of ssh user3@destination
  ProxyCommand ssh user2@hop2 -W %h:%p