SSH Jump Host (Bastion) with ProxyJump: The Clean, Modern Way

Prerequisites

  • You can SSH to the gatekeeper from your laptop (WAN reachable).
  • The gatekeeper can SSH to the workstation (LAN reachable).
  • Both servers run sshd (OpenSSH server).
  • Your laptop has OpenSSH client (ssh) (macOS/Linux yes by default).

Step 1 — Generate a Key (if you don’t have one)

On your laptop:

ssh-keygen -t ed25519 -C "soulevil@jumphost"

This creates:

  • Private key: ~/.ssh/id_ed25519
  • Public key: ~/.ssh/id_ed25519.pub

Step 2 — Put Your Public Key on the Gatekeeper

ssh-copy-id -p 422 soulevil@<wanip>

If ssh-copy-id isn’t available, you can do:

cat ~/.ssh/id_ed25519.pub | ssh -p 422 soulevil@<wanip> 'mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys'

Test direct access:

ssh -p 422 soulevil@<wanip>

Step 3 — Put Your Public Key on the Workstation (Recommended)

Option A (simple): If you can reach <localip> from your laptop already, run:

ssh-copy-id soulevil@&lt;localip>

Option B (common real-world): You cannot reach <localip> directly from your laptop (that’s the point). In that case, copy the key through the gatekeeper:

cat ~/.ssh/id_ed25519.pub | ssh -p 422 soulevil@&lt;wanip> "ssh soulevil@&lt;localip> 'mkdir -p ~/.ssh &amp;&amp; chmod 700 ~/.ssh &amp;&amp; cat >> ~/.ssh/authorized_keys &amp;&amp; chmod 600 ~/.ssh/authorized_keys'"

Step 4 — Create 

~/.ssh/config

On your laptop:

nano ~/.ssh/config

Add:

Host gatekeeper
    HostName &lt;wanip>
    User soulevil
    Port 422
    IdentityFile ~/.ssh/id_ed25519

Host workstation
    HostName &lt;localip>
    User soulevil
    IdentityFile ~/.ssh/id_ed25519
    ProxyJump gatekeeper

Fix permissions:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/config

Now connect:

ssh workstation

That’s it.

What Each Line Means

Gatekeeper block

  • Host gatekeeper: nickname you use in commands (ssh gatekeeper)
  • HostName <wanip>: actual IP/DNS
  • User soulevil: default username
  • Port 422: your custom SSH port
  • IdentityFile: which SSH key to use

Workstation block

  • HostName <localip>: private IP (only gatekeeper can reach)
  • ProxyJump gatekeeper: “to reach workstation, hop via gatekeeper”

Handy Commands You’ll Actually Use

Check the full resolved config

ssh -G workstation | head -n 50

Verbose debug (when it fails)

ssh -vvv workstation

One-off jump without config

ssh -J soulevil@&lt;wanip>:422 soulevil@&lt;localip>

File Copy Through the Jump Host

scp

 via ProxyJump (modern)

scp -o ProxyJump=gatekeeper ./file.txt workstation:/tmp/

rsync

 via SSH jump

rsync -av -e "ssh -J gatekeeper" ./mydir/ workstation:/var/www/mydir/

Port Forwarding Through the Jump Host

Forward a workstation service to your laptop

Example: workstation has a web app on localhost:8080 (from workstation’s point of view)

ssh -J gatekeeper -L 8080:127.0.0.1:8080 workstation

Then open on your laptop:

  • http://127.0.0.1:8080

Forward a database port

ssh -J gatekeeper -L 3306:127.0.0.1:3306 workstation

Now your laptop can connect to MySQL as if it’s local.

Security Hardening Checklist (Strongly Recommended)

On 

gatekeeper

  • Disable password auth (use keys only)
  • Disable root SSH login
  • Add fail2ban or rate-limits
  • Restrict by firewall (allow SSH only from your IP/VPN if possible)
  • Consider 2FA (e.g., PAM Google Authenticator) for the bastion

Typical /etc/ssh/sshd_config ideas:

  • PasswordAuthentication no
  • PermitRootLogin no
  • PubkeyAuthentication yes

Restart SSH after changes (carefully):

sudo systemctl restart ssh

On 

workstation

  • Keep it LAN-only
  • Allow SSH only from gatekeeper’s LAN IP (firewall rule)
  • Keys only

Common Problems & Fixes

1) “Permission denied (publickey)”

  • Your key isn’t installed on gatekeeper/workstation
  • Wrong User
  • Wrong IdentityFile
  • Bad permissions on remote:
    • ~/.ssh should be 700
    • authorized_keys should be 600

2) “Connection timed out” to workstation

  • Gatekeeper can’t reach <localip>
  • Wrong network route/VLAN
  • Workstation firewall blocks SSH from gatekeeper

Test from gatekeeper:

ssh soulevil@&lt;localip>

3) Custom port only on gatekeeper

That’s normal. Your workstation can stay on default port 22 on LAN.

Bonus: Multiple Environments Pattern

You can scale this cleanly:

Host gatekeeper-prod
    HostName &lt;prod-wan-ip>
    User soulevil
    Port 422

Host prod-app-1
    HostName 10.0.10.11
    User soulevil
    ProxyJump gatekeeper-prod

Now ssh prod-app-1 just works.

Summary

  • ProxyJump is the simplest, cleanest way to do a jump host in OpenSSH.
  • You harden one public server (gatekeeper) and keep internal servers private.
  • Your daily workflow becomes one command: ssh workstation.

If you want, paste your real topology (gatekeeper LAN IP/subnet + workstation subnet + firewall rules you use), and I’ll give you a “locked down” config example (firewall + sshd_config) that still stays convenient for daily dev work.

If you are interested in network security and system integration, you can also explore our detailed guide on OAuth 1.0 vs OAuth 2.0 Process Flow and Key Differences to secure your application architecture.

Pages: 1 2