2

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

diyoda_
  • 5,274
  • 8
  • 57
  • 89
  • you need to use -g flag to bind local listening port to 0.0.0.0 for external hosts to use your tunnel - [see pitfalls section here](https://stackoverflow.com/a/61286246/12396017). your command has to be ```ssh -N -i ~/keys/test.pem bisco@bisco.storesandbox.de -g -L0.0.0.0:3306:127.0.0.1:3306``` – Maxim Sagaydachny Apr 20 '20 at 06:09
  • You plan to open the service to the world anyway so it does not matter much which of servers does expose it and which exposition method is used. IF sql server has public IP address then you could just open port 3306 at original sql server, i.e. tell it to bind to 0.0.0.0 instead of 127.0.0.1. Then you could be able to connect to it directly without usage of Server-A – Maxim Sagaydachny Apr 20 '20 at 07:25

1 Answers1

2

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

Maxim Sagaydachny
  • 2,098
  • 3
  • 11
  • 22