Picture of the author
Jarred Kenny
Published on

SSH Gymnastics - Jump Hosts and Port Forwarding

Authors

SSH Jump Hosts connections to be chained and routed via many servers and is often useful for connecting to servers where firewall restrictions may prevent you from connecting directly.

These proxy hosts have many names but are refereed to officially by SSH as "Jump Hosts" however the term "Bastion Host" is also very common.

Using Jump Hosts

Jump hosts are simple to use and can be set using ssh on the command line or permanently within your users SSH configuration. (~/.ssh/config)

1. Command Line

SSH can be instructed to route a connection via a jumphost using the -J command line option.

For example, lets say we have two servers running known as hostA and hostB. hostA is available on the public internet as well as a private network or VPC, while hostB is only available on our private network or VPC.

We can connect to hostB via hostA with the following command:

ssh -J user@hostA user@hostB

2. Using ~/.ssh/config

In cases where you want every connection you make to a server to be routed via a jump host or many jump hosts, you can permanently configure behaviour for a server in ~/.ssh/config

Let's continue with hostA and hostB. We know that hostB can only be reached via hostA. In this case, your ~/.ssh/config would look something like this:

Host hostA
	Hostname hostA
	Port 22
	User root

Host hostB
	ProxyJump hostA

This configuration is equivalent to our command line example, however there is far greater flexibility offered when using ~/.ssh/config to configure connections. For example, you can use wildcards to match hosts whose connections you may want to route via a jump host.

Lets say we wanted to route [anything.mydomain.com](http://anything.mydomain.com) via hostA where anything could be the hostname of any one of your servers on that domain. We simply need to make one change to the configuration above.

Host hostA
	Hostname hostA
	Port 22
	User root

Host *.mydomain.com
	ProxyJump hostA

Adding Port Forwarding

Combining Jump Hosts with SSH's build in port forwarding is an incredibly useful tool for connecting to remote services with complicated firewall restrictions.

Use Case:

You have a database server running in a VPC and due to firewall rules you have in place the DB server can only be connected to from your application server. Your application server is also on a secure private network and can only be accessed via SSH from a dedicated SSH bastion which has both a public IP address and a private IP address on your internal network.

Your goal, use SSH to create a local tunnel to the database server from the application server via the bastion host. We can use SSH port forwarding here to forward a local port to the database server via the tunnel.

We will say the database server is db1, the application server is app1, and the bastion host is jump.

Consider the following command:

ssh -N user@app1 -J user@jump1 -L 3306:db1:3306

What does it do?

  • -N instructs SSH not to open an interactive shell and in this case only establish the connection for port forwarding
  • user@app1 specifies the user and server we are establishing a connection to
  • -J user@jump1 instructs SSH to use jump1 as a jump host to establish our connection
  • -N 3306:db1:3008 tells SSH that when the connection is established forward port 3306 on your local system to port 3306 on db1 via the SSH tunnel.

In this example, you can now talk to the database at localhost:3006 and the network traffic is actually routed to db1 via jump1 and then app1.

And Beyond.

Jump hosts are an incredibly powerful feature of SSH and are so easy to configure that you can often set it and forget it. You can combine this features with SSH port forwarding, X11 session forwarding, or SSH agent forwarding and navigate any number of restricted or complicated network setups.

I have to admit there has been a number of times I could no longer to connect to one of my servers because I forgot that there was a jumphost configured in my SSH configuration and I had actually taken the jump host down. Luckily, you can take management of your SSH configuration to any extreme you desire, from making local edits on your system to pushing our a shared SSH configuration to your entire team.