Introduction

A misplaced iptables rule can instantly lock you out of a remote server by blocking port 22. This is one of the most dangerous firewall misconfigurations because it cuts off your only access path. The issue usually stems from rule ordering: iptables processes rules sequentially, and a blanket DROP rule placed before an ACCEPT rule for SSH will block all connections.

Symptoms

  • SSH connection hangs with Connection timed out or Connection refused
  • ssh -v output stops at Connecting to host port 22
  • Other services on the server work but SSH does not
  • iptables -L -n -v shows a DROP/REJECT rule matching port 22 traffic

Common Causes

  • INSERT (-I) vs APPEND (-A) confusion placing DROP before ACCEPT
  • Flushing rules without a safety net cron job to restore access
  • Stateful connection tracking not established before filtering
  • Default policy changed to DROP without explicit SSH ACCEPT rule
  • NAT or PREROUTING rules redirecting port 22 incorrectly

Step-by-Step Fix

  1. 1.Access the server via console (out-of-band management, cloud provider console, KVM/IPMI):
  2. 2.If you have console access through your cloud provider (AWS EC2 Serial Console, DigitalOcean Recovery Console, etc.), log in directly.
  3. 3.Review current iptables rules:
  4. 4.```bash
  5. 5.sudo iptables -L INPUT -n -v --line-numbers
  6. 6.sudo iptables -L -n -v
  7. 7.`
  8. 8.Insert an ACCEPT rule for SSH at the top of the chain:
  9. 9.```bash
  10. 10.sudo iptables -I INPUT 1 -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
  11. 11.`
  12. 12.If the default policy is DROP, verify the chain:
  13. 13.```bash
  14. 14.sudo iptables -L INPUT -n | head -5
  15. 15.# If policy is DROP, ensure SSH rule exists before any DROP rule
  16. 16.`
  17. 17.Save the corrected rules:
  18. 18.```bash
  19. 19.# On Debian/Ubuntu
  20. 20.sudo iptables-save | sudo tee /etc/iptables/rules.v4

# On RHEL/CentOS sudo iptables-save | sudo tee /etc/sysconfig/iptables sudo systemctl restart iptables ```

  1. 1.Test SSH connectivity from another terminal before closing console:
  2. 2.```bash
  3. 3.ssh user@server -p 22
  4. 4.`

Prevention

  • Always use a recovery cron job before modifying remote firewall rules:
  • ```bash
  • sudo bash -c '(crontab -l 2>/dev/null; echo "*/5 * * * * iptables-restore < /etc/iptables/rules.v4") | crontab -'
  • `
  • This restores rules every 5 minutes if you get locked out.
  • Test firewall changes in a screen or tmux session so you can reconnect
  • Use iptables -C to check if a rule exists before adding it
  • Prefer firewalld or ufw for simpler management: sudo ufw allow 22/tcp