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 outorConnection refused ssh -voutput stops atConnecting to host port 22- Other services on the server work but SSH does not
iptables -L -n -vshows 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.Access the server via console (out-of-band management, cloud provider console, KVM/IPMI):
- 2.If you have console access through your cloud provider (AWS EC2 Serial Console, DigitalOcean Recovery Console, etc.), log in directly.
- 3.Review current iptables rules:
- 4.```bash
- 5.sudo iptables -L INPUT -n -v --line-numbers
- 6.sudo iptables -L -n -v
- 7.
` - 8.Insert an ACCEPT rule for SSH at the top of the chain:
- 9.```bash
- 10.sudo iptables -I INPUT 1 -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
- 11.
` - 12.If the default policy is DROP, verify the chain:
- 13.```bash
- 14.sudo iptables -L INPUT -n | head -5
- 15.# If policy is DROP, ensure SSH rule exists before any DROP rule
- 16.
` - 17.Save the corrected rules:
- 18.```bash
- 19.# On Debian/Ubuntu
- 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.Test SSH connectivity from another terminal before closing console:
- 2.```bash
- 3.ssh user@server -p 22
- 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 -Cto check if a rule exists before adding it - Prefer firewalld or ufw for simpler management:
sudo ufw allow 22/tcp