Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Basically, I have two EC2 instances on Amazon Web Services. They are both running Ubuntu 11.10 x64. They both have a private and a public (Elastic) IP addresses. I'm having trouble setting up iptables to forward SQL data properly.

I would like it so that if I connect to "" on Server A (which does not have an SQL server installed), it will forward to <private ip>:3306 (aka Server B -- which does have an SQL server installed).

I'm able to access each server (from the other) using the associated private ip's. I'd like to keep the forwarding private as well without having to use a public IP.

Is there an easy way to do this?

share|improve this question
Why does it need to connect to localhost? – Ignacio Vazquez-Abrams Apr 4 '12 at 2:45
@IgnacioVazquez-Abrams I don't want to make the actual MySQL server on Server B open to remote connections (from the internet). However, I still want to be able to access it from Server A, internally. – Michael D Apr 4 '12 at 2:49
Is binding it to the private address not feasible? – Ignacio Vazquez-Abrams Apr 4 '12 at 2:51
@IgnacioVazquez-Abrams It's feasible, yes. However, I'd have to change a ton of configuration settings everywhere on Server A since the IP address would be different. Just looking for an easier option. I'd rather have it so connecting to "" will actually connect to Server B. – Michael D Apr 4 '12 at 2:53
MySQL-proxy might be worth a look, although I've never used it dev.mysql.com/downloads/mysql-proxy. From the documentation it seems like exactly what you need...if a bit of overkill – RobotHumans Apr 4 '12 at 3:03

I think this might be what you are looking for:

iptables -t nat -A PREROUTING -p tcp --dport 3306 -j DNAT --to <private ip>:3306
share|improve this answer

I have a similiar setup, but slightly more complex.

On my home laptop, I have a /etc/xinetd.d/mysqlfwd containing

service mysqlfwd
        type            = UNLISTED
        port            = 3307 # could be 3306 as well if ther will never be a MySQL server installed here
        socket_type     = stream
        protocol        = tcp
        wait            = no
        user            = ports
        server          = /usr/local/bin/ports
        server_args     = -s mysql@<mydomain>

This mysql@<mydomain> denotes the SSH subsystem defined on the server. As mysql is not, and does not have, a defined subsystem name, I chose to define one by myself using (the appropriate Convention for Names)[http://tools.ietf.org/html/rfc4250#section-4.6.1].

The used /usr/local/bin/ports is defined as

#!/usr/bin/env python

def ssh(*args, **opts):
    import subprocess
    map= { False: 'no', True: 'yes' }
    op = [ "-o%s=%s" % (k, map.get(v, v)) for k, v in opts.iteritems()]
    args = op + list(args)
    sp = subprocess.Popen(['ssh'] + args)
    return sp

def ssh_conn(*args, **opts):
    args = ['connect@myservernamehere', '-C' ] + list(args)
    opts2 = dict(ControlPath='/tmp/ssh-%r@%h:%p')
    return ssh(*args, **opts2)

def master():
    sp = ssh_conn('-f', 'sleep', '15h', ControlMaster=True)

def client(*args):
    sp = ssh_conn(*args, **dict(ControlMaster=False))

def main():
    import sys
    args = sys.argv[1:]
    if not args:

if __name__ == '__main__':

In the said server, there is a user named connect and, as said, a subsystem called mysql@<mydomain> The latter is defined in /etc/ssh/sshd_config with the line

Subsystem mysql@<mydomain> /usr/bin/netcat localhost 3306

The user connect exists just to have a platform to operate on hand has, except accepting my "port forwarding key" via its ~/.ssh/authorized_keys, no special features, properties or such.

This way my server can keep its MySQL port private (not accessible from outside), but I have a way to connect it nevertheless.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.