SSH includes a feature known as ProxyJump. ProxyJump allows an SSH connection to be used as a transparent proxy for a subsequent SSH connection. In other words, allowing you to "jump" through one server to reach another. These ProxyJumps can be chained together.
This sounds a bit confusing, but it's really just an extension of the SSH LocalForward option. To illustrate, suppose we have Host1
which shares an internal network with Host2
. If we wanted to access Host2, we could do the following:
SSH ProxyJump simplifies this process, so that we can do the above in one line ssh host2user@host2 -J host1
Defining Jump Hosts in ~/.ssh/config
This feature is most powerful when ProxyJumps are defined in ~/.ssh/config
because any SSH features (like port-forwarding or SCP) can be used through a jump host.
With this definition, every SSH connection to 'host2' will go through host1. Resolution of the hostname will be performed on host1. If custom options for host1
(such as a different port or user) are required, add an above entry in ~/.ssh/config
We can also add wildcard entries, like this
Chaining ProxyJump Entries
Host1 is reachable. Host2 is only reachable via Host1. Host3 is only reachable via Host2
Note: Hostname resolution is performed on the jump host. 'host2' must resolve correctly on host1, and host3 must resolve correctly on host2
.
This problem can be solved by adding IP addresses as the hostnames in your local ~/.ssh/config
.
Creating a locked down account for JumpHosts
Add the above to /etc/ssh/sshd_config
to restrict the user sshjumpsa
as a jump host service account. The PermitOpen statement is a whitelist of allowed upstream destinations. The match is string/regex based, so adding a hostname does not permit requests that use the corresponding IP.
To create the service account, use the following commands:
Locked Down Access in ~/.ssh/authorized_keys
It is also possible to define locked-down access for a particular public key in ~/.ssh/authorized_keys
.
In the example below, the public key can open ssh connections to host2 and host3:22; access is only allowed from 203.0.113.0/24 (the from= statement is optional)