sshdatabase-connectionportforwardingssh-tunnelautossh

Create a SSH tunnel from a Jump host to a Database and access the database on Jump Host Port


I am trying to create a SSH tunnel between a database running server port and another server as the following.

MySQL:3306 <=====> Server-A:3306

And I want to use the Server-A:3306 as the database URI to connect to the database.

I am running the following on ServerA

ssh -f -N -i ~/keys/test.pem foo@foo.storesandbox.com -L5001:127.0.0.1:2001

I can see that the tunnel is up and running. But when I use the public IP of Server-A and try to connect to the database, It does not work.

If I create another tunnel between between Server-A and where I run the MySQL client. then it works. But I don't want to do that.

What can be the reason for this issue. I am fairly new to scripting


Solution

  • by default local side (ssh client) creates listening port at loopback interface with address 127.0.0.1 when you use command like this

    ssh me@server -L3306:localhost:3306
    

    if you check netstat on your host you will see something like this

    sudo netstat -ntlp | grep 3306
    tcp  0 0 127.0.0.1:3306  0.0.0.0:*   LISTEN 12354/ssh
    

    So applications at your local node can connect to such mapped service because loopback interface is visible to host itself but external nodes have no access to this virtual interface so can't make any connections to any service(port) which is listening on this single interface.

    To instruct local ssh client to share such mapped port to the world you need to instruct it to bind to either all interfaces (including loopback) or to specific interface only

    # here you explicitly tell ssh client to accept connection to your tunnel
    # from any client(i.e. bind listenning port to all interfaces)
    ssh me@server -L0.0.0.0:3306:localhost:3306 
    sudo netstat -ntlp | grep 3306 
    tcp  0 0 0.0.0.0:3306   0.0.0.0:*   LISTEN 12354/ssh
    
    #here you do the same thing by using -g option
    ssh me@server -g -L3306:localhost:3306
    sudo netstat -ntlp | grep 3306 
    tcp  0 0 0.0.0.0:3306   0.0.0.0:*   LISTEN 12354/ssh
    
    #and here is an example of how to bind to specific interfaces only
    # 10.0.0.12 is an IP of one of interfaces on your node
    # 10.1.0.156 is also IP address of one interfaces of your node
    ssh me@server -L10.0.0.12:3306:localhost:3306 -L10.1.0.156:3306:localhost:3306
    
    sudo netstat -ntlp | grep 3306
    tcp  0 0 10.0.0.12:3306   0.0.0.0:*   LISTEN 12354/ssh
    tcp  0 0 10.1.0.156:3306  0.0.0.0:*   LISTEN 12354/ssh