How to Chain SSH Connections Through Multiple Hosts Using ProxyCommand


11 views

When working with nested private networks, we often need to traverse multiple SSH hops to reach our target machine. The standard ProxyCommand approach works well for single-hop scenarios, but multi-hop connections require careful configuration.

In our case:

Local Machine → gateway.example.com → foo → baz

The key insight is that each hop requires its own SSH connection and port forwarding.

Here's the correct configuration for ~/.ssh/config:

Host baz
    ProxyCommand ssh -W %h:%p foo
    
Host foo
    ProxyCommand ssh -W %h:%p gateway.example.com

If you prefer the nc method, this works too:

Host baz
    ProxyCommand ssh -q foo "nc %h %p"
    
Host foo
    ProxyCommand ssh -q gateway.example.com "nc %h %p"

Add these parameters for better performance:

Host *
    ControlMaster auto
    ControlPath ~/.ssh/control:%h:%p:%r
    ControlPersist 10m
    ServerAliveInterval 60

If connections fail:

  1. Verify each host can reach the next one
  2. Check /etc/hosts or DNS resolution at each hop
  3. Test with -v flag for verbose output

For production environments:

Host *
    ForwardAgent no
    StrictHostKeyChecking yes



When dealing with nested private networks, standard SSH connections often fall short. The specific challenge arises when:

  • Your target machine (baz) exists in a 3rd-level network
  • The intermediate hosts (gateway → foo → baz) each have distinct network access
  • Traditional ProxyCommand configurations don't handle multiple hops

Visualizing the path helps:

[Your Machine] → [gateway.example.com] → [foo] → [baz]
      (Public)        (Corporate LAN)    (Private Subnet)

For modern OpenSSH (7.3+), use the -J flag:


host baz
    ProxyJump gateway.example.com,foo
    User remote_username
    Port 22

For older versions (like Ubuntu 10), chain ProxyCommands:


host baz
    ProxyCommand ssh -W %h:%p foo
host foo
    ProxyCommand ssh -W %h:%p gateway.example.com

When -W isn't available:


host baz
    ProxyCommand ssh -q gateway.example.com 'ssh -q foo nc %h %p'

Add these flags to troubleshoot:


ssh -vvv -T baz

Add these to your config to reduce latency:


ControlMaster auto
ControlPath ~/.ssh/control:%h:%p:%r
ControlPersist 10m
  • Always use SSH keys instead of passwords
  • Consider adding -o StrictHostKeyChecking=yes
  • Limit port forwarding with -o PermitLocalCommand=no