Hitting a brick wall when trying to log into a remote machine is frustrating, especially when it halts critical deployments or emergency maintenance. When your terminal spits back an error stating that the connection was refused, it means the target machine actively rejected the incoming request rather than dropping it silently. This typically points to a sleeping daemon, a misconfigured port, a blocking firewall, or missing server software.
Let's fix it right now. We'll bypass the usual fluff and get straight into diagnosing why port 22 is slamming the door in your face, starting with local network verification and moving through daemon states, socket bindings, firewalls, and configuration adjustments.
Verify Network Reachability and Port Status
Before editing configuration files on the remote server, confirm whether the machine is actually reachable over the network and whether anything is listening on the target port.
Run a basic network ping test to ensure basic connectivity:
ping your_server_ip
If the server responds to ICMP packets, the network layer is fine. Next, check if port 22 is open and accepting TCP connections from your local machine using nc or telnet:
nc -zv your_server_ip 22
If this command returns a connection refused error instantly, it means the server's network stack is alive, but no process is listening on port 22. If the command hangs indefinitely, a firewall is likely dropping your packets entirely rather than rejecting them. For a deeper look at network tools and protocol troubleshooting, check the OpenSSH Project Documentation.
Check if the SSH Daemon is Running
The most common reason for a connection refusal is that the OpenSSH server daemon isn't running on the target machine. If you have physical access, console access via a cloud provider web terminal (like AWS EC2 Instance Connect or DigitalOcean Console), or serial access, log in locally.
Check the status of the SSH service with systemd:
sudo systemctl status ssh(orsshddepending on your Linux distribution)
If the service is stopped or inactive, start it immediately:
sudo systemctl start ssh
To ensure the daemon starts automatically every time the server reboots, enable it:
sudo systemctl enable ssh
If the service fails to start, check the system journal for clues using journalctl -u ssh -n 50. Syntax errors in configuration files are frequent culprits when a daemon refuses to start.
Inspect Socket Bindings and Active Ports
Sometimes systemd reports that the service is running, but it's bound to a loopback address or a non-standard port due to a stale configuration or a conflicting service. Verify what process is actually binding to port 22 by running this command on the server:
sudo ss -tulpn | grep :22
You should see an entry showing sshd listening on 0.0.0.0:22 or :::22. If you see nothing, or if it's bound exclusively to 127.0.0.1:22, external connections will be rejected.
If another service (such as an alternative dropbear instance or a custom application) has hijacked port 22, you'll need to stop that service or reconfigure SSH to use a different port.
Review and Fix SSH Configuration Files
If the daemon is running and bound correctly, examine the main configuration file located at /etc/ssh/sshd_config. Open it with your preferred text editor:
sudo nano /etc/ssh/sshd_config
Look for these critical directives:
- Port: Ensure this is set to
22(or whatever port you intend to use). If it's commented out with a#, it defaults to 22, but explicitly defining it avoids ambiguity. - ListenAddress: Ensure this is either commented out to listen on all interfaces or explicitly set to your server's public IP address. If it's set to
127.0.0.1, external connections will fail.
After making changes, always test the configuration for syntax errors before restarting the service:
sudo sshd -t
If the test passes cleanly, restart the daemon:
sudo systemctl restart ssh
Adjust Firewall and Security Group Rules
If your network checks show that packets are timing out or being dropped, firewalls are usually to blame. Depending on your Linux distribution, you might be running UFW, firewalld, or raw iptables.
If you are using UFW (common on Ubuntu and Debian):
- Check status:
sudo ufw status verbose - Allow SSH explicitly:
sudo ufw allow OpenSSHorsudo ufw allow 22/tcp
If you are using firewalld (common on RHEL, CentOS, and Fedora):
- Check active rules:
sudo firewall-cmd --list-all - Add SSH permanently:
sudo firewall-cmd --permanent --add-service=ssh - Reload firewall:
sudo firewall-cmd --reload
If your server runs inside a cloud environment like AWS, Google Cloud, or Azure, remember that host-level firewalls are only half the battle. You must also check your cloud provider's virtual firewall settings (Security Groups or Network Security Groups) to ensure inbound TCP traffic on port 22 is allowed from your client IP address. You can read more about hardening network security standards through the National Institute of Standards and Technology (NIST).
Diagnose with Verbose Client Output
When troubleshooting client-side connection drops, increase the verbosity of your SSH client command to output detailed debugging logs. This reveals exactly where the handshake fails:
ssh -vvv user@your_server_ip
Look through the output for lines indicating connection attempts, socket creation, and key exchange negotiations. If the client logs show Connection refused immediately after resolving the IP, the issue is strictly a closed port or a downed daemon on the remote end. If it hangs at Connecting to..., suspect a firewall drop or incorrect routing.
Frequently Asked Questions
Why does SSH say connection refused instead of permission denied?
Connection refused means the server's network stack actively rejected your TCP SYN packet because no application is listening on that port or a firewall rule explicitly rejected it. Permission denied means the server successfully accepted your connection, but your authentication credentials (password or SSH key) were rejected.
Can I change the default SSH port to fix security issues?
Moving SSH off port 22 reduces automated botnet brute-force noise in your auth logs, but it does not fix underlying security vulnerabilities. Always rely on disabling password authentication and enforcing public key cryptography for robust security.
What should I do if I locked myself out after editing sshd_config?
If you made a mistake in the configuration file and restarted the service, remote access will drop. You must log into the server via your cloud provider's out-of-band console, serial terminal, or physical IPMI interface, revert the configuration error, and restart the SSH service.
Why does my SSH connection drop randomly after working fine?
Random mid-session drops are usually caused by network idle timeouts or stateful firewalls dropping idle TCP connections. You can fix this by configuring the client-side keepalive settings in your ~/.ssh/config file by adding ServerAliveInterval 60.