Skip to content

Can't SSH In or Locked Out

Losing SSH access is stressful, but the exact error message is a precise diagnostic. Each one points at a different layer — the daemon, the firewall, authentication, or fail2ban — so read it carefully before you touch anything.

Tested on

AlmaLinux 9 / RHEL 9. Notes for Debian/Ubuntu are called out inline. On RHEL-family the SSH log is /var/log/secure; on Debian/Ubuntu it is /var/log/auth.log and the service may be named ssh rather than sshd.

Symptom

You run ssh user@host and it fails. The specific failure differs:

  • ssh: connect to host ... port 22: Connection refused
  • ssh: connect to host ... port 22: Connection timed out
  • Permission denied (publickey) or Permission denied (publickey,password)
  • Connection reset by peer, or it worked a moment ago and now hangs/rejects repeatedly

The error tells you which section below to jump to.

Likely causes

Error Most likely cause
Connection refused sshd not running, or listening on a different port
Connection timed out Firewall, cloud security group, or routing blocks the packet
Permission denied (publickey) Wrong key, bad permissions, or server auth policy
Connection reset / repeated failures Banned by fail2ban

Get a console first

Most fixes below run on the server. If SSH is your only way in, open the provider's console / out-of-band access (KVM, serial console, cloud "VNC console", IPMI) before you start.

Diagnose

Client side — see exactly what SSH negotiates

ssh -vvv user@host

Read the verbose output: it shows the port and IP it dials, which keys it offers (Offering public key:), and where authentication stops. This alone usually identifies the layer.

Server side — via console

# Is the daemon up and which port is it on?
sudo systemctl status sshd
sudo ss -tlnp | grep ssh        # confirm it is LISTEN on the expected port

# What does the auth log say? (Debian/Ubuntu: /var/log/auth.log)
sudo journalctl -u sshd -e
sudo tail -n 50 /var/log/secure

Always validate config before reloading

A typo in sshd_config can stop the daemon from starting and finish your lockout. Validate first, every time:

sudo sshd -t        # silent = OK; prints the offending line on error

"Connection refused" → sshd down or wrong port

The host is reachable but nothing is listening on that port. From the console:

sudo systemctl status sshd
sudo ss -tlnp | grep :22

Fix:

# Daemon stopped/crashed
sudo systemctl start sshd
sudo systemctl enable --now sshd

# sshd listens on a non-standard port — connect to the right one
sudo grep -i '^Port' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf
ssh -p 2222 user@host

If it crashed, sudo sshd -t and journalctl -u sshd will show why.


"Connection timed out" → firewall, security group, or network

Packets never reach the daemon. Check each gate from outermost to innermost:

# Host firewall (RHEL/Alma uses firewalld)
sudo firewall-cmd --list-all

# Or nftables/iptables directly
sudo nft list ruleset
sudo iptables -L -n -v

Then verify the cloud security group / network ACL in your provider console allows TCP 22 (or your port) from your source IP, and that routing/NAT to the host is intact (ip route, provider route tables).

Debian/Ubuntu

These commonly use UFW: sudo ufw status verbose.

Fix — open the port on firewalld:

sudo firewall-cmd --permanent --add-service=ssh
# Or for a custom port:
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

See Firewalls for the full firewalld/UFW workflow.


"Permission denied (publickey)" → key or auth policy

The connection succeeds but authentication fails. Causes, in order of frequency:

  1. Wrong / missing key. ssh -vvv shows which keys are offered. Point at the right one explicitly:

    ssh -i ~/.ssh/id_ed25519 user@host
    
  2. Permissions too open. sshd refuses keys if the files are group/other-writable. On the server (or wherever the user logs in):

    chmod 700 ~/.ssh
    chmod 600 ~/.ssh/authorized_keys
    chmod 644 ~/.ssh/*.pub
    # Home directory must NOT be group- or world-writable
    chmod go-w ~
    ls -ld ~ ~/.ssh
    
  3. Server policy blocks you. Check on the server:

    sudo sshd -T | grep -iE 'passwordauthentication|pubkeyauthentication|allowusers|allowgroups|permitrootlogin'
    
    • PasswordAuthentication no means key-only — a password will never work.
    • AllowUsers / AllowGroups whitelist specific accounts; if yours is not listed, you are denied.
    • PermitRootLogin no blocks direct root login.
  4. SELinux context on authorized_keys (RHEL/Alma). After moving/restoring a home dir:

    restorecon -Rv ~/.ssh
    sudo ausearch -m avc -ts recent   # look for ssh-related denials
    

Fix: correct the permissions, use the right key, or adjust the policy in a drop-in:

sudo vi /etc/ssh/sshd_config.d/99-local.conf
# e.g. AllowUsers deepak admin
sudo sshd -t && sudo systemctl reload sshd

See SSH for key generation and config details.


"Connection reset" / repeated failures → banned by fail2ban

If it worked earlier and now resets or rejects you after a few tries, your IP is likely jailed.

sudo fail2ban-client status sshd        # lists "Banned IP list"

Fix — unban your address:

sudo fail2ban-client set sshd unbanip 203.0.113.10

See fail2ban to tune ban times and add your IP to ignoreip.

Fix

Pick the fix matching your error above. The universal safe pattern when changing SSH config:

sudo vi /etc/ssh/sshd_config.d/99-local.conf
sudo sshd -t                 # validate — do NOT skip
sudo systemctl reload sshd   # reload, not restart, keeps current sessions alive

reload re-reads config without dropping established connections — so a mistake won't instantly evict you.

Prevent

Never edit SSH from your only session

Keep a second SSH session open to the host while you change anything SSH-, firewall-, or PAM-related. After reload, open a brand-new session and confirm login works before closing the old one. If the new session fails, the old one is still your lifeline.

  • Always have console / out-of-band access (cloud VNC, KVM, IPMI, serial) configured and tested — it is independent of sshd and the network firewall.
  • Add your management IP to fail2ban ignoreip so you can never lock yourself out:

    # /etc/fail2ban/jail.local
    [DEFAULT]
    ignoreip = 127.0.0.1/8 ::1 203.0.113.10
    
  • Run sudo sshd -t before every reload, and prefer reload over restart.

  • Document the SSH port, allowed users/groups, and source IPs in your runbook.
  • Follow the Server Hardening Checklist so hardening changes are deliberate, not surprises.

Test yourself