Troubleshooting SSH Connection Refused: Port 22 Blocked by Network or Host Firewall

Resolve 'SSH connection refused' when port 22 is blocked by host or network firewalls. A comprehensive guide for Linux sysadmins.


When attempting to establish a Secure Shell (SSH) connection to a remote server, encountering an immediate “Connection refused” error on port 22 can be a frustrating experience. This typically indicates that the connection request reached the server’s operating system, but the server actively rejected the connection, often due to no service listening on the port, or a firewall explicitly denying the connection. This guide will walk through the common culprits and provide systematic steps to diagnose and resolve this issue, focusing on both host-based and network-level firewall obstructions.

Symptom & Error Signature

The most common symptom is an immediate refusal when trying to connect via an SSH client. You will not be prompted for a password, and the connection attempt will terminate quickly.

$ ssh user@your_server_ip
ssh: connect to host your_server_ip port 22: Connection refused

Occasionally, if a firewall is silently dropping packets rather than actively refusing, you might see a timeout, though “Connection refused” is the primary signature for this specific problem:

$ ssh user@your_server_ip
ssh: connect to host your_server_ip port 22: Connection timed out

Root Cause Analysis

The “SSH connection refused” error, particularly when “port 22 network firewall blocks” is implicated, can stem from several underlying issues. It’s crucial to understand that “refused” implies the connection reached something that then rejected it, whereas “timed out” often means the connection never reached the target.

  1. SSH Daemon (sshd) Not Running: The OpenSSH server process (sshd) is not active on the target server, so there’s nothing listening on port 22 to accept connections.
  2. Incorrect SSH Port: The sshd daemon is configured to listen on a non-standard port, and the client is attempting to connect to the default port 22.
  3. Host-Based Firewall: A firewall running directly on the server (e.g., UFW, iptables, firewalld) is blocking inbound connections to port 22. This is often the first line of defense after the SSH service itself.
  4. Network-Level Firewall: An external firewall, such as cloud security groups (AWS, GCP, Azure), a corporate network firewall, or a home/office router’s access control list (ACL), is blocking traffic to the server’s port 22 before it even reaches the server’s operating system.
  5. TCP Wrappers: The tcpd service, configured via /etc/hosts.allow and /etc/hosts.deny, is preventing connections from your client IP.
  6. SSH Daemon Configuration Restrictions: Specific settings within /etc/ssh/sshd_config, such as ListenAddress, AllowUsers, DenyUsers, AllowGroups, or DenyGroups, are preventing your connection.
  7. Resource Exhaustion or Temporary Ban: The server might be experiencing high load preventing new connections, or security tools like fail2ban have temporarily banned your IP address after too many failed authentication attempts.
  8. Incorrect Target IP/Hostname: A simple but common error – you’re trying to connect to the wrong IP address or hostname.

Step-by-Step Resolution

Troubleshooting should follow a logical path, starting with network reachability and moving inward towards the server’s services and configurations.

1. Verify Basic Network Reachability

Before diving into SSH specifics, ensure the server is generally reachable on the network.

[!IMPORTANT] If you cannot SSH into your server, you will need to use an alternative access method like a cloud provider’s web console (e.g., AWS EC2 Instance Connect, GCP Serial Console, Azure Serial Console), a KVM-over-IP, or a direct physical console connection to perform server-side checks.

  • Ping Test (Limited Utility): ping your_server_ip While ping verifies basic IP connectivity, many servers block ICMP (ping) requests at the firewall level, so a lack of response doesn’t definitively mean the server is down.

  • Traceroute (Diagnose Network Path): traceroute your_server_ip (Linux/macOS) or tracert your_server_ip (Windows) This command helps identify where traffic stops on its way to the server. If it completes, it means the server is responding at a network level. If it stops at a particular hop, that might indicate a router or intermediate firewall issue.

  • Telnet / Netcat (Port Check - Client Side): This is the most direct client-side test to see if something is listening on port 22.

    telnet your_server_ip 22
    # OR
    nc -vz your_server_ip 22

    If you get Connection refused here, it confirms the issue is either a network firewall blocking the connection, or no service listening on the server. If it hangs or times out, it more strongly suggests a network-level block silently dropping packets. If it connects and shows “SSH-2.0-OpenSSH_…” then the SSH service is running and accessible from the network, suggesting client-side configuration issues.

2. Check SSH Daemon Status on the Server

Once you have console access to the server, verify the SSH service is running and listening.

  • Check SSH service status:

    sudo systemctl status ssh

    You should see output indicating active (running). If it’s inactive (dead) or failed, proceed to start it.

  • Start the SSH service:

    sudo systemctl start ssh

    If it starts successfully, try connecting via SSH from your client again.

  • Enable SSH to start on boot:

    sudo systemctl enable ssh
  • Check listening ports: Use ss (Socket Statistics) or netstat to see if sshd is listening on port 22.

    sudo ss -tuln | grep 22
    # OR
    sudo netstat -tuln | grep 22

    You should see an entry like tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* or :::22 for IPv6. If there’s no output, nothing is listening on port 22.

  • Review SSH service logs:

    sudo journalctl -u ssh.service -e

    Look for error messages that might explain why sshd failed to start or why it’s refusing connections.

3. Inspect Host-Based Firewalls (Server-Side)

If sshd is running and listening on port 22, the server’s local firewall is the next most likely culprit.

  • Uncomplicated Firewall (UFW) - Common on Ubuntu/Debian:

    sudo ufw status verbose

    Look for rules that explicitly allow OpenSSH or port 22 from your IP or Anywhere. If port 22 is blocked or UFW is active without an explicit allow rule, you’ll need to add it.

    # Allow SSH from your specific IP address (highly recommended for security)
    sudo ufw allow from your_client_ip to any port 22
    
    # OR, if you need broader access (less secure)
    sudo ufw allow OpenSSH
    # OR
    sudo ufw allow 22/tcp

    [!WARNING] If ufw is currently disabled, enabling it without configuring rules first can lock you out! Ensure you have allow OpenSSH or allow 22/tcp in place before enabling.

    sudo ufw enable
  • iptables (Direct Configuration):

    sudo iptables -L -n -v

    Examine the INPUT chain. Look for rules that DROP or REJECT connections to dport 22 or a default policy that denies everything. A common safe rule to allow SSH is:

    # Allow established connections
    sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    # Allow SSH from your specific IP
    sudo iptables -A INPUT -p tcp -s your_client_ip --dport 22 -j ACCEPT
    # OR, allow from anywhere (less secure)
    # sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
    # Ensure a default DROP policy at the end for other ports if not explicitly allowed
    # sudo iptables -A INPUT -j DROP

    [!WARNING] iptables changes are ephemeral by default. To make them persistent, you need to save them. On Debian/Ubuntu, install iptables-persistent:

    sudo apt install iptables-persistent
    sudo netfilter-persistent save

4. Review Network-Level Firewalls (Cloud/External)

This is a very common cause of “Connection refused” when dealing with cloud-hosted servers, as these firewalls block traffic before it reaches the server’s OS.

  • Cloud Security Groups (AWS): Navigate to your EC2 instance in the AWS console. Check the associated Security Groups. Ensure there is an inbound rule that allows SSH (port 22) from your client’s public IP address (my_client_ip/32) or a broader range if necessary.

    [!IMPORTANT] Never leave SSH access open to 0.0.0.0/0 (anywhere) in production environments unless absolutely necessary and coupled with other strong security measures. Always restrict to known IPs.

  • VPC Firewall Rules (Google Cloud Platform): In the GCP console, go to VPC network > Firewall. Look for ingress rules that allow TCP port 22. Ensure the rule applies to your server’s network tags and targets (e.g., Allow from your_client_ip/32 on port 22).

  • Network Security Groups (Azure): In the Azure portal, navigate to your Virtual Machine, then to Networking. Check the inbound security rules of the associated Network Security Group. Ensure there’s a rule allowing TCP port 22 from your source IP.

  • On-Premise / Router Firewalls: If your server is in a corporate network or behind a home router, there might be a physical firewall or router Access Control List (ACL) blocking port 22. This often requires contacting your network administrator.

5. Verify SSH Daemon Configuration (/etc/ssh/sshd_config)

Even with firewalls open, specific sshd settings can still block connections. Access this file via console if SSH is currently unavailable.

sudo nano /etc/ssh/sshd_config

Look for and verify the following directives:

  • Port:

    Port 22

    Ensure this is set to 22 (or the custom port you expect) and is not commented out (#). If it’s a non-standard port, you must specify it when connecting from your client (ssh -p YOUR_PORT user@your_server_ip).

  • ListenAddress:

    ListenAddress 0.0.0.0
    # Or for IPv4 only:
    # ListenAddress 0.0.0.0
    # For IPv6 only:
    # ListenAddress ::

    Ensure it’s set to 0.0.0.0 (listen on all interfaces) or the specific IP address of the server’s interface you are trying to connect to. If it’s set to an incorrect or non-existent IP, sshd won’t listen where you expect.

  • PermitRootLogin: If you’re trying to log in as root, ensure this is set to yes, prohibit-password, or forced-commands-only.

    PermitRootLogin yes

    [!WARNING] Allowing direct root login via password is a security risk. It’s better to log in as a regular user and then sudo.

  • AllowUsers, DenyUsers, AllowGroups, DenyGroups: These directives explicitly control who can log in. If your username or a group you belong to is listed in DenyUsers/DenyGroups or not in AllowUsers/AllowGroups (when they are used), your connection will be refused.

    # Example: Allow only 'adminuser' and 'devteam' group members
    # AllowUsers adminuser
    # AllowGroups devteam

    If these are present, ensure they don’t exclude your intended user.

After making any changes to sshd_config, you must restart the SSH service:

sudo systemctl restart ssh

6. Check TCP Wrappers

TCP Wrappers provide an additional layer of access control for network services.

  • Inspect hosts.allow and hosts.deny:

    cat /etc/hosts.allow
    cat /etc/hosts.deny

    Look for entries related to sshd. For example, sshd: ALL in /etc/hosts.deny would block all SSH connections. Rules in hosts.allow take precedence over hosts.deny. Ensure your client IP is allowed or that sshd isn’t globally denied.

    Example allowing specific IP for SSH:

    # /etc/hosts.allow
    sshd: your_client_ip

    Example blocking all SSH:

    # /etc/hosts.deny
    sshd: ALL

    If you find blocking rules, comment them out or adjust them appropriately. Changes take effect immediately.

7. Examine SSH Client Configuration

Sometimes the issue is on the client side, where the SSH command is misconfigured.

  • Verbose Client Output:

    ssh -v user@your_server_ip -p 22

    The -v flag provides verbose debugging output, which can offer clues if the client is trying to connect to the wrong address, port, or is encountering other issues before the server responds.

  • Check ~/.ssh/config: If you use an SSH client configuration file, verify that the Hostname, Port, and other settings for your server entry are correct.

    Host my_server_alias
        Hostname your_server_ip
        User your_username
        Port 22
        IdentityFile ~/.ssh/id_rsa

    Ensure Port 22 (or the correct custom port) is specified if it’s not the default.

8. Check for fail2ban or Other Intrusion Detection Systems

If you’ve recently made several failed login attempts, fail2ban might have temporarily banned your IP.

  • Check fail2ban status:

    sudo fail2ban-client status sshd

    This will show if the sshd jail is running and which IPs are currently banned.

  • Unban your IP: If your IP address is listed, you can unban it:

    sudo fail2ban-client set sshd unbanip your_client_ip

    After unbanning, try connecting again.

By systematically working through these steps, you should be able to identify and resolve the “SSH connection refused” error caused by network or host firewalls on port 22. Remember to always prioritize security by restricting access to the minimum necessary IP ranges.