Skip to content

🔑 SSH Keys & Jump Hosts

Why Use Keys Instead of Passwords?

Password-based login has three major problems: brute-force attack risk, having to type it every time, and inconvenience for automation scripts. SSH key authentication uses asymmetric encryption, crushing passwords in both security and convenience.

bash
# Step 1: Generate a key pair locally
ssh-keygen -t ed25519 -C "your_email@example.com"
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):    ← Recommended to set a passphrase
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_ed25519
Your public key has been saved in /home/user/.ssh/id_ed25519.pub

# Step 2: Copy the public key to the server
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
Number of key(s) added: 1

# Now you can log in without a password
ssh user@server   # No more password prompt!

# View the public keys on the server
cat ~/.ssh/authorized_keys
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... your_email@example.com

⚠️ Note: ⚠️ Security hardening: After generating keys, it's recommended to disable password authentication on the server: /etc/ssh/sshd_config PasswordAuthentication noPubkeyAuthentication yes Then systemctl restart sshd. This way, even if the password is compromised, no one can log in.

SSH Config for Multi-Server Management

bash
# Edit ~/.ssh/config to create server aliases
cat >> ~/.ssh/config << 'EOF'
Host prod-web
    HostName 203.0.113.50
    User deploy
    Port 2222
    IdentityFile ~/.ssh/id_ed25519_prod

Host prod-db
    HostName 203.0.113.51
    User admin
    IdentityFile ~/.ssh/id_ed25519_prod

Host staging-*
    User staging
    IdentityFile ~/.ssh/id_ed25519_staging
    ForwardAgent yes
EOF

# Now connect using the alias
ssh prod-web          # Equivalent to ssh -p 2222 deploy@203.0.113.50
ssh prod-db           # Equivalent to ssh admin@203.0.113.51
scp file.txt prod-web:/tmp/   # Use aliases for file transfers too

SSH Jump Hosts (ProxyJump)

Your internal servers don't have public IPs and must be accessed through a jump host (bastion host). Previously you had to use ssh -t for a two-step jump, but now ProxyJump handles it in one line:

bash
# Scenario: local → jump host (bastion) → internal server

# Method 1: Direct jump from the command line
ssh -J user@bastion:22 user@internal

# Method 2: Add to SSH config (recommended, set it once and forget it)
cat >> ~/.ssh/config << 'EOF'
Host bastion
    HostName 203.0.113.1
    User admin

Host internal
    HostName 10.0.0.100
    User deploy
    ProxyJump bastion
EOF

# Now just ssh internal to tunnel through the jump host!
ssh internal
scp file.txt internal:/tmp/

# Multi-level jumps also work
Host deep-server
    HostName 10.0.1.50
    ProxyJump bastion,internal   # Jump through bastion first, then internal

💡 Tip: 💡 Agent Forwarding: If you want to use your local key on the jump host to operate internal servers (e.g., when running ssh internal with a local key), you need to enable ForwardAgent yes. However, note that Agent Forwarding has security risks — the root user on the jump host can hijage your key. A more secure alternative is ProxyJump (the key always stays local).