SSH Cheatsheet
Troubleshooting
Use this SSH reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
First Steps: Verbose Mode
Always start here. Add -v flags to get a detailed trace of what SSH is doing.
ssh -v user@host # basic debug ssh -vv user@host # more detail ssh -vvv user@host # maximum detail (key offers, channel ops, etc.)
Read the output from the top — it shows each phase: DNS, TCP connect, version exchange, key exchange, authentication offers.
Common Errors and Fixes
| Error | Cause | Fix |
|---|---|---|
Connection refused | sshd not running, wrong port | Check port with -p; verify systemctl status sshd on server |
Connection timed out | Firewall blocking port 22 | Check firewall; try -v to see where it hangs |
Permission denied (publickey) | Key not in authorized_keys, wrong perms, wrong key offered | See auth section below |
Permission denied (publickey,password) | Password auth disabled and key not accepted | Verify key is in authorized_keys |
Host key verification failed | Server host key changed | Run ssh-keygen -R host then reconnect |
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! | Same as above (or MITM) | Verify the new fingerprint out-of-band, then ssh-keygen -R host |
No such file or directory (socket) | Control socket stale | Delete the stale socket file under ~/.ssh/ |
Too many authentication failures | Agent offering too many keys | Use -o IdentitiesOnly=yes -i key |
Could not resolve hostname | DNS failure | Try IP directly; check /etc/hosts |
Broken pipe | Idle connection dropped | Add ServerAliveInterval 60 |
channel 0: open failed: administratively prohibited | TCP forwarding disabled on server | Set AllowTcpForwarding yes in sshd_config |
bind: Address already in use | Local port taken (tunnel conflict) | Change local port or kill the process using it |
Diagnosing Authentication Failures
# Show which keys the client is offering ssh -vvv user@host 2>&1 | grep -E "Offering|Trying|key:|identity" # Force only a specific key (bypass agent) ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 user@host # Skip the config file entirely ssh -F /dev/null user@host # Try password auth explicitly ssh -o PreferredAuthentications=password user@host
On the server, check the auth log:
# Debian/Ubuntu tail -f /var/log/auth.log | grep sshd # RHEL/CentOS/Fedora journalctl -u sshd -f # Look for permission errors grep "Authentication refused\|bad ownership" /var/log/auth.log
Permission Problems
# Fix all at once chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys chmod 600 ~/.ssh/id_ed25519 chmod 644 ~/.ssh/id_ed25519.pub chmod 600 ~/.ssh/config # Verify ownership (must be the user, not root) ls -la ~/.ssh/
SSH silently rejects keys if ~/.ssh or authorized_keys is writable by group/other, or not owned by the user.
Stale Host Keys
# Server reimage / key rotation / new VM ssh-keygen -R hostname ssh-keygen -R 192.168.1.10 # Or edit manually nano ~/.ssh/known_hosts # delete the line for the host
Testing sshd Config
# Syntax check without restarting sudo sshd -t # Run in foreground on a test port (safe — doesn't replace your main sshd) sudo /usr/sbin/sshd -ddd -p 2222
Then connect ssh -p 2222 user@localhost and watch both sides for detailed output.
Network Diagnostics
# Confirm sshd is listening ss -tlnp | grep :22 # Linux netstat -an | grep .22 # macOS/older # Test TCP reachability nc -zv host 22 telnet host 22 # Trace the route traceroute host mtr host # Check if a firewall is blocking nmap -p 22 host
Slow Login
# DNS reverse lookup causing delay (common cause) # In /etc/ssh/sshd_config: UseDNS no # GSSAPI delay (Kerberos lookup timing out) # In /etc/ssh/sshd_config: GSSAPIAuthentication no # Or on the client: ssh -o GSSAPIAuthentication=no user@host
Debugging Tunnels and Forwarding
# Confirm tunnel is listening ss -tlnp | grep PORT # Linux lsof -iTCP:PORT -sTCP:LISTEN # macOS # Check the tunnel is routing correctly curl -v http://localhost:LOCAL_PORT # Kill a specific tunnel by control socket ssh -S ~/.ssh/cm-user@host -O cancel -L 5432:db:5432 user@host
Useful One-Liners
# Fingerprint of a server you haven't connected to yet ssh-keyscan host | ssh-keygen -lf - # Which config block matches a host ssh -G user@host | head -20 # Print the effective config for a host alias ssh -G myalias