Introduction / Why This Is Needed
The SSH Connection refused error is one of the most common when attempting to remotely connect to a Linux server. It means that no process is listening on TCP port 22 (or another port you specified) on the target host. This is not a general network problem (ping may work), but specifically the unavailability of the SSH service.
In this guide, you will learn how to systematically diagnose and eliminate the cause, restoring secure remote access. We will cover checking the service, network settings, firewall, and the SSH configuration itself.
Requirements / Preparation
Before you begin, ensure that:
- You have local access to the target host (console, KVM, IPMI) or through an alternative management channel (e.g., a cloud provider's web console).
- You possess superuser (sudo) privileges on the target host to check services and modify configuration.
- The SSH client (
ssh) is installed on your client machine.
Step-by-Step Instructions
Step 1: Check the SSH Service Status
The first thing to do is ensure that the SSH daemon (sshd) is running.
# For most modern distributions (RHEL, CentOS, Fedora, Ubuntu 22.04+)
sudo systemctl status sshd
# For older Debian/Ubuntu (service name may be 'ssh')
sudo systemctl status ssh
What to look for in the output:
active (running)— the service is running.inactive (dead)orfailed— the service is stopped or fails to start.
If the service is not running:
sudo systemctl start sshd # Start it now
sudo systemctl enable sshd # Enable autostart
Step 2: Check if the System is Listening on Port 22
Even if the service is running, it might be listening only on the local interface (127.0.0.1), which would block external connections.
sudo ss -tlnp | grep -E ':22|:ssh'
Or
sudo netstat -tlnp | grep ':22'
Critical output: In the Local Address:Port column, you should see 0.0.0.0:22 (for IPv4) or [::]:22 (for IPv6). If it shows 127.0.0.1:22 — SSH is listening for local connections only.
Step 3: Check Firewall Settings
Modern Linux uses firewalld (RHEL/Fedora/CentOS) or ufw (Ubuntu/Debian). Incorrect rules are a frequent cause of Connection refused.
For firewalld:
sudo firewall-cmd --list-all
Ensure that ssh is listed under services: or 22/tcp is listed under ports:.
To add a rule (if missing):
sudo firewall-cmd --add-service=ssh --permanent
sudo firewall-cmd --reload
For ufw:
sudo ufw status verbose
Look for 22/tcp (ssh) in the Allow list.
To allow it:
sudo ufw allow ssh
# or explicitly by port
sudo ufw allow 22/tcp
Step 4: Check the SSH Configuration File
Open the main daemon configuration file: /etc/ssh/sshd_config.
sudo nano /etc/ssh/sshd_config
What to pay attention to:
Port 22— ensure the port is not commented out and is set to 22 (or the port you are using).ListenAddress— if this directive is present and specifies127.0.0.1or::1, SSH will only listen for local connections. Comment out this line or set it to0.0.0.0(for all IPv4 interfaces).PermitRootLogin,PasswordAuthentication— these parameters affect authentication, not the fact of port listening. However, check them later if the connection establishes but fails authentication.
After making changes:
sudo sshd -t # Check config syntax (without restarting the service)
If the output is empty — the syntax is correct.
Step 5: Restart the SSH Service
Apply all changes by restarting the daemon.
sudo systemctl restart sshd
# Check the status again to confirm a successful restart
sudo systemctl status sshd
Verifying the Result
From your client machine, try to connect again:
ssh username@server_ip_address
If the connection is established, the problem is solved. If you changed the standard port, specify it with the -p flag:
ssh -p 2222 username@server_ip_address
Additional verification using telnet or nc:
telnet server_ip_address 22
# or
nc -zv server_ip_address 22
A successful connection will show that the port is open and the SSH daemon is serving.
Potential Issues
- SELinux/AppArmor is blocking SSH. On SELinux systems (RHEL/CentOS/Fedora), check logs:
sudo ausearch -m avc -ts recent. Temporary disable for testing:sudo setenforce 0. If the problem disappears, you need to adjust the SELinux policy, not leave it disabled. - Double NAT or cloud Security Group. If the server is in a cloud (AWS, GCP, Azure), ensure that Security Group / Firewall Rules in the cloud's control panel allow inbound traffic on port 22 from your IP address. This is a common cause when everything is configured correctly on the virtual machine itself.
- SSH daemon is listening only on IPv6, while the client tries IPv4. Check the
ss -tlnpoutput. If you see only[::]:22and not0.0.0.0:22, addListenAddress 0.0.0.0tosshd_config. - Port conflict. Ensure no other process is using port 22:
sudo lsof -i :22. - Configuration errors after editing. If
sshdcrashes after restart, check the logs:sudo journalctl -u sshd -n 50 --no-pager. Common errors: incorrect permissions on key files (/etc/ssh/ssh_host_*), invalid directives.