The Problem You’re Solving
If you’ve ever needed to access a remote server that’s hidden behind another server—like a database on a private network, a development environment, or a production server not directly exposed to the internet—you’ve faced the multi-hop SSH challenge.
In a typical scenario:
- You need to connect from your local machine to a server behind a firewall
- The target host only exists within a private network
- You must first pass through an intermediate jump host (bastion server)
- Without the right setup, this becomes a cumbersome two-step manual process
Visualizing the Connection Flow
flowchart TD
A[Your Local Machine<br/>VS Code / Terminal] --> B{Connection Request}
B --> C[Direct Connection Attempt<br/>to target-server]
C --> D[FAILS<br/>Private Network Blocked]
B --> E[ProxyJump Connection<br/>via SSH Config]
E --> F[Step 1: Connect to<br/>Jump Host<br/>bastion.example.com]
F --> G[SSH Authentication<br/>with Keys]
G --> H[Step 2: Jump Host connects to<br/>Target Server<br/>10.0.1.50]
H --> I[Final Connection<br/>Established]
I --> J[Access Granted<br/>Seamless Dev Experience]
style A fill:#e1f5fe
style F fill:#f3e5f5
style H fill:#e8f5e8
style J fill:#e8f5e8
style D fill:#ffebeeWhy ProxyJump Beats Manual SSH Chaining
Before ProxyJump, developers used manual SSH chaining like this:
ssh -t jump-server ssh target-serverOr they’d use SSH agent forwarding with all its security concerns.
Here’s why ProxyJump is superior:
- Single Command, Single Step: Connect directly with
ssh private-serverinstead of manual hopping - VS Code Integration: Works seamlessly with remote development features in VS Code
- Native SSH Feature: Uses standard SSH configuration—no custom scripts or workarounds
- Better Security: No need for SSH agent forwarding across hosts
- Cleaner Logging: All connections are properly logged as separate sessions
- Reliability: Handles reconnections and timeouts more gracefully
Your Complete Solution
Configuration for Your Setup
Add this to your SSH config file (~/.ssh/config on Linux/Mac, C:\Users\username\.ssh\config on Windows):
# Jump Host Configuration
Host jump-host
HostName bastion.example.com
Port 22
User jumpuser
# Target Server (Behind Private Network)
Host private-server
HostName 10.0.1.50
User internaluser
ProxyJump jump-hostHow It Works (Step-by-Step)
sequenceDiagram
participant Local as Local Machine
participant Jump as Jump Host<br/>bastion.example.com
participant Target as Target Server<br/>10.0.1.50
Note over Local,Target: 1. Initial Connection Attempt
Local->>Target: Direct SSH connection?
Target-->>Local: ❌ Connection refused<br/>(Private network)
Note over Local,Target: 2. ProxyJump Activated
Local->>Jump: SSH to jump host<br/>(Key authentication)
Jump-->>Local: ✅ Authentication successful
Note over Local,Target: 3. Tunnel Established
Local->>Jump: "Proxy this to target server"
Jump->>Target: SSH connection<br/>from jump host
Target-->>Jump: ✅ Authentication successful
Jump-->>Local: ✅ Tunnel established
Note over Local,Target: 4. Transparent Communication
loop Data Transfer
Local->>Jump: Encrypted traffic
Jump->>Target: Forwarded traffic
Target->>Jump: Response data
Jump->>Local: Forwarded response
endHow to Use It
Once configured, accessing your private server becomes trivial:
- From VS Code:
- Open Command Palette (
Ctrl+Shift+P) - Select “Remote-SSH: Connect to Host”
- Choose
private-server - VS Code handles the jump automatically!
- From Terminal:
ssh private-server
# That's it! No manual hopping needed
- For SCP/SFTP:
scp file.txt private-server:/path/
# Works exactly like a direct connection
Critical Setup Requirements
SSH Key Authentication is Mandatory:
- Your public key must be in
~/.ssh/authorized_keyson BOTH servers - This ensures passwordless, automated connections
- Test with:
ssh jump-hostandssh private-server(after setup)
Enhanced Configuration Examples
With Multiple Jump Hosts
# Chain multiple jumps if needed
Host deep-server
HostName 192.168.2.100
User admin
ProxyJump jump1,jump2 # Connect through multiple hopsWith Specific Identity Files
Host jump-host
HostName bastion.example.com
User jumpuser
IdentityFile ~/.ssh/id_ed25519_bastion
Host private-server
HostName 10.0.1.50
User internaluser
ProxyJump jump-host
IdentityFile ~/.ssh/id_rsa_internalWith Connection Optimization
Host private-server
HostName 10.0.1.50
User internaluser
ProxyJump jump-host
ServerAliveInterval 30
ServerAliveCountMax 3
ControlMaster auto
ControlPath ~/.ssh/%r@%h:%p
ControlPersist 1hSecurity Comparison: ProxyJump vs Alternatives
graph TD
subgraph "Connection Methods Comparison"
A[Manual SSH Chain] --> B[Requires Agent Forwarding]
B --> C[⛔ Security Risk<br/>Keys exposed to jump host]
D[SSH Tunnel<br/>-L/-R Flags] --> E[Complex Configuration]
E --> F[⚠️ Maintenance Heavy<br/>Manual port management]
G[ProxyJump Method] --> H[No Agent Forwarding]
H --> I[✅ Secure by Design]
G --> J[Single Command]
J --> K[✅ Easy to Maintain]
G --> L[Native SSH Support]
L --> M[✅ Widely Compatible]
end
style C fill:#ffebee
style F fill:#fff3e0
style I fill:#e8f5e8
style K fill:#e8f5e8
style M fill:#e8f5e8Troubleshooting Common Issues
| Issue | Solution |
|---|---|
| Permission denied (publickey) | Verify authorized_keys on both servers |
| Connection refused | Check jump host firewall rules and SSH service |
| VS Code hangs | Add ServerAliveInterval 60 to SSH config |
| Host key verification failed | Use ssh-keygen -R hostname to remove old keys |
| “Bad configuration option: ProxyJump” | Upgrade OpenSSH client (7.3+ required) |
| Slow connections | Add compression: Compression yes |
Pro Tips
- Test Your Setup:
ssh -v private-server
# The -v flag shows the ProxyJump process in action- Use VS Code Remote Explorer for visual connection management
- Consider SSH Config Aliases for complex environments:
# Alias for development server
Host dev
HostName 10.0.1.50
User devuser
ProxyJump jump-host
# Alias for production server
Host prod
HostName 10.0.2.50
User produser
ProxyJump jump-hostThis ProxyJump method transforms a complex multi-step process into a single, seamless connection—perfect for remote development, server management, CI/CD pipelines, and accessing restricted environments.