Error Medic

Troubleshooting 'iptables connection refused': A Comprehensive Guide

Fix 'iptables connection refused' errors by diagnosing firewall rules, checking service listening states, and resolving permission denied issues.

Last updated:
Last verified:
1,327 words
Key Takeaways
  • Check if the target service is actually listening on the intended port using ss or netstat.
  • Verify iptables rules are not actively REJECTing the connection with tcp-reset.
  • Ensure you have root/sudo permissions to avoid 'iptables permission denied' errors.
  • Use the raw table TRACE target or tcpdump to trace packet flow when facing 'iptables not working' symptoms.
Diagnostic Approaches Compared
MethodWhen to UseTimeRisk
ss -tulpnInitial check to see if the service is listening1 minNone
iptables -L -n -vReviewing active firewall rules for REJECTs2 minsNone
tcpdumpVerifying if packets are reaching the interface5 minsLow
iptables TRACEDeep debugging of complex chain traversals15 minsMedium

Understanding the Error

When you encounter an iptables connection refused error, or related issues like iptables failed, iptables not working, iptables permission denied, or iptables slow, it is critical to understand the mechanics of TCP/IP and how the Linux kernel handles packet filtering. iptables itself rarely generates a "Connection refused" (TCP RST) response natively unless explicitly configured to do so via a REJECT target.

More often, a "Connection refused" means one of two things:

  1. The packet successfully traversed the firewall, but there is no service listening on the target port.
  2. A firewall rule is explicitly matching the packet and jumping to the REJECT target with a --reject-with tcp-reset option.

This is distinctly different from a connection timeout, which occurs when packets are silently dropped (using the DROP target).

Step 1: Diagnose the Symptom

Before manipulating iptables rules, we must accurately diagnose the state of the system.

1. Is the service actually running and listening? The most common root cause of "Connection refused" is an application-level issue. The backend service (Nginx, SSH, MySQL, etc.) might be down, crashed, or bound to the wrong network interface (e.g., listening on 127.0.0.1 instead of 0.0.0.0 or a specific public IP).

Use the ss utility to verify listening sockets:

sudo ss -tulpn | grep :<port_number>

If the command returns no output for your target port, the issue is not iptables. You must start or reconfigure your service.

2. Is iptables actively rejecting the packet? If the service is listening correctly, the next step is to check if iptables is explicitly rejecting the connection. List your current rules with packet counts and line numbers:

sudo iptables -L -n -v --line-numbers

Scan the INPUT chain (or FORWARD chain if this is a router/gateway) for rules that jump to REJECT. Pay special attention to rules that match your target destination port.

3. Resolving 'iptables permission denied' If you execute an iptables command and receive a permission error, you are likely running it as an unprivileged user. Managing the netfilter framework requires CAP_NET_ADMIN and CAP_NET_RAW Linux capabilities. Always prepend your commands with sudo or execute them in a root shell.

Step 2: Implement the Fix

Scenario A: The REJECT Target

If your diagnostics revealed a REJECT rule blocking your legitimate traffic, you need to modify the ruleset. You can either delete the offending rule or insert an ACCEPT rule before it (since iptables evaluates rules sequentially from top to bottom).

To delete a specific rule (e.g., rule number 5 in the INPUT chain):

sudo iptables -D INPUT 5

To insert an ACCEPT rule for port 80/TCP at the very top of the INPUT chain, ensuring it gets evaluated before any REJECT or DROP rules:

sudo iptables -I INPUT 1 -p tcp --dport 80 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
Scenario B: 'iptables slow' and Connection Tracking

Sometimes, the issue isn't a hard refusal but extremely sluggish performance. If connections succeed but are agonizingly slow, you might be exhausting the connection tracking table. The kernel logs (dmesg) will typically show nf_conntrack: table full, dropping packet.

Check your current connection tracking usage and maximum limits:

sysctl net.netfilter.nf_conntrack_count
sysctl net.netfilter.nf_conntrack_max

If the count is near the maximum, you should increase the limit dynamically:

sudo sysctl -w net.netfilter.nf_conntrack_max=262144

Make this persistent by adding net.netfilter.nf_conntrack_max = 262144 to /etc/sysctl.conf.

Step 3: Advanced Debugging with TRACE

When iptables not working is your primary complaint and standard listings don't reveal the problem, it's time for advanced packet tracing. Modern Linux systems use a complex web of chains, tables (filter, nat, mangle, raw), and potentially container networking (like Docker or Kubernetes) that dynamically alter rules.

You can use the TRACE target in the raw table to log the exact path a packet takes through the netfilter framework.

sudo iptables -t raw -A PREROUTING -p tcp --dport 80 -j TRACE

Once the rule is active, attempt a connection and monitor the kernel ring buffer or syslog:

sudo dmesg -w | grep TRACE

This output will show you precisely which table, chain, and rule number processed the packet, definitively proving where a connection is being dropped or rejected.

Step 4: Persistence

A critical mistake many engineers make is fixing the issue in memory but failing to save the rules. iptables configurations are ephemeral and will be lost on the next reboot unless explicitly saved.

On Debian/Ubuntu systems using iptables-persistent:

sudo netfilter-persistent save

On RHEL/CentOS systems:

sudo iptables-save > /etc/sysconfig/iptables

By following this structured approach—verifying listening services, checking for explicit rejections, utilizing connection tracking metrics, and employing packet tracing—you can systematically resolve iptables connection refused errors and restore reliable network communication.

Frequently Asked Questions

bash
# 1. Verify if the target service is actually listening on the port
sudo ss -tulpn | grep :80

# 2. Check iptables for explicit REJECT rules (with line numbers for easy deletion)
sudo iptables -L INPUT -n -v --line-numbers

# 3. If a REJECT rule is found, insert an ACCEPT rule above it (e.g., at position 1)
sudo iptables -I INPUT 1 -p tcp --dport 80 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

# 4. Advanced: Trace the packet through all chains and tables to find the drop/reject point
sudo iptables -t raw -A PREROUTING -p tcp --dport 80 -j TRACE
sudo dmesg -w | grep TRACE
E

Error Medic Editorial

Error Medic Editorial is a team of senior DevOps, SREs, and Linux System Administrators dedicated to creating actionable, deep-dive troubleshooting guides for complex infrastructure issues.

Sources

Related Articles in iptables

Explore More Linux Sysadmin Guides