30-Second Fix: Is the SSH Daemon Even Running?
I've lost count of the times I've walked up to a server, tried to SSH in, and got Connection refused. The first thing that pops into your head is probably "firewall" or "network." But 8 times out of 10, it's simpler than that: the SSH daemon isn't running.
Check it before you touch anything else. On systemd systems (that's Ubuntu 15.04+, CentOS 7+, Debian 8+, all the modern ones), run:
sudo systemctl status sshdOn older SysV init systems, it's:
sudo service sshd statusIf it's not running, start it and enable it so it comes back after a reboot:
sudo systemctl start sshd
sudo systemctl enable sshdThat's the 30-second fix. If the daemon was stopped, you're done. Move on with your life.
5-Minute Fix: Firewall Blocking Port 22
If sshd is running fine and you still get refused, the next suspect is the firewall. Now, if you're on a cloud server (AWS, DigitalOcean, Azure), don't forget the security group / network security group. That's a firewall too, and it sits outside your OS. I've seen people chase OS firewalls for an hour when the real blocker was an AWS security group rule. Check that first.
On the server itself, look at what firewall is active. Most Linux systems use ufw or firewalld now.
For ufw (Ubuntu, Debian):
sudo ufw statusIf it's active and port 22 isn't allowed, add it:
sudo ufw allow 22/tcp
sudo ufw reloadFor firewalld (CentOS, RHEL, Fedora):
sudo firewall-cmd --state
sudo firewall-cmd --list-allIf port 22 isn't listed, add it permanently:
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reloadIf you're using iptables directly (old school, or you've got a custom setup), check with sudo iptables -L -n and look for a DROP or REJECT rule on port 22.
Don't Forget the Router (If You're Not in the Cloud)
If this is a home or office server behind a NAT, port forwarding needs to point to the right internal IP. And your public IP might have changed if you don't have a static IP. That's a bigger topic, but worth a quick check if you're not in the cloud.
15-Minute Fix: Network Misconfiguration or SSH Config Issues
If the daemon's running and the firewall's open, it's time to dig deeper. Here's what I've seen bite people:
SSH Is Listening on the Wrong Interface or Port
Maybe sshd is running but it's only listening on localhost. That happens when someone messed with the config. Check:
sudo netstat -tlnp | grep sshdYou want to see something like 0.0.0.0:22 or :::22. If you see 127.0.0.1:22, that's your problem. The fix is in /etc/ssh/sshd_config — look for a line like ListenAddress. Comment it out or set it to 0.0.0.0. Also, someone might have changed the port. If it's not 22, you'll need to specify it with ssh -p <port>.
Fail2ban or Similar Tools Are Blocking You
Fail2ban is great at stopping brute-force attacks, but it can also lock you out if you've triggered it. Check if it's running:
sudo fail2ban-client statusIf you see your IP in a banned list, unban it with:
sudo fail2ban-client set sshd unbanip <your-ip>And check the jail rules — maybe the bantime is too aggressive.
TCP Wrappers (If You're on Old School Linux)
This is rare now, but if you're on an older server, check /etc/hosts.deny. If your IP is in there, you're getting refused no matter what. Remove it.
Client-Side Issues You Might Have Missed
Here's the thing — the error message says "Connection refused," but sometimes it's not the server at all. You might be trying to connect to the wrong IP or hostname. Verify you're hitting the right machine:
ping <hostname-or-ip>If that works, try a quick port check:
nc -vz <hostname-or-ip> 22If that says Connection refused, it's a server-side issue. If it times out, you're dealing with a firewall drop — which is a different beast. Also, if you're using a custom port, make sure you're passing -p <port> on the command line. And yes, I've seen people forget that for days.
When All Else Fails: Check the Logs
Don't go in circles. The server logs will tell you exactly what's happening. Look at:
sudo tail -f /var/log/auth.logor on CentOS/RHEL:
sudo tail -f /var/log/secureYou'll see lines like Connection refused or Failed password if it's an auth issue. And if sshd is crashing on startup, journalctl -u sshd will show you why. This is where you separate the real issue from a guess.
One more thing — if you've made changes to sshd_config, always test the config before restarting:
sudo sshd -tThat'll catch syntax errors before you lock yourself out.
Final Thoughts
The order matters. Don't jump to the network rabbit hole before checking the daemon. And if you're on AWS or Azure, remember the security group. I've had days where the OS was perfect but the security group rule was missing. That's a 2-minute fix once you know where to look.
If you've gone through all of this and still get refused, post your sshd_config (minus the secrets) and the relevant log lines to a forum. Nine times out of ten, someone will spot the issue immediately.