You tightened SSH on your VPS, logged out to test it, and now you can't get back in. I've unlocked dozens of these tickets through the console, and the pattern is always the same: one hardening step applied without testing, then panic.
This guide walks you through the seven most frequent SSH hardening errors I see in production, the symptoms that surface, the root cause, and the exact fix for each. Test every change before you close your existing session.
Error 1: Permission denied (publickey) after disabling password auth
Symptoms
You set PasswordAuthentication no in sshd_config, restarted SSH, and now every login attempt returns Permission denied (publickey). Your password no longer works, and you never uploaded a key.
Root cause
Disabling password authentication before installing your public key on the server locks you out. The SSH daemon expects a valid keypair, finds none, and refuses the connection.
Fix
Log in through your hosting provider's web console or VNC. Generate a keypair on your local machine if you don't have one:
ssh-keygen -t ed25519 -C "[email protected]"
Press Enter to accept the default path. Copy the public key to the server:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your_vps_ip
If ssh-copy-id isn't available, manually append the public key:
cat ~/.ssh/id_ed25519.pub | ssh user@your_vps_ip "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
On the server, verify permissions:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Test key authentication from a second terminal before you enable PasswordAuthentication no. If the key logs you in, then edit /etc/ssh/sshd_config and restart.
Error 2: Connection timed out after changing the default port
Symptoms
You changed Port 22 to Port 2222 in sshd_config, restarted SSH, and now ssh user@your_vps_ip hangs for 60 seconds before timing out.
Root cause
Your SSH client still connects to port 22, but the daemon now listens on 2222. Or your firewall blocks the new port.
Fix
First, confirm the daemon listens on the new port. From the console:
sudo ss -tlnp | grep sshd
You should see a line like LISTEN 0 128 *:2222. If you see *:22, the config change didn't take or you forgot to restart:
sudo systemctl restart sshd
Next, verify your firewall allows the new port. For ufw:
sudo ufw allow 2222/tcp
sudo ufw reload
For firewalld:
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
For iptables directly:
sudo iptables -I INPUT -p tcp --dport 2222 -j ACCEPT
sudo iptables-save | sudo tee /etc/iptables/rules.v4
Now connect with the -p flag:
ssh -p 2222 user@your_vps_ip
Once confirmed, close the old port 22 rule. Keep one working session open until you test the new port from a fresh terminal.
Error 3: SSH key rejected with "invalid format" or "no mutual signature algorithm"
Symptoms
You generated a key, copied it to the server, but login fails with no mutual signature algorithm found or invalid format. Password fallback works, but key auth doesn't.
Root cause
Older key types like RSA 1024-bit or DSA are deprecated in recent OpenSSH versions. If your server runs OpenSSH 8.8 or newer, RSA keys using SHA-1 are rejected by default.
Fix
Regenerate your key using Ed25519 or a longer RSA key:
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_new
Or for RSA 4096:
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_new
Copy the new public key to the server:
ssh-copy-id -i ~/.ssh/id_ed25519_new.pub user@your_vps_ip
If you must use an old RSA key temporarily, you can re-enable RSA SHA-1 on the client side by adding this to ~/.ssh/config:
Host your_vps_ip
PubkeyAcceptedKeyTypes +ssh-rsa
HostkeyAlgorithms +ssh-rsa
Don't do this long-term. Upgrade the key instead.
Error 4: Root login disabled but no sudo user exists
So what if the port is open but SSH still refuses?
Symptoms
You set PermitRootLogin no, logged out, and realize your only account is root. You have no other user to SSH in as.
Root cause
Disabling root login before creating a non-root user with sudo privileges leaves you with no way in.
Fix
Access the server via console. Create a new user:
adduser deploy
Set a strong password when prompted. Add the user to the sudo group:
usermod -aG sudo deploy
On RedHat-based systems, use wheel instead:
usermod -aG wheel deploy
Copy your SSH key to the new user:
mkdir -p /home/deploy/.ssh
cp /root/.ssh/authorized_keys /home/deploy/.ssh/
chown -R deploy:deploy /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys
Test login as the new user from a second terminal:
ssh deploy@your_vps_ip
Verify sudo works:
sudo whoami
If it returns root, you're safe. Now you can set PermitRootLogin no and restart SSH.
Error 5: Fail2Ban locks you out after repeated typos
Symptoms
You mistyped your SSH password or key passphrase three times, and now every connection attempt immediately fails with Connection refused or hangs. The server doesn't even prompt for a password.
Root cause
Fail2Ban or a similar intrusion-prevention tool banned your IP after detecting failed login attempts.
Fix
Log in through the console. Check if your IP is banned:
sudo fail2ban-client status sshd
Look for your IP under "Banned IP list." Unban it:
sudo fail2ban-client set sshd unbanip YOUR_IP
If Fail2Ban isn't installed but you see drops in iptables:
sudo iptables -L INPUT -v -n | grep YOUR_IP
Remove the blocking rule:
sudo iptables -D INPUT -s YOUR_IP -j DROP
To prevent this, whitelist your office or home IP in Fail2Ban's jail configuration. Edit /etc/fail2ban/jail.local:
[DEFAULT]
ignoreip = 127.0.0.1/8 YOUR_STATIC_IP
Restart Fail2Ban:
sudo systemctl restart fail2ban
If you don't have a static IP, increase maxretry from 3 to 5 in the [sshd] section.
Error 6: SELinux blocks SSH key authentication
Symptoms
You're on a RedHat-based system (AlmaLinux, Rocky, CentOS Stream). Password auth works, but key auth fails with Permission denied (publickey) even though file permissions are correct.
Root cause
SELinux enforces mandatory access controls. If the .ssh directory or authorized_keys has the wrong security context, SSH won't read the keys even when Unix permissions are correct.
Fix
From the console, check the current context:
ls -Z ~/.ssh/authorized_keys
You should see ssh_home_t. If you see user_home_t or default_t, restore the correct context:
restorecon -Rv ~/.ssh
Verify:
ls -Z ~/.ssh/authorized_keys
If SELinux is in enforcing mode and you're still blocked, check the audit log:
sudo ausearch -m avc -ts recent | grep sshd
Look for denials related to ssh_home_t or read. The log will suggest a policy module to allow the access, but fixing the context usually resolves it.
To temporarily test if SELinux is the blocker, set it to permissive:
sudo setenforce 0
Try key auth again. If it works, the issue is SELinux context. Run restorecon and switch back to enforcing:
sudo setenforce 1
Error 7: sshd_config syntax error prevents SSH from starting
Symptoms
You edited sshd_config, ran systemctl restart sshd, and got Job for sshd.service failed. Now SSH won't start at all, and you can't connect.
Root cause
A typo, duplicate directive, or unsupported option in sshd_config causes the daemon to fail at startup.
Fix
Access the server via console. Test the config syntax:
sudo sshd -t
This prints the exact line number and error. Common mistakes:
PermitRootLoginspelled wrong or set to an invalid value (useyes,no,prohibit-password, orforced-commands-only)- Duplicate
PortorListenAddresslines - Unsupported options copied from outdated guides (e.g.,
Protocol 2is ignored in modern OpenSSH but sometimes triggers warnings)
Fix the reported line, then test again:
sudo sshd -t
When it returns no output, the config is valid. Restart SSH:
sudo systemctl restart sshd
Check status:
sudo systemctl status sshd
If it shows active (running), try connecting from a second terminal before you close the console session.
What to check before you lock yourself out
Every SSH hardening mistake I've diagnosed came down to the same root issue: applying changes without a fallback. Here's the checklist I follow:
- Keep one session open. Never test SSH changes from your only connection.
- Test incrementally. Change one directive, restart SSH, test from a second terminal. If it works, move to the next change.
- Verify firewall rules before you switch ports. Use
ss -tlnpto confirm the daemon binds to the new port, then update your firewall. - Copy your public key before you disable password auth. Test key login from a fresh session.
- Create a non-root sudo user before you disable root login. Test sudo access.
- Whitelist your IP in Fail2Ban if you have a static address.
- Run
sshd -tafter every/etc/ssh/sshd_configedit.
If you skip the test step, the console becomes your only recovery path.
Double-check these three things first
When SSH hardening fails, the fix usually lives in one of three places: file permissions on .ssh/authorized_keys, a firewall rule blocking the new port, or a Fail2Ban ban you triggered while testing. Check chmod 600 on the key file, confirm the daemon listens with ss -tlnp, and inspect Fail2Ban's ban list before you assume the config is wrong.
Hardening SSH protects your VPS, but the most common threat isn't an attacker—it's locking yourself out during setup. Test every change with a backup session, and you won't need the console.
