Chapter 2

SSH Keys & Agents

ed25519, authorized_keys, ssh-agent, passphrases.

Learning objectives

  • Generate Ed25519 key pairs and install public keys on servers
  • Use ssh-agent and macOS Keychain / Linux keyring
  • Apply passphrase and key rotation practices for Workshop Co.

Why keys beat passwords

Password authentication sends a secret over the network every login. Brute-force bots hammer port 22 worldwide. Public-key authentication uses cryptography: the server holds your public key; only your private key can prove you are Marcus.

Workshop Co. disables password login on production servers. Marcus's laptop holds the only private key — with a passphrase — for admin access.

Generate a key pair

# On Marcus's MacBook — Ed25519 recommended
ssh-keygen -t ed25519 -C "marcus@workshopco.ca" -f ~/.ssh/workshopco_ed25519

# Passphrase: yes, always — protects key if laptop stolen

This creates:

  • ~/.ssh/workshopco_ed25519 — private key (never share, chmod 600)
  • ~/.ssh/workshopco_ed25519.pub — public key (goes on servers)

Install public key on a server

# One-time, if password login still enabled on bastion
ssh-copy-id -i ~/.ssh/workshopco_ed25519.pub marcus@bastion.workshopco.ca

# Manual method — append pub key to server
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo "ssh-ed25519 AAAA... marcus@workshopco.ca" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

Worked example — Workshop Co. bastion

Marcus adds his key to the bastion LXC (CT 200 renamed to bastion role) and each VM's deploy user:

HostUserKey in authorized_keys
bastion.workshopco.camarcusMarcus laptop + backup YubiKey key
VM 110 web (via bastion)deploySame Marcus key
VM 120 db (via bastion)deploySame Marcus key

SSH agent

Typing a passphrase every connection is tedious. The ssh-agent holds decrypted keys in memory:

# macOS — add key and store in Keychain
ssh-add --apple-use-keychain ~/.ssh/workshopco_ed25519

# Linux — start agent and add
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/workshopco_ed25519

# List loaded keys
ssh-add -l
Key hygiene

One key per person, not one shared team key on a USB stick. When an employee leaves Workshop Co., remove their line from every authorized_keys — document hosts in a spreadsheet.

Try it yourself

Generate a lab key ~/.ssh/lab_ed25519. Write the exact command to connect using that key explicitly:

Answer
ssh -i ~/.ssh/lab_ed25519 user@hostname

Check your understanding

  1. Can you recover a lost private key from the server's authorized_keys?
  2. Why use Ed25519 instead of 4096-bit RSA in 2026?
Answers
  1. No — authorized_keys only has the public half. Generate a new key pair and replace the public key on servers.
  2. Ed25519 is faster, shorter keys, modern curve crypto — default recommendation for new keys.