Linux iptables firewall port redirecting + preventing iptables lock out

Linux iptables firewall port redirecting

Sometimes you just want to redirect an external port to another internal port for security reasons.

I.e. you have a running mySQL server on default port 3306 and you want to access it outside from a ‘more secure’/uncommon port- let’s say 53306.

Typically you just add the following line to iptables:

/sbin/iptables -t nat -A PREROUTING -p tcp –dport 53306 -j REDIRECT –to-port 3306

However if you also want explicit firewall functionality you should close port 3306 for incoming packets and open port 53306 for them.

The basic packet flow in iptables is as follows:

Packet flow in linux iptables. Every table contains several chains/queues, where the packets are added/moved to. Incoming packets get in from top, then through mangle table PREROUTING chain, nat table PREROUTING chain, then mangle table INPUT chain, filter table INPUT chain and then to the application! Important: The default table is ‘filter’.

Typically to close port 3306 for incoming tcp packets, you move TCP packets with destination port 3306 from (table nat, chain PREROUTING) to (table filter, chain DROP). You would write:

/sbin/iptables -t nat -A PREROUTING -p tcp –dport 3306 -j DROP

However this line gives out an error, as the nat table does not allow to forward to the DROP chain.

So if you take a look at the graph above, the best table/chain to close the external port 3306 for incoming tcp packets is table/chain ‘mangle/prerouting’:

/sbin/iptables -t mangle -A PREROUTING -p tcp –dport 3306 -j DROP

Then you open the table/chain ‘filter/input’ on port 3306 (see graph above) and the firewall internally is opened:

/sbin/iptables -A INPUT -p tcp –dport 3306 -j ACCEPT
You see: iptables is quite easy if you understand the principle of packets just moving from one table/chain to another.

Preventing iptables lock out

As you can lock out yourself with iptables by adding wrong rules, it is recommended to add the following lines to crontab:

# FOR IPTABLES TESTS ONLY : flush all ip table rules every 60 minutes (in case you lock yourself out)
*/5 * * * * root /etc/

The looks as follows:

echo 0 > /opt/psa/var/modules/firewall/
chmod 644 /opt/psa/var/modules/firewall/
echo 0 > /proc/sys/net/ipv4/ip_forward
/sbin/iptables -F
/sbin/iptables -X
/sbin/iptables -Z
/sbin/iptables -P INPUT ACCEPT
/sbin/iptables -P OUTPUT ACCEPT
/sbin/iptables -P FORWARD ACCEPT
exit 0

If something goes wrong editing iptables, the firewall will be totally cleared every hour.  Then if everything works fine, simply comment the line in crontab and you are ready to go.

Another option for preventing a lock-out by a wrong iptables configuration is iptables-apply (

For backups of your iptables firewall rules, use iptables-save and iptables-restore commands (iptables gives data to stdout; i.e. iptables-save > ~/iptables_backup_24_11_2016.txt would save the data to your home).

With iptables –list you can check the current rules (default table is filter – so if you want to output all tables you have to use the -t parameter; simplier for inspescting all table rules is iptables-save).

NOTE: iptables looses all rules on process/system restart. Install iptables-persistent (apt-get install iptables-persistent) to load them every time the system/runlevel is entered (help link for German users: