I need to provision servers via SSH, and in the process, configure iptables. More precisely, I want to run the following commands in this order:

iptables -F
iptables -P INPUT DROP
iptables -A INPUT -i lo -p all -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT 
iptables -A INPUT -p tcp -m tcp --dport 25 -j ACCEPT 
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT 
iptables -t nat -A PREROUTING -p tcp --dport 25 -j REDIRECT --to-port 5000
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8000
iptables -A INPUT -j DROP

How do I accomplish that without getting locked out? Can I apply those in batch?

  • 1
    I tend to put an explicit ACCEPT at the top of chain(s) for my management traffic until I'm sure I've got everything configured as I want it. "Locking the keys in the car" is embarrassing. Feb 10 '13 at 17:08

I would probably save the rules in a new file, i.e /etc/iptables/new.rules and use the command iptables-apply to test them:

iptables-apply -t 180 new.rules

This way, the rules will be active for 180 seconds (-t = time) but not be saved unless you confirm the connection is still working as expected. In case of no interaction after 180 seconds, the rules will be reverted back to the previous state.


I assume the reason you think you'll be locked out is that you put in the default DROP rule before configuring the ACCEPT rules.

Run the commands through a single shell command like:

bash -c 'iptables -F; iptables -P INPUT DROP; ...'

The entire string will be sent and read before being processed and then the rules will be applied. Since the commands don't require input, they'll all process, and when you're done you'll still have access.

  • Since I'm deploying with fabric, your solution was great since it only required a simple list join in python.
    – Era
    Feb 10 '13 at 17:26
  • 1
    Whenever I'm doing risky things that cause connection drop-outs (eg reconfiguring OpenVPN settings), I set a cronjob that will reset to defaults after a period of time. If things go well I cancel the job, if they don't I wait until it sets up access again.
    – deed02392
    Feb 21 '14 at 11:27

I usually do this:

1) I backup the old iptables configuration file:

cp /etc/sysconfig/iptables /etc/sysconfig/iptables.bak

2) Before trying the new settings I execute this command to make sure I can connect back if something in the new settings locks me out (basically I replace the old rules after 10/15 minutes):

echo "mv /etc/sysconfig/iptables.bak /etc/sysconfig/iptables && service iptables restart" | at now + 15min

3) Now I can safely modify iptables rules. If something goes bad I can connect back in 15 minutes.


If you want to avoid the situation that you are locked out for a moment (and avoid the risk that the firewall setup fails due to errors) a technical alternative is to avoid the table flush for INPUT. Replace iptables -F or iptables -F INPUT by

iptables -I INPUT 1 -p tcp -m tcp --dport 22 -j ACCEPT
while iptables -D 2 INPUT; do
for chain in $(iptables -L -n | awk '/^Chain/ && $2 != "INPUT" { print $2 }'); do
  iptables -F "$chain"

Then define the rules as usual (just -A for INPUT though, no -I INPUT 1, please) and in the end remove the connection safety rule: iptables -D INPUT 1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.