Let’s consider a server running MySQL server, listening on 127.0.0.1:3306.
I would now like to give Docker containers running on the same host access to the MySQL server. MySQL would reject incoming connections, since they don’t originate from 127.0.0.1, but from the container’s IP. I could change the binding address of MySQL to ‘*’, but then I would rely entirely on the firewall to prevent access from other networks. Therefore, I would prefer to keep MySQL listening on 127.0.0.1, and use iptables to “white list” the containers. I am not an iptables expert, so I just tried different combinations, using -t nat INPUT, PREROUTING, POSTROUTING, but couldn’t get it to work so far. I also set “net.ipv4.conf.docker0.route_localnet” to 1, since that looks necessary.
How can I make iptables set the source address to 127.0.0.1 for all packets coming on the docker0 interface (or a specific IP or network), and handle the following address translation?
Answering my own question: it looks like iptables is the wrong tool for the job. I installed rinetd and configured it like this:
# bindadress bindport connectaddress connectport 172.17.0.1 3308 127.0.0.1 3306
rinetd binds only to the Docker address (172.17.0.1), and forwards connection from the containers to the MySQL server running on the host. From MySQL’s perspective, the connections are coming from 127.0.0.1, so it happily accepts them.
It would be much easier if MySQL would support multiple bind addresses, but since the corresponding feature request have been open for 11 years, I guess it is not going to be implemented any time soon (https://bugs.mysql.com/bug.php?id=14979).