SSH and Key-Based Authentication
SSH (Secure Shell) is the protocol you use to log into remote Linux machines. The right way to use it is with key-based authentication — generate a keypair once, copy the public key to your servers, and never type a password again. Plus your servers are dramatically harder to brute-force.
Connect to a server
ssh user@server.com # password prompt by default
ssh -p 2222 user@server.com # custom port
ssh -i ~/.ssh/special-key user@server.com # specific key file
Generate an SSH key
Modern recommendation: ed25519 (smaller, faster, secure):
ssh-keygen -t ed25519 -C "your_email@example.com"
Press Enter to accept the default location (~/.ssh/id_ed25519). Set a passphrase OR leave blank for no-prompt key.
This creates two files:
~/.ssh/id_ed25519— your private key. NEVER share. Treat like a password.~/.ssh/id_ed25519.pub— your public key. Safe to share. Goes on every server.
Copy your key to a server
Easiest way:
ssh-copy-id user@server.com
Type your password one last time. Now your public key is on the server in ~/.ssh/authorized_keys.
Manual way:
cat ~/.ssh/id_ed25519.pub | ssh user@server.com 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys'
Now log in — no password:
ssh user@server.com
Use ssh-agent (cache the key)
If you set a passphrase on your key, ssh-agent caches it for the session:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519 # type passphrase ONCE
# now SSH uses the cached key automatically
The ~/.ssh/config file
Stop typing long ssh commands. Set per-host shortcuts:
# ~/.ssh/config
Host myserver
HostName 198.51.100.42
User alice
Port 2222
IdentityFile ~/.ssh/special-key
Host *.example.com
User deploy
ForwardAgent yes
Host github.com
User git
IdentityFile ~/.ssh/github-key
Now ssh myserver just works. scp myfile myserver: works. Everything that uses ssh inherits these settings.
Common SSH operations
Run one command without an interactive shell
ssh user@server "uname -a"
ssh user@server "tail -f /var/log/syslog"
ssh user@server "df -h" | grep "/$"
Copy files
scp file.txt user@server:/tmp/
scp -r project/ user@server:/opt/
rsync -av project/ user@server:/opt/ # better for serious copies
SSH tunnel (port forwarding)
# Forward local 8080 to remote 80 (access remote service via localhost:8080)
ssh -L 8080:localhost:80 user@server
# Reverse: expose YOUR local port 3000 to the remote machine
ssh -R 3000:localhost:3000 user@server
# SOCKS proxy through the server (use as proxy in browser)
ssh -D 1080 user@server
Run X11 GUI apps remotely
ssh -X user@server
# now graphical apps you launch over SSH show on YOUR screen
Server-side: harden sshd
Edit /etc/ssh/sshd_config, then sudo systemctl reload sshd:
PermitRootLogin no # disallow direct root login
PasswordAuthentication no # require keys; no passwords
PubkeyAuthentication yes
Port 22 # change to non-default to reduce noise
AllowUsers alice bob # restrict who can log in
ClientAliveInterval 300 # disconnect idle clients after 5 min
Test from a SECOND terminal before disconnecting — if you misconfigured, you can fix it without locking yourself out.
Common mistakes
- Wrong permissions on
~/.ssh/id_ed25519— must be 600. Fix:chmod 600 ~/.ssh/id_ed25519. - Wrong permissions on
~/.ssh— must be 700. Fix:chmod 700 ~/.ssh. - Wrong permissions on the server’s
~/.ssh/authorized_keys— must be 600. - Pushing your PRIVATE key to a git repo. (Search GitHub for “id_ed25519” — terrifying.)
- Disabling password auth without testing your key auth FIRST.
Recover when locked out
If you can’t SSH in:
- Use the cloud provider’s web console / VNC.
- Boot from rescue mode and chroot to fix sshd_config.
- Check that ssh service is actually running: cloud-init or systemctl logs.
What to learn next
Once SSH is set up, the next layer is the firewall — controlling which ports are open and to whom. Up next.