hosting

How to fix ssh connection refused error on a VPS

3 min read
How to fix ssh connection refused error on a VPS

An SSH "Connection refused" error means your client can't establish a TCP connection to the server at all — the port is closed, the service isn't running, or something is blocking the traffic. Here's how to systematically diagnose and fix it.

1. Verify the SSH Service Is Actually Running

The most common cause is that the SSH daemon (sshd) has stopped or failed to start. Log into your VPS via your provider's web console (most VPS providers offer a browser-based emergency console for exactly this situation), then run:

sudo systemctl status sshd

If the service is stopped or failed, you'll see output like Active: inactive (dead) or Active: failed. Restart it with:

sudo systemctl restart sshd

Then check status again to confirm it's running. On Ubuntu and Debian, the service may be named ssh instead of sshd:

sudo systemctl restart ssh

On CentOS, AlmaLinux, or RHEL-based systems, the service is named sshd and the command above applies as written.

2. Confirm Which Port SSH Is Listening On

If the service is running but you're still getting refused, SSH may have been configured to listen on a non-standard port. Check the current configuration:

sudo grep -i port /etc/ssh/sshd_config

If the output shows something like Port 2222 instead of the default Port 22, you need to connect using that port explicitly:

ssh -p 2222 user@your-server-ip

You can also verify what ports sshd is actually bound to right now:

sudo ss -tlnp | grep sshd

The output will show the local address and port (e.g., 0.0.0.0:22 or :::22). If nothing shows up, the daemon isn't listening — go back to Step 1.

3. Check Your Firewall Rules

A running SSH service can still be unreachable if a firewall is dropping traffic before it arrives. Check ufw first on Ubuntu/Debian:

sudo ufw status

If the output shows Status: active and port 22 (or your custom SSH port) isn't listed as allowed, add it:

sudo ufw allow 22/tcp
sudo ufw reload

On CentOS/AlmaLinux using firewalld:

sudo firewall-cmd --list-all
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload

If you're using raw iptables, check the current rules:

sudo iptables -L INPUT -n --line-numbers

Look for a DROP or REJECT rule targeting port 22 that might be overriding an ACCEPT rule. Rule order matters — a DROP higher in the chain will block traffic even if an ACCEPT exists below it.

4. Check Your VPS Provider's Network-Level Firewall

This is a common gotcha: many VPS control panels include a separate cloud firewall or security group that sits outside the operating system entirely. Even if ufw allows port 22, a network-level rule blocking it will cause "Connection refused" (or more often, a timeout). Log into your hosting control panel and verify that port 22 TCP inbound is permitted for your server's IP.

5. Look at SSH Logs for the Root Cause

If the service keeps failing to start, the logs will tell you why:

sudo journalctl -u sshd -n 50 --no-pager

Common log errors and what they mean:

  • "Address already in use" — Another process is bound to port 22. Find it with sudo ss -tlnp | grep :22 and stop the conflicting service.
  • "Missing privilege separation directory: /run/sshd" — The directory was deleted. Recreate it: sudo mkdir -p /run/sshd && sudo chmod 0755 /run/sshd
  • "No hostkeys available" — SSH host keys are missing. Regenerate them: sudo ssh-keygen -A

6. Test Connectivity From Outside Before Assuming It's Fixed

After making changes, don't just retry your SSH client — use a port check first to confirm the port is actually reachable from the outside world:

nc -zv your-server-ip 22

A successful response looks like Connection to your-server-ip 22 port [tcp/ssh] succeeded!. If it still fails from outside but works locally on the server, the issue is almost certainly a firewall — either the OS firewall or the network-level one from your provider.

Quick Reference Checklist

  • Is sshd running? → systemctl status sshd
  • Is it on the expected port? → ss -tlnp | grep sshd
  • Is ufw or firewalld blocking it? → check and allow the port
  • Is there a cloud/panel-level firewall blocking it? → check your provider's control panel
  • What do the logs say? → journalctl -u sshd -n 50
✏️ Edit This Post