How to Chain SSH Connections Through Multiple Hosts Using ProxyCommand


3 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