How to Configure SSH Jump Host Tunneling for Multi-Hop Server Access


1 views

When working with production environments, it's common to encounter servers hidden behind multiple gateway machines. The standard approach - manually chaining SSH connections - becomes tedious when you need to:

ssh johndoe@gateway
ssh webby@production-server

This workflow breaks automation scripts, makes file transfers cumbersome, and creates friction during debugging sessions.

The solution lies in properly configuring your ~/.ssh/config file. Here's a complete solution that handles:

  • Jump host authentication
  • Port forwarding
  • SCP compatibility
  • Multiple environment support

For the described environment with gateways A/B and target server FOO:

Host gateway
    HostName a.example.com
    User johndoe
    IdentityFile ~/.ssh/prod_key

Host foo
    HostName foo.internal
    User webby
    ProxyCommand ssh gateway -W %h:%p
    IdentityFile ~/.ssh/internal_key

When the gateway lacks netcat (nc), use SSH's built-in forwarding:

Host foo
    HostName foo.internal
    User webby
    ProxyJump gateway
    IdentityFile ~/.ssh/internal_key

For more complex scenarios, consider these patterns:

Multiple Jump Hosts:

Host backend-server
    HostName db001.private
    ProxyJump gateway1,gateway2

Port Forwarding Through Hops:

ssh -L 8080:target:80 foo

SCP File Transfers:

scp -o 'ProxyJump gateway' file.txt foo:/path/
  • Verify each connection segment works independently first
  • Add -v flag to identify where connections fail
  • Check permissions on all identity files (chmod 600)
  • Test with ssh -J before committing to config

When working with production environments that require traversing multiple gateway servers, SSH access becomes unnecessarily complex. The traditional method of manually chaining connections creates operational inefficiencies:

ssh johndoe@gatewayA
ssh webby@prod-server1

This approach breaks workflows for:

  • SCP file transfers
  • Port forwarding scenarios
  • Automated deployment scripts
  • Quick server access

The proper solution involves leveraging OpenSSH's ProxyCommand directive in your ~/.ssh/config. Here's the complete setup:

Host gateway
    HostName gatewayA.example.com
    User johndoe
    IdentityFile ~/.ssh/production_key
    
Host prod-server1
    HostName 192.168.1.100
    User webby
    ProxyCommand ssh -W %h:%p gateway
    IdentityFile ~/.ssh/production_key
    ForwardAgent yes

When facing environments without netcat (nc), use SSH's built-in tunneling:

Host prod-server2
    HostName 192.168.1.101
    User webby
    ProxyCommand ssh gateway -q -x 'exec 3<>/dev/tcp/%h/%p; cat <&3 & cat >&3'
    IdentityFile ~/.ssh/production_key

Key considerations for production use:

  1. Key Management: Use separate keys for gateway and production servers
  2. Connection Timeouts: Add ServerAliveInterval 60 to prevent stale connections
  3. Host Verification: Include StrictHostKeyChecking yes for security

For complex scenarios:

# Multi-hop through two gateways
Host prod-server3
    HostName 10.0.0.5
    User webby
    ProxyCommand ssh -t gateway1 'ssh -t gateway2 "nc %h %p"'
    
# SCP through tunnel
scp -o 'ProxyCommand ssh gateway -W %h:%p' file.txt prod-server1:/path/
  • Test basic connectivity first: ssh -vT gateway
  • Verify permissions on ~/.ssh/config (must be 600)
  • Check SSH agent forwarding is working with ssh-add -L