Multi-Hop SSH Connections via a Bastion Host

How to set up multi-hop SSH connections through a bastion host using ProxyCommand, ProxyJump, and SSH config file with practical examples.

Due to security reasons or network configurations, there may be cases where you cannot directly SSH into a target server. In such cases, you need “multi-hop SSH” – first connecting to a bastion host (jump host), and then connecting to the target server from there.

Here, we explain how to perform multi-hop SSH connections using the ProxyCommand option, the ProxyJump option, or the SSH configuration file (~/.ssh/config).

1. Using the ProxyCommand Option

The ProxyCommand option specifies a command to be executed before establishing the SSH connection. The standard input/output of this command is used as a tunnel for the SSH connection to the target server.

ssh -o ProxyCommand="ssh -W %h:%p bastion_user@bastion_host" target_user@target_host
  • bastion_user@bastion_host: Connection information for the bastion server.
  • target_user@target_host: Connection information for the target server you ultimately want to connect to.
  • ssh -W %h:%p: The -W option performs TCP port forwarding through standard input/output. %h expands to the target server’s hostname and %p to the target server’s port number.

Example:

  • Bastion server: bastion_user@192.168.1.100
  • Target server: target_user@10.0.0.5
ssh -o ProxyCommand="ssh -W %h:%p bastion_user@192.168.1.100" target_user@10.0.0.5

2. Using the ProxyJump Option (OpenSSH 7.3+)

Starting with OpenSSH 7.3, the ProxyJump option was introduced, allowing multi-hop SSH connections to be written more simply.

ssh -J bastion_user@bastion_host target_user@target_host

Example:

ssh -J bastion_user@192.168.1.100 target_user@10.0.0.5

When passing through multiple bastion servers, you can specify them separated by commas.

ssh -J user1@host1,user2@host2 target_user@target_host

By writing settings in the ~/.ssh/config file, you can avoid entering complex commands every time and connect easily using aliases.

Create or edit the ~/.ssh/config file.

nano ~/.ssh/config

Add the following content.

# Bastion server configuration
Host bastion
    HostName 192.168.1.100
    User bastion_user
    IdentityFile ~/.ssh/id_rsa_bastion # Private key for bastion connection (optional)

# Target server configuration
Host target
    HostName 10.0.0.5
    User target_user
    ProxyJump bastion # Specify the bastion server's Host name here
    IdentityFile ~/.ssh/id_rsa_target # Private key for target connection (optional)

After configuration, you can connect to the target server with the following command.

ssh target

~/.ssh/config Options

  • Host: An alias (shorthand name) for this configuration. Used with the ssh command.
  • HostName: The actual hostname or IP address.
  • User: The username for the connection.
  • IdentityFile: The path to the private key used for the connection.
  • ProxyJump: Specifies the Host alias of the bastion server. Available in OpenSSH 7.3 and later.
  • ProxyCommand: Used when ProxyJump is not available in older SSH clients or when more complex tunneling is needed.
    # Using ProxyCommand instead of ProxyJump
    Host target_old_ssh
        HostName 10.0.0.5
        User target_user
        ProxyCommand ssh bastion_user@192.168.1.100 -W %h:%p
        IdentityFile ~/.ssh/id_rsa_target
    

Using ~/.ssh/config is the most recommended method for multi-hop SSH connections, as configurations are highly reusable and easy to manage once set up.