Recovering Connection After iptables Rules Reset
Emergency guide to restoring network connectivity after accidentally flushing iptables rules, including console recovery and rule reconstruction.
Recovering Connection After iptables Rules Reset
Flushing iptables rules can instantly lock you out of a remote server. I experienced this while trying to troubleshoot a firewall issue - a simple iptables -F dropped all established connections. This guide covers emergency recovery and rule reconstruction.
Environment
- OS: Ubuntu 22.04 LTS
- Firewall: iptables (without ufw)
- Context: Production web server, SSH access required
$ sudo iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443
DROP all -- 0.0.0.0/0 0.0.0.0/0The Problem
# The command that caused the problem (DO NOT RUN THIS)
$ sudo iptables -F
$ sudo iptables -X
# Immediately lost SSH connection
ssh: connect to host server.example.com port 22: Connection timed outAnalysis
Understanding What Happened
When you flush iptables rules:
- All established connections are dropped
- The default policy is ACCEPT (usually), but new connections may be blocked
- If policy was DROP, everything is blocked
Step 1: Access via Console
Use your cloud provider's web console or physical console access:
# After logging in via console
$ sudo iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
# Empty - all rules were flushed
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destinationStep 2: Restore Basic Connectivity
# Allow SSH immediately
$ sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
$ sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Test from another terminal
$ ssh admin@server
# Should work nowSolution
Rebuild Complete iptables Rules
#!/bin/bash
# /usr/local/bin/setup-firewall.sh
# Flush existing rules
iptables -F
iptables -X
# Set default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Allow loopback
iptables -A INPUT -i lo -j ACCEPT
# Allow established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow SSH
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow HTTP/HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow DNS
iptables -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT
# Allow ICMP (ping)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# Log dropped packets (optional)
iptables -A INPUT -j LOG --log-prefix "IPTables-Dropped: "
# Save rules
iptables-save > /etc/iptables/rules.v4Make Rules Persistent
# Install iptables-persistent
$ sudo apt install iptables-persistent
# Save current rules
$ sudo netfilter-persistent save
# Rules will survive reboot
$ sudo netfilter-persistent reloadAlternative: Use iptables-save/restore
# Backup rules before changes
$ sudo iptables-save > /root/iptables-backup-$(date +%Y%m%d).rules
# Restore from backup
$ sudo iptables-restore < /root/iptables-backup-20250612.rules
# Verify
$ sudo iptables -L -nPrevention Strategies
Use ufw for Simpler Management
# Install ufw
$ sudo apt install ufw
# Set defaults
$ sudo ufw default deny incoming
$ sudo ufw default allow outgoing
# Allow services
$ sudo ufw allow ssh
$ sudo ufw allow http
$ sudo ufw allow https
# Enable
$ sudo ufw enable
# Status
$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN AnywhereCreate a Safe Firewall Script
#!/bin/bash
# /usr/local/bin/safe-iptables.sh
# Only allows flush if console session is active
if [ -z "$SSH_CONNECTION" ]; then
echo "Flushing iptables rules..."
iptables -F
iptables -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
echo "Rules flushed. Reconnect via console to restore."
else
echo "ERROR: Cannot flush iptables via SSH."
echo "Use console access or run: iptables-restore < /etc/iptables/rules.v4"
exit 1
fiQuick Reference
# View current rules
$ sudo iptables -L -n -v
# Count rules per chain
$ sudo iptables -L INPUT -n | wc -l
# Check specific port
$ sudo iptables -L -n | grep ":22"
# List numbered rules
$ sudo iptables -L INPUT --line-numbers
# Delete specific rule
$ sudo iptables -D INPUT 3
# Insert rule at position
$ sudo iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPTLessons Learned
- Never flush iptables via SSH without console access available.
- Always keep a backup of working iptables rules.
- Use ufw or firewalld for safer firewall management.
- Test firewall changes with a script that auto-restores after timeout.
- Document all custom rules for team reference.
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.