SSH connection failures are usually caused by a breakdown in the authentication or transport layer, leaving you staring at a "Connection refused" or "Permission denied" message.
Let’s walk through diagnosing a stubborn SSH connection.
1. Is the SSH Server Actually Running?
This is the most basic, yet frequently overlooked, issue. The SSH daemon (sshd) might have crashed, been stopped, or never started in the first place.
Diagnosis: On the server you’re trying to connect to, run:
sudo systemctl status sshd
or if you’re on an older system:
sudo service ssh status
Fix: If it’s not active, start it:
sudo systemctl start sshd
or:
sudo service ssh start
Then, enable it to start on boot:
sudo systemctl enable sshd
Why it works: This ensures the sshd process is listening on the network, ready to accept incoming connections on the default port 22.
2. Is a Firewall Blocking Port 22?
Even if sshd is running, a firewall on the server, your client, or anywhere in between can silently drop packets destined for port 22.
Diagnosis: On the server, check ufw (Uncomplicated Firewall) if you use it:
sudo ufw status
If ufw is active and port 22 is not listed as allowed, that’s your culprit. On systems using firewalld:
sudo firewall-cmd --list-all
Look for ssh or port 22/tcp in the services or ports list.
Fix: For ufw:
sudo ufw allow ssh
or explicitly:
sudo ufw allow 22/tcp
For firewalld:
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload
Why it works: These commands explicitly instruct the firewall to permit incoming TCP traffic on port 22, allowing SSH packets to reach the daemon.
3. Incorrect Hostname or IP Address
A simple typo in the hostname or IP address will lead to a connection attempt to a non-existent or incorrect destination.
Diagnosis: Double-check the hostname or IP address you’re using in your ssh command. Try pinging it from your client:
ping your_server_hostname_or_ip
If ping fails, the address is wrong or unreachable.
Fix: Correct the hostname or IP address in your ssh command. Ensure DNS resolution is working correctly if using a hostname.
Why it works: This ensures your SSH client is attempting to connect to the actual IP address where the sshd server is listening.
4. SSH Daemon Configuration Issues (sshd_config)
The sshd_config file on the server dictates many aspects of SSH server behavior, including the port it listens on and which users are allowed to connect.
Diagnosis: Examine the /etc/ssh/sshd_config file on the server. Key parameters to check:
Port: Ensure it’s set to22(or whatever port you’re trying to connect to). If it’s commented out (#Port 22), it defaults to 22.ListenAddress: If this is set to a specific IP,sshdwill only listen on that IP. If it’s0.0.0.0, it listens on all interfaces.AllowUsers/DenyUsers/AllowGroups/DenyGroups: Check if your username or group is explicitly denied or not included in anAllowUserslist.
Fix: Edit /etc/ssh/sshd_config with sudo nano /etc/ssh/sshd_config. Correct any misconfigurations, uncomment lines if necessary, and save the file. After making changes, you must reload the SSH service:
sudo systemctl reload sshd
Why it works: This applies the corrected configuration parameters, ensuring sshd is listening on the expected port and interface, and respects user access controls.
5. Host Key Verification Issues
When you connect to an SSH server for the first time, your client stores the server’s public host key. If the server’s key changes (e.g., after a reinstall), your client will refuse to connect to prevent man-in-the-middle attacks.
Diagnosis: Your client will typically show a message like:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY...
...
The authenticity of host 'your_server_hostname_or_ip (xxx.xxx.xxx.xxx)' can't be established.
ECDSA key fingerprint is SHA256:....
Are you sure you want to continue connecting (yes/no/[fingerprint])?
The offending key is stored in your ~/.ssh/known_hosts file.
Fix: Remove the old entry from your ~/.ssh/known_hosts file. You can do this manually with nano ~/.ssh/known_hosts and deleting the line corresponding to the server, or use the ssh-keygen command:
ssh-keygen -R your_server_hostname_or_ip
Then, attempt to connect again. You’ll be prompted to accept the new key.
Why it works: Removing the old key entry from known_hosts allows your SSH client to accept the server’s new public key as legitimate, re-establishing trust.
6. Authentication Failures (Password/Key Issues)
If you get past the initial connection and receive a "Permission denied" error, it’s usually an authentication problem.
Diagnosis:
- Password: Ensure you’re typing the correct password. Check
/etc/ssh/sshd_configforPasswordAuthentication yes. If it’sno, passwords are disabled. - SSH Keys:
- On the server, check
/etc/ssh/sshd_configforPubkeyAuthentication yes. - Ensure your public key (
~/.ssh/id_rsa.pubor similar) is correctly added to the server’s~/.ssh/authorized_keysfile for the user you’re logging in as. - Check permissions on the server:
~/.sshdirectory should be700, and~/.ssh/authorized_keysshould be600.
- On the server, check
Fix:
- Password: Enable
PasswordAuthentication yesinsshd_config(if desired and secure), thensudo systemctl reload sshd. - SSH Keys:
- Copy your public key to the server’s
~/.ssh/authorized_keysfile. - On the server, run:
chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys - Ensure the
authorized_keysfile contains the exact content of your public key.
- Copy your public key to the server’s
Why it works: Correctly configured public key authentication bypasses the need for a password, and strict file permissions prevent unauthorized modification of your authorized keys.
7. Resource Exhaustion on the Server
A server overloaded with processes or memory can become unresponsive, leading to connection timeouts or refusals.
Diagnosis: On the server, check system load and memory usage:
top
or:
htop
Look for high CPU utilization (%CPU) or processes consuming excessive memory (%MEM). Also, check dmesg for kernel-level errors.
Fix: Identify and stop runaway processes, or increase server resources (RAM, CPU) if consistently overloaded.
Why it works: Releasing system resources allows the sshd daemon to respond to new connection requests promptly.
After resolving these, you might encounter issues with PAM (Pluggable Authentication Modules) if your sshd_config has specific PAM directives.