troubleshooting2025-07-12·10·5/348

SSH Connection Denied: Complete Troubleshooting Guide

Comprehensive guide to diagnosing and resolving SSH connection refused and permission denied errors on Linux servers, covering all common causes.

SSH Connection Denied: Complete Troubleshooting Guide

Losing SSH access to a remote server is one of the most stressful situations for any developer. Last month, I locked myself out of a production server by accidentally modifying sshd_config. This guide covers every common SSH denial scenario and its resolution.

Environment

  • Client: macOS Sonoma / Windows 11 with OpenSSH
  • Server: Ubuntu 22.04 LTS, OpenSSH_8.9p1
  • Authentication: Key-based (ed25519)
$ ssh -V
OpenSSH_9.4p1, LibreSSL 3.3.6

$ ssh admin@server.example.com -v
OpenSSH_9.4p1, LibreSSL 3.3.6
debug1: Reading configuration data /Users/joel/.ssh/config

The Problem

$ ssh admin@server.example.com
ssh: connect to host server.example.com port 22: Connection refused

# After switching to a different port:
$ ssh -p 2222 admin@server.example.com
admin@server.example.com: Permission denied (publickey).

Two different errors depending on the situation. Let us diagnose each one.

Analysis

Scenario 1: Connection Refused

This means the TCP connection itself is being rejected. The server is not listening on port 22, or a firewall is blocking it.

# Check if port 22 is open from outside
$ nmap -p 22 server.example.com
PORT   STATE  SERVICE
22/tcp closed ssh

# Check if sshd is running on the server (via console/b console)
$ sudo systemctl status sshd
● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
     Active: inactive (dead)

$ ss -tlnp | grep :22
# No output - sshd is not listening

Root cause: sshd service is stopped.

Scenario 2: Permission Denied (publickey)

The TCP connection succeeds, but authentication fails:

$ ssh -vvv admin@server.example.com
debug1: Offering public key: /Users/joel/.ssh/id_ed25519 RSA SHA256:abc123...
debug1: Server accepts key: /Users/joel/.ssh/id_ed25519 RSA SHA256:abc123...
debug1: Authentication succeeded (publickey).
Authenticated to server.example.com.
...
debug1: drow connection closed by remote host.
Connection closed by server.example.com port 22.

Or worse:

$ ssh -vvv admin@server.example.com
debug1: Offering public key: /Users/joel/.ssh/id_ed25519 RSA SHA256:abc123...
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
admin@server.example.com: Permission denied (publickey).

The key is offered but rejected.

Solution

Fix 1: Restart sshd Service

# On the server (via console/b console)
$ sudo systemctl start ssh
$ sudo systemctl enable ssh

# Verify
$ sudo systemctl status ssh
● ssh.service - OpenBSD Secure Shell server
     Active: active (running) since Sat 2025-07-12 10:00:00 WET; 5s ago

Fix 2: Check Firewall Rules

# UFW
$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
22/tcp                     DENY        Anywhere

# Allow SSH
$ sudo ufw allow 22/tcp
$ sudo ufw reload

# Or using iptables
$ sudo iptables -L -n | grep 22
Chain INPUT (policy DROP)
DROP  tcp  --  0.0.0.0/0  0.0.0.0/0  tcp dpt:22

$ sudo iptables -I INPUT -p tcp --dport 22 -j ACCEPT
$ sudo service iptables save

Fix 3: Verify SSH Key Permissions

# On the server
$ ls -la ~/.ssh/
drwx------ 2 admin admin 4096 Jul 12 10:00 .
drwxr-xr-x 5 admin admin 4096 Jul 12 10:00 ..
-rw------- 1 admin admin  570 Jul 12 10:00 authorized_keys
-rw------- 1 admin admin 2655 Jul 12 10:00 id_ed25519
-rw------- 1 admin admin  570 Jul 12 10:00 id_ed25519.pub

# Fix permissions if needed
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/id_ed25519
$ chmod 644 ~/.ssh/id_ed25519.pub

Fix 4: Check authorized_keys Content

$ cat ~/.ssh/authorized_keys
# Verify your public key is there and not malformed
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGnN3... joel@laptop

# Check for Windows line endings (CR LF)
$ file ~/.ssh/authorized_keys
~/.ssh/authorized_keys: ASCII text, with CRLF line terminators  # BAD

# Fix line endings
$ sudo apt install dos2unix
$ dos2unix ~/.ssh/authorized_keys

Fix 5: Verify sshd_config Settings

$ sudo grep -v '^#' /etc/ssh/sshd_config | grep -v '^$'
Port 22
ListenAddress 0.0.0.0
PermitRootLogin prohibit-password
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no

Critical settings to verify:

# These should be "yes" for key-based auth
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

# Check for DenyUsers or AllowUsers
$ sudo grep -i "deny\|allow" /etc/ssh/sshd_config
AllowUsers admin deploy
# Make sure your user is in the AllowUsers list

Fix 6: Restore from Backup After Config Mistake

If you modified sshd_config and cannot get back in:

# Via console/b console
$ sudo cp /etc/ssh/sshd_config.bak /etc/ssh/sshd_config
$ sudo systemctl restart ssh

# Or test config before restarting
$ sudo sshd -t
# No output means config is valid
$ sudo sshd -T | grep pubkeyauthentication
pubkeyauthentication yes

Fix 7: Handle StrictModes Issues

sshd's StrictModes checks ownership and permissions of home directory:

$ sudo sshd -T | grep strictmodes
strictmodes yes

# Home directory must be owned by the user
$ ls -la /home/
drwxr-xr-x  3 admin admin 4096 Jul 12 10:00 admin

# If ownership is wrong:
$ sudo chown -R admin:admin /home/admin
$ sudo chmod 755 /home/admin

Prevention Checklist

# 1. Always keep a backup console session open when modifying sshd_config
# 2. Test config changes before restarting:
$ sudo sshd -t && sudo systemctl restart ssh

# 3. Set up a monitoring script:
#!/bin/bash
if ! ss -tlnp | grep -q ":22 "; then
    echo "SSH is down! Restarting..." | logger -t ssh-monitor
    systemctl restart ssh
fi

Lessons Learned

  1. Always run sshd -t to validate configuration before restarting the service.
  2. Keep a secondary console (cloud provider web console) open when making SSH changes.
  3. File permissions matter - SSH is extremely strict about .ssh/ and authorized_keys permissions.
  4. Check firewall rules before assuming SSH configuration is the problem.
  5. Use ssh -vvv for verbose output to pinpoint exactly where authentication fails.

This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.