We've all been there - applying a new iptables rule only to find ourselves staring at a frozen SSH session. Locking yourself out of a production server is every sysadmin's nightmare. Here's how to avoid it while still effectively testing firewall rules.
Before touching production systems, set up a local test environment:
# Create a test VM using Vagrant
vagrant init ubuntu/focal64
vagrant up
vagrant ssh
Create a cron job that flushes all rules after X minutes:
# As root:
(crontab -l 2>/dev/null; echo "*/5 * * * * /sbin/iptables -F") | crontab -
This automatically resets your firewall every 5 minutes. Remove it once testing is complete.
The iptables-apply
tool is your best friend:
# Save current rules
iptables-save > current.rules
# Test new rules with timeout
iptables-apply -t 60 new.rules
If you don't confirm within 60 seconds, it auto-reverts.
Use these techniques to verify rule matches:
# Log packets before dropping them
iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "SSH ATTEMPT: "
iptables -A INPUT -p tcp --dport 22 -j DROP
# View logs in real-time
tail -f /var/log/syslog | grep SSH
Always check your work:
# Show all rules with line numbers
iptables -L -n -v --line-numbers
# Check specific chain
iptables -L INPUT -n -v
# Test connectivity from another terminal
telnet yourserver 22
nc -zv yourserver 80
For remote servers, ensure you have:
- IPMI access configured
- Out-of-band management (iDRAC/iLO)
- Vendor console access (AWS/Azure/GCP)
Once verified, persist the rules:
# Ubuntu/Debian
iptables-save > /etc/iptables.rules
apt install iptables-persistent
# RHEL/CentOS
service iptables save
Every sysadmin has that heart-stopping moment when they realize they've just locked themselves out of a remote server via misconfigured iptables rules. When working with Ubuntu Server (or any Linux distribution), testing firewall rules requires careful planning to avoid these scenarios.
Before making any changes to iptables on a production server, implement these safeguards:
# Create a failsafe cron job that flushes rules if you get locked out
(crontab -l 2>/dev/null; echo "*/5 * * * * /sbin/iptables -F") | crontab -
# View current rules with counters to see what's matching
iptables -L -v -n
# Save current rules for quick restoration
iptables-save > ~/iptables.backup
Follow this process when implementing new rules:
# 1. First, insert new rules with logging
iptables -I INPUT -p tcp --dport 22 -j LOG --log-prefix "SSH ACCESS: "
# 2. Check logs to verify matches
tail -f /var/log/syslog | grep "SSH ACCESS"
# 3. Only after verification, replace temporary logging with final rules
iptables -R INPUT 1 -p tcp --dport 22 -j ACCEPT
Method 1: Using the --dry-run Flag
iptables-restore --test < new_rules.v4
Method 2: Temporary Rules with Timeouts
# Set temporary rule that expires
iptables -A INPUT -p tcp --dport 22 -j ACCEPT && \
sleep 300 && \
iptables -D INPUT -p tcp --dport 22 -j ACCEPT &
Method 3: Virtual Testing Environments
Using Vagrant for local testing:
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/precise64"
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y iptables-persistent
SHELL
end
For complex rule sets, use these verification methods:
# Check which rule is matching for specific traffic
iptables -L -v -n --line-numbers
# Test packet flow simulation
iptables -N TEST_CHAIN
iptables -A TEST_CHAIN -p tcp --dport 80 -j LOG --log-prefix "HTTP_TEST: "
iptables -I INPUT -j TEST_CHAIN
When all else fails and you're locked out:
# If you have console access (IPMI/KVM)
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
iptables -X
# Restore from backup
iptables-restore < ~/iptables.backup
- Always test in staging first (Vagrant/Docker)
- Implement rule changes during maintenance windows
- Use verbose logging for new rules
- Maintain multiple access methods (SSH, console, IPMI)
- Document rollback procedures