These forums are read-only!
iptables help for MySQL via private IP
  • We are moving from hosting our website on one slice, to a simple load balancing setup across two slices using mod_proxy_balancer.

    The MySQL database, and mod_proxy_balancer are on Server 1. Server 1 and Server 2 each host an instance of the web application.

    I am having trouble configuring iptables to allow MySQL on Server 1 to listen on port 3306 only for requests coming from Server 2.

    When I use this line in the iptables config on Server 1, everything does work:

    -A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT

    But that opens MySQL up to the world, so I don't like it (even if my MySQL users are secure).

    I tried this line, but Server 2 becomes no longer able to connect to MySQL on Server 1:

    -A INPUT -p tcp -s 1.2.3.4 --dport 3306 -j ACCEPT

    For 1.2.3.4, I tried both the public and private IP addresses of Server 2, with no luck. Any suggestions what I'm doing wrong?

    Ideally I'd even like to add /24 after the IP address to require that it be on the LAN, didn't work for me either, but should it? Are there further options I can specify to further secure this connection?

    Thanks for any tips,
    Dan
  • While for a different application, I'd also be very interested in the answer to this question: ie: how to limit access to a port to a single or several ip addresses. I've tried the same approach with no success (in this case to an instance of Wowza running on a non-standard port). Seems like the only choices I have are wide open or completely shut.
  • I used the private IP addresses (shown on the slice manager page); so on the server with mysql you add this:

    -A INPUT -i eth1 -s 1.2.3.4 -p tcp --destination-port 3306 -j ACCEPT
  • Posted By: dogzillaWhile for a different application, I'd also be very interested in the answer to this question: ie: how to limit access to a port to a single or several ip addresses. I've tried the same approach with no success (in this case to an instance of Wowza running on a non-standard port). Seems like the only choices I have are wide open or completely shut.

    Using the -s (--source) option together with --destination-port should work, as long as you're also accepting all RELATED,ESTABLISHED packets. If it doesn't, what I would do is add a LOG target near the end of the firewall rules to log all dropped packets, and look at the system logs to see what packets are getting dropped. Also, you could try running tcpdump to see what packets are trying to get through in the first place.

    I wrote something about IPtables once that's posted on my website at
    http://www.ellipsix.net/geninfo/firewall/iptables/index.html
    I'm not sure if it might be of some use to you. (The target audience is IPtables beginners) It's sort of a perpetual work in progress but there's a fair amount of information there.

    :) David
  • One thing to keep in mind is also the order of rules. The general setup of my iptables follows:

    Allow specific "new" packets
    Allow related/established packets
    Reject all others

    I'm using a rule similar to what you're trying to accomplish for my PostgreSQL db server. It looks like:
    -A INPUT -m state --state NEW -s xxx.yyy.zzz.aaa -p tcp -m tcp --dport 5432 -j ACCEPT

    That should work for you; of course, using the appropriate source IP (-s) and destination port (--dport). Keep in mind to put this before your default reject rule.

    In addition, you can use CIDR notation on the IPs. For instance, you could use:
    -s xxx.yyy.zzz.aaa/24

    However, this will allow access from ALL slices on that internal IP range. I would not personally recommend this, as there is always the possibility of a malicious slice.

    Hope to help,
    -Joey
  • This doesn't directly answer your question, but if you don't want people being able to connect to your MySQL through the public address, you can also just tell MySQL to only bind to the private address.

    In my.cnf [mysqld] section add something like:
    bind-address=10.123.456.789


    The one advantage to doing it through iptables is that you can do complicated things, like make an exception so that just your IP can directly connect.
  • Thanks, these are very helpful. About the bind-address approach: would that prevent connecting to MySQL via localhost (fastest way to connect from Server 1 I think), or is localhost always supported?
    Thanks,
    Dan
  • Well, yes and no.

    Yes, it does prevent connections through localhost, but keep in mind that's not the only (or even necessarily the fastest) way to connect to a server running on the same box as a client. For example, the "mysql" command line client will still work because by default it doesn't connect through localhost, it uses a unix socket file (see the socket= line in your my.cnf), which doesn't require any networking at all.
  • Ah ok, I'll investigate whether Rails connects by socket-- it probably does, come to think of it.
    Thanks, -Dan
  • It should, as should PHP; I believe I've disabled networking completely on some of our slices.
  • Posted By: kuleI used the private IP addresses (shown on the slice manager page); so on the server with mysql you add this:

    -A INPUT -i eth1 -s 1.2.3.4 -p tcp --destination-port 3306 -j ACCEPT

    By the way kule's line worked perfectly. I guess I was missing the "-i eth1"? Not sure.