Mysql – How to get port forwarding to work with iptables

iptablesMySQLport-forwarding

I want to protect my MySQL Server from portscanners/probes. So my idea is to put the external port on let's say 36636, internal port has to stay at the default 3306 for compatibility with local apps.

A MySQL client connects to mysql.hostname.tld:36636 and should then be forwarded to 3306 by iptables.
But I just can't get it to work. Here my redirect-rule:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 36636 -j REDIRECT --to-port 3306

I activated extensive logging in iptables and in MySQL, I'm pretty sure the packets go trough the firewall, but then they "disappear", they don't seem to reach MySQL. Of course I also opened a port 36636 in iptables.

Best Answer

First of all, this is not an effective way of protecting mysql server. Changing the port will not make it impossible for an attacker to know you are running mysql server. It may just delay him a little bit.

To answer your question, your rule seems OK if you are running iptables and mysql on the same host. Otherwise, you need to use DNAT target instead of REDIRECT. Also, you need to allow IP forwarding in this case. This is with regard to NAT rules. For filtering rules, you need either to allow mysql port or set default INPUT/FORWARD/OUTPUT policy to ACCEPT (do this only if you want to allow everything to pass through the firewall).

Anyway, you have to allow port 3306 even if you are doing port forward from another port. You have two options:

1- Change the port mysql server is listening on. This might not be suitable for you as it will affect the local applications.
2- Add another NAT rule to port forward standard mysql port 3306 to something else invalid.

For option 2, you can execute:

iptables -A PREROUTING ! -s local_subnet -p tcp --dport 3306 -j REDIRECT --to-port 9999

This rule will prevent access to mysql port from non-local subet.