SSH troubleshooting
Permission denied (publickey)
The server rejected your key. Confirm the public key is in the target user's
~/.ssh/authorized_keys, permissions are
700 on .ssh and 600 on
authorized_keys, and you're using the right key with
ssh -i. Check server logs:
grep sshd /var/log/auth.log.
Connection refused
Nothing is listening on the target port. Verify sshd is running
(systemctl status ssh), confirm the port in
/etc/ssh/sshd_config, and check firewalls
(ss -tlnp | grep ssh, security groups, iptables).
Tip: ssh vs sshd service name
Debian/Ubuntu use ssh; RHEL/CentOS use sshd as the
systemd unit name. Wrong name → “Unit not found” when you restart or check
logs: systemctl status ssh vs
systemctl status sshd,
journalctl -u ssh vs journalctl -u sshd.
Connection timed out
Network path issue — wrong IP, routing, or a firewall dropping packets.
Test with nc -zv host 22 or traceroute. Unlike
"refused", a timeout usually means the packet never reached sshd.
Host key verification failed
The server's host key changed — common after rebuilds or MITM (rare).
Verify the new fingerprint out-of-band, then remove the old entry:
ssh-keygen -R hostname. Do not blindly accept unknown keys in production.
Too many authentication failures
ssh-agent offered several keys and the server disconnected after max tries.
Specify the key explicitly: ssh -i ~/.ssh/right_key user@host,
or set IdentitiesOnly yes in ~/.ssh/config.
Works as root but not as deploy user
Check home directory ownership, SELinux context (RHEL), and that
authorized_keys belongs to the target user. Home dir must not be
group/world-writable. Review AllowUsers in sshd_config.
Wrong permissions on ~/.ssh
OpenSSH ignores keys if permissions are too open:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_ed25519
chown -R user:user ~/.sshLocked out after editing sshd_config
Always validate before reload and keep a backup session open:
sshd -t # syntax check
systemctl reload ssh # apply if test passesIf locked out, use console access (cloud serial console, IPMI, hypervisor) to fix the config and restart sshd.
Debugging workflow
1. Verbose client output
ssh -vvv -i ~/.ssh/key user@host2. Server-side auth log
tail -f /var/log/auth.log | grep sshd # Debian/Ubuntu
tail -f /var/log/secure | grep sshd # RHEL/CentOS3. Confirm listener and config
ss -tlnp | grep ssh
grep -E '^(Port|PermitRootLogin|PasswordAuthentication)' /etc/ssh/sshd_configBastion / jump host issues
When chaining through a bastion, test each hop separately:
ssh bastion # hop 1
ssh -J bastion user@internal # combined
# Or in ~/.ssh/config: ProxyJump bastionPractice scenarios
Hands-on SSH scenarios on live Linux VMs: ssh