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.

  • is your system allowing port forwarding? cat /proc/sys/net/ipv4/conf/eth0/forwarding should return 1 – sreimer May 7 '12 at 14:48
  • Yes, forwarding is allowed by the system. – Tobe May 7 '12 at 15:01

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.

  • Iptables and MySQL are on the same host. Filter rules are set to ACCEPT input on port 36636. Forward and Output are set to ACCEPT everything. IP forwarding is set to 1. – Tobe May 7 '12 at 14:57
  • You need to allow TCP destination port 3306 in addition to RELATED/ESTABLISHED connections. – Khaled May 7 '12 at 15:00
  • That doesn't help. Only when I open up port 3306 fully, I can access MySQL. Do I have to configure MySQL somehow to not use port 3306 externally? – Tobe May 7 '12 at 15:25
  • Your NAT rule is OK, but you need to open the port 3306 (after NAT). The PREROUTING rule is executed before any filtering rule in INPUT chain. – Khaled May 7 '12 at 15:30
  • How can I open port 3306 after NAT? I don't want this port to be open to the whole world. – Tobe May 7 '12 at 19:37

Well, there's no need to enable ip forwarding if the MySQL server is on the same host. You could use the following command to redirect traffic from port 36636 to 3306:

iptables -t nat -A PREROUTING -m tcp -p tcp --dport 36336 -j DNAT --to-destination IP_ADDRESS:3306

where IP_ADDRESS is the IP address of the interface MySQL is listening to.

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.