Introduction
One of the fastest ways to take production offline is to change firewall rules over SSH and accidentally block your own connection. This happens more often than teams admit, especially when debugging iptables in remote environments without out-of-band console access.
This article focuses on practical, safe workflows for updating iptables without locking yourself out.
Why SSH Lockouts Happen
Most lockouts are caused by one of these mistakes:
- Dropping inbound traffic before allowing SSH.
- Forgetting established/related connection rules.
- Applying rules in the wrong order.
- Flushing current rules in a live session.
- Testing from one source IP, then reconnecting from another.
The root issue is almost always sequencing, not intent.
Golden Safety Rules Before Any Firewall Change
Before touching iptables on a remote server, always do the following:
- Keep one existing SSH session open at all times.
- Open a second SSH session for validation.
- Add SSH allow rules first.
- Add established/related rules before deny/drop rules.
- Use a timed rollback when experimenting.
- If possible, ensure console access exists (KVM, cloud serial console, provider rescue mode).
The Minimum Safe Rule Skeleton
If you remember only one safe baseline, use this sequence:
# Accept loopback
iptables -A INPUT -i lo -j ACCEPT
# Keep existing connections alive
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Explicitly allow SSH from your admin source
iptables -A INPUT -p tcp --dport 22 -s 203.0.113.10 -j ACCEPT
# Optionally allow ICMP for diagnostics
iptables -A INPUT -p icmp -j ACCEPT
# Default deny
iptables -P INPUT DROP
Important: if your team connects from multiple known source IPs, include all of them before applying a drop policy.
Safe Change Workflow in Production
Step 1: Snapshot Existing Rules
Always export current rules before changes.
iptables-save > /root/iptables.backup.$(date +%Y%m%d-%H%M%S)
Step 2: Stage New Rules in a Script
Create a script instead of typing ad-hoc commands.
#!/usr/bin/env bash
set -euo pipefail
iptables -F INPUT
iptables -P INPUT ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 203.0.113.10 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -P INPUT DROP
Step 3: Use a Timed Rollback Guard
A rollback guard is the most reliable anti-lockout pattern.
# 1) Schedule rollback in 2 minutes
echo "iptables-restore < /root/known-good.rules" | at now + 2 minutes
# 2) Apply new rules
bash /root/apply-new-iptables.sh
# 3) Validate connectivity from a fresh SSH session
# 4) If everything works, remove pending at jobs
atq
atrm <job-id>
Do not use repeating cron jobs that disable your firewall every minute in production. That creates a permanent security hole and can fail unpredictably.
Validation Checklist After Applying Rules
Run these checks in order:
- Open a fresh SSH session from a trusted admin IP.
- Verify required application ports from outside.
- Confirm blocked ports are truly blocked.
- Confirm your monitoring and backup agents still connect.
- Persist rules only after all checks pass.
Useful commands:
iptables -S
iptables -L -n -v
ss -tulpen
Persisting Rules Across Reboot
Distribution behavior varies.
Debian/Ubuntu (with iptables-persistent)
apt-get update
apt-get install -y iptables-persistent
iptables-save > /etc/iptables/rules.v4
RHEL/CentOS style systems
Depending on OS generation, use service iptables save or migrate to nftables/firewalld defaults.
UFW and firewalld Notes
Many teams use wrappers instead of raw iptables.
UFW basic safety
ufw allow from 203.0.113.10 to any port 22 proto tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw default deny incoming
ufw enable
firewalld equivalent pattern
Use permanent rules and reload only after confirming required services and sources.
Common Anti-Patterns to Avoid
- Flushing all chains in a live SSH-only session.
- Setting default drop first, then adding allow rules later.
- Allowing
0.0.0.0/0on SSH permanently. - Using cron-based auto-stop of firewall as a safety mechanism.
- Skipping backups of known-good rules.
Incident Recovery if You Are Locked Out
If lockout already happened:
- Use cloud provider serial console or rescue mode.
- Restore the last known-good rules file.
- Reboot networking only if required.
- Document the bad rule and update change checklist.
Operational Policy Recommendation
For teams managing multiple hosts:
- Treat firewall changes as code (Ansible/Terraform/etc.).
- Require review for INPUT default policy changes.
- Add a rollback guard in every runbook.
- Roll out firewall changes in canary batches.
Conclusion
iptables is not dangerous because it is complex. It is dangerous because it is fast and unforgiving when rule order is wrong. If you always stage changes, backup current rules, use timed rollback, and validate from a second session, lockouts become rare and recoverable.
Resources
- Netfilter project documentation
- iptables(8) man page
- DigitalOcean iptables essentials
- Ubuntu UFW documentation
Comments