0

I can't seem to wrap my head around the concept of ssh tunneling. The situation I'm currently in is that I have:

  • Server A, which can be accessed through ssh, and inside it there's a mysql db accessed through localhost:3306.
  • Server B, which has ssh access to A.
  • MySQL instance C which has access to B. I can only access the db server, not the server itself, so I am unable to ssh anywhere from C. I can only connect to any port on B.

My goal is MySQL replication from A to C, where A is the master, and C - the slave. How should I proceed if I wanted to connect from C to A. I imagine it something like this diagram:

C ─────────B:B_PORT────────> B
                            │││
         |/─────tnl A:22────┘││
A_db <────localhost:3306─────┘│
         |\─────tnl A:22──────┘

So far I tried to run this on B sudo ssh -L B_PORT:localhost:3306 A_user@A_ip -f -N but I still can't seem to access A from C, when connecting to B_PORT.

EDIT: Also tried ssh -L B_PORT:localhost:3306 A_user@A_ip -f -N -g as suggested by @larsks with no avail. His explanation leads me to believe there might be issues within the network

My journey so far

  1. Create tunnel on B with ssh -L B_PORT:localhost:3306 A_user@A_ip -f -N -g
  2. Connect C to B.
  3. netstat on B shows multiple SYN_RECV connections from C to B
  4. If I try to connect to B_PORT from B I get this
packet_write_wait: Connection to A port 22: Broken pipe
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0
  1. ssh connection is dropped on B and tunnel needs to be reopened
  2. Fiddled around with security groups and other network rules. Enabled network inbound and outbound from and to C and everything is working!
1
  • Thank you for the suggestions (both on the diagnosing and on question composing). It seems that I solved my problems and everything is alright
    – jazzimier
    Commented Aug 21, 2019 at 11:32

2 Answers 2

3

You need to add the -g option to your ssh command line:

     -g      Allows remote hosts to connect to local forwarded ports.
             If used on a multiplexed connection, then this option
             must be specified on the master process.

This will expose forwarded ports on host B so that they are accessible from C. This assumes your firewall configuration on B permits these connections.

The -g option changes the local bind address that ssh uses for the local port. Without -g, -L 8000:localhost:8000 results in:

$ netstat -tln | grep 8000
tcp        0      0 127.0.0.1:8000          0.0.0.0:*               LISTEN     
tcp6       0      0 ::1:8000                :::*                    LISTEN     

As you can see, in this case, both sockets are bound to the loopback address (127.0.0.1 for ipv4 and ::1 for ipv6).

With -g, we instead get:

$ netstat -tln | grep 8000
tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN     
tcp6       0      0 :::8000                 :::*                    LISTEN     

In this case, you can see that ssh is now binding to the wildcard address instead of the loopback address.

5
  • Executed sudo ssh -L B_PORT:localhost:3306 A_user@A_ip -f -N -g on B. Still cannot connect from C. Will try to investigate firewall issues and etc. Thank you!
    – jazzimier
    Commented Aug 20, 2019 at 11:45
  • Thanks. After running your command I can see the incoming connections in netstat. They're stuck on SYN_RECV, so I will investigate further. Thank you
    – jazzimier
    Commented Aug 20, 2019 at 13:15
  • I don't like this answer, it does not seem to address your problem. Why did you accept it. Commented Aug 21, 2019 at 6:50
  • @ctrl-alt-delor what about this answer doesn't seem to address the problem? Using -g to open up ports to external connections seems to be exactly what the OP was asking about.
    – larsks
    Commented Aug 21, 2019 at 11:28
  • Now that the question is amended. I see that this may be a good answer. Commented Aug 22, 2019 at 13:31
0

Why the sudo? sudo is not the answer to all problems, and often the cause.

I think this is what you want.

ssh -L local_port:remote_ip:remote_port jump_user@jump_ip
ssh -L C_PORT:A_ip:3306 B_user@B_ip -f -N
  • remote is from jump's perspective
  • jump is from local's perspective
4
  • These commands should be executed from B? Why interchangeably use "local, jump, remote" notation and my "A B C" notation when it might cause more confusion. Or are they interchangeable?
    – jazzimier
    Commented Aug 21, 2019 at 8:42
  • You run it from C (the place that you said you want to connect from). I have given two examples. The first is more generic, the 2nd is for your case. Commented Aug 21, 2019 at 8:45
  • As I said, I cannot run commands from C, I only have access to the db directly. Thank you for clarifying the examples.
    – jazzimier
    Commented Aug 21, 2019 at 8:47
  • I think you will need to edit you question, to make it clear what you are trying to do. Commented Aug 21, 2019 at 8:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .