5

I am developing a test app to understand how to do SSH tunnelling to connect to a MySQL Database in C++.

I am using the libssh2 library and I am using an example from https://www.libssh2.org/examples/direct_tcpip.html but I am not 100% sure whether or not this is the correct thing to use.

I've pretty much copied the example but when connecting to MySQL on my socket, MySQL throws:

Errro 2013 (HY000): Lost connection to mysql server at 'reading communication packet', system error: 0

When I connect to mysql using mysql -uroot -p -P2222 my app reads data on the channel using the following:

int len = libssh2_channel_read(channel, buf, sizeof(len));

and the buf contains SSH-2.0- and then this is written to the forwarding socket as follows:

wr = 0;
while (wr < len)
{
    i = send(forward_socket, buf + wr, len - wr, 0);
    if (i <= 0)
    {
        perror("write");
        return EXIT_FAILURE;
    }
    wr += i;
}

As soon as the send is done, I instantly get the mysql error. I assume it is because I am sending SSH-2.0- to MySQL which MySQL isn't expecting so its closing the connection but I can't see what's wrong, and I can't find for certain whether or not libssh2 direct_tcpip is the correct thing to use.

halfer
  • 19,824
  • 17
  • 99
  • 186
Boardy
  • 35,417
  • 104
  • 256
  • 447
  • There is a similar thread here http://stackoverflow.com/questions/21091850/error-2013-hy000-lost-connection-to-mysql-server-at-reading-authorization-pa – Misgevolution Dec 21 '16 at 08:47
  • That's not really related, yes its the same error but that's to do with MySQL config/network not C++ programatically creating an SSH tunnel which is what I am trying to do – Boardy Dec 21 '16 at 16:00
  • Wait what is it your trying to do from the start. SSH Tunnelling is a socket thing E.G you tunnel Client port `8282` to Server `3306` once that is setup your MySQL client can then use `localhost:8282` on your client machine E.G MySQL Workbench to connect to `localhost:8282` and it will connect to your server on port `3306` – Barkermn01 Dec 22 '16 at 16:33
  • nothing wrong with a Proof of Concept for understanding, but if I heard of somebody doing this in the Real World, I would strongly recommend against it I have trouble seeing why you'd do the ssh tunneling in the app when it cleanly and easily can be a layer outside of the app. Further , MySQL already provides ssl encryption capabilities on the data stream, making ssh tunnel even more of a runtime detail. – erik258 Dec 24 '16 at 16:56
  • It's part of an API for an android app – Boardy Dec 24 '16 at 17:47

2 Answers2

3

Finally, managed to figure out what to do, with lots of trial and error and hair pulling managed it.

Using the example from https://www.libssh2.org/examples/direct_tcpip.html but I was setting the variables with the wrong value.

Basically, in the example it has

const char *remote_desthost = "localhost"; /* resolved by the server */ 
unsigned int remote_destport = 22;

Because of remote_destport in the example being 22, I thought this was the SSH connection details so I set this to be my SSH settings.

It turns out this is where the connection gets forwarded to from the SSH session so I changed it to be

const char *remote_desthost = "localhost"; /* resolved by the server */ 
unsigned int remote_destport = 3306;

So now I can run my app from my laptop, which connects to my SSH server for my web server and then on my laptop run in the command

mysql -uroot -p -P2222 and I connect to the database on my webserver through the SSH tunnel.

Boardy
  • 35,417
  • 104
  • 256
  • 447
1

I think you have misunderstood what SSH Tunnelling is.

SSH Tunnelling is nothing more than a Client Socket to Server Socket Mapping E.G a Firewalled Network port.

Putty Setup a SSH Tunnel

And to show that this is how it works. i used my personal web server and connected to a MySQL server that does not allow any external connections to it so connections from localhost only.

Connection though SSH Tunnel

To Setup a SSH Tunnel using LibSSH2 follow the code at http://api.libssh.org/master/libssh_tutor_forwarding.html under heading Doing direct port forwarding with libssh

If you don't want to expose the mapping to a port on your client machine you don't necessarily have to you could manually send data down the channel and read it however if there is any form of encryption or text encoding that does not match your on the channel to mysql you will send invalid data to it.

So once you have SSH Tunnelling created then you use it as a standard network connection to the port you have Tunnelled to talk to the service if you wish to do this in C++ use the MySQL C++ Connector and once the tunnel is create connect using the C++ Connector.

If you wish to allows your application to talk to MySQL though the SSH channel without exposing it to a network port, you probably gonna have to mess with the source code for the C++ MySQL Connector. A lot, more work that you think it is you would be going though the entire connector and any writing and reading it does via the Network Socket and replace it with code to go though your SSH Tunnel Channel.

Barkermn01
  • 6,781
  • 33
  • 83
  • Thanks, I haven't misunderstood SSH tunnelling, I've done it before in C# and I use it often, but converting the C# app to C++ hence why I need to the SSH tunnelling. The documentation of libssh2 seemed pretty poor so I've found another library now which I'm working with instead – Boardy Dec 22 '16 at 18:22