SSH is the backbone of working with remote Linux servers. You’re not using it right if you’re still typing passwords. Here’s the complete flow: generate a key, get it on the server, configure your client, and then move files securely.
Generating SSH Keys
You want ed25519 keys. They’re smaller, faster, and more secure than RSA. If your target server is ancient (pre-2014), fall back to RSA.
Ed25519 (modern servers — do this):
ssh-keygen -t ed25519 -C "you@laptop" -f ~/.ssh/id_ed25519The -C flag is just a comment. The -f flag specifies where to save it. When prompted for a passphrase, use one — your key file itself is encrypted on disk.
RSA (legacy servers):
ssh-keygen -t rsa -b 4096 -C "you@laptop" -f ~/.ssh/id_rsaThe -b 4096 sets the key size to 4096 bits (stronger than the 2048 default, and still fast). Anything under 2048 is obsolete — don’t bother.
You now have two files: ~/.ssh/id_ed25519 (private key — never share) and ~/.ssh/id_ed25519.pub (public key — safe to distribute).
Getting Your Public Key to the Server
The easy way:
ssh-copy-id handles all the fiddly details: it logs in (you’ll type your password one last time), appends your public key to ~/.ssh/authorized_keys on the server, and sets permissions correctly so SSH won’t complain.
If ssh-copy-id isn’t available (some Windows setups), do it manually:
cat ~/.ssh/id_ed25519.pub | ssh [email protected] "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"Now test passwordless login:
No password prompt? You’re done with auth. Close the connection and move on.
Configuring ~/.ssh/config
Stop typing ssh -p 2222 [email protected]. Create ~/.ssh/config:
Host homelab HostName 192.168.1.100 User username Port 2222 IdentityFile ~/.ssh/id_ed25519
Host production HostName prod.example.com User deploy IdentityFile ~/.ssh/id_rsa StrictHostKeyChecking accept-newNow you just type ssh homelab. SSH uses the right user, port, and key automatically. You can add multiple hosts — each gets its own section.
Common options:
HostName— the actual server address (IP or domain)User— username to log in as (overrides your local username)Port— non-standard SSH port if neededIdentityFile— which key to use for this hostStrictHostKeyChecking accept-new— skip the “are you sure?” prompt on first connection (but still verify host keys thereafter)
Copying Files with SCP
SCP (secure copy) works like cp, except it can reach across the network over SSH.
Remote to local:
Local to remote:
Recursive (directories):
The -r flag means “recursively copy everything inside.” No -r? SCP treats it as a file and fails.
Using a non-standard SSH port:
Note: it’s -P (capital), not -p. (Confusingly, ssh uses lowercase -p for ports. Different tools, different conventions.)
Host-to-host (remote to remote):
[email protected]:/backups/Copying multiple files:
Or use glob patterns:
Quick Cheatsheet
| Task | Command |
|---|---|
| Generate ed25519 key | ssh-keygen -t ed25519 -C "comment" -f ~/.ssh/id_ed25519 |
| Copy public key to server | ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host |
| SSH to a host | ssh user@host (or ssh hostname if in ~/.ssh/config) |
| Download a file | scp user@host:/path/file ~/local/ |
| Upload a file | scp ~/file user@host:/path/ |
| Copy a directory | scp -r ~/dir/ user@host:/path/ |
| Download on custom port | scp -P 2222 user@host:/file ~/ |
| Copy between remotes | scp user1@host1:/file user2@host2:/path/ |
That’s it. Keys, config, and file transfers — the foundation of working with remote machines. Your 2 AM self will appreciate never having to type a password again.
Using ssh-agent So You Don’t Retype Your Passphrase All Day
You followed the advice earlier and set a passphrase on your key — good. But now every ssh or scp invocation prompts for it. That gets old fast. ssh-agent solves this by holding your decrypted key in memory for the duration of your session.
Start the agent and add your key:
eval "$(ssh-agent -s)"ssh-add ~/.ssh/id_ed25519Enter your passphrase once. From that point on, every SSH operation in that terminal session goes through the agent — no more prompts. You can verify what keys are loaded with ssh-add -l.
On macOS the system already runs an agent, and you can persist the key across reboots with one extra flag:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519This stores the passphrase in the macOS Keychain so the key reloads automatically after a restart.
On Linux with a desktop session, most distros integrate with gnome-keyring or kwallet which handles this transparently once you log in. Headless servers? Add this to your ~/.bashrc or ~/.zshrc:
if [ -z "$SSH_AUTH_SOCK" ]; then eval "$(ssh-agent -s)" > /dev/null ssh-add ~/.ssh/id_ed25519 2>/dev/nullfiThe if guard prevents spawning a new agent process for every terminal you open — rookie mistake that leaves dozens of orphaned agent processes behind.
Common gotcha: if you cloned a repo or set up a server and SSH suddenly stops working after a reboot, the agent died with your session. Just run ssh-add again. Alternatively, look into keychain (the tool, not the macOS concept) — it persists a single agent across logins on Linux, which is exactly what you want on a dev box you log into repeatedly.