16

I'm attempting to use SSH.NET to create a tunnel from localhost:3306 to port 3306 on a remote machine:

  PrivateKeyFile file = new PrivateKeyFile(@" .. path to private key .. ");
  using (var client = new SshClient(" .. remote server .. ", "ubuntu", file))
  {

      client.Connect();
      var port = new ForwardedPortLocal(3306, "localhost", 3306);
      client.AddForwardedPort(port);
      port.Start();

            // breakpoint set within the code here

      client.Disconnect();
  }

When the breakpoint is hit, client.IsConnected is returning true, but telnet localhost 3306 is not connecting. If I create the connection using Putty instead, and set up the same tunnel there, it succeeds. What have I missed?

Adrian Wragg
  • 7,311
  • 3
  • 26
  • 50
  • Do you get a specific warning for the telnet application? Does it close? Binary connection data may not be displayed... – Maarten Bodewes Aug 29 '13 at 10:08
  • It hangs, failing to connect. When using Putty I get a string of data. – Adrian Wragg Aug 29 '13 at 10:09
  • Try [this link](http://sshnet.codeplex.com/discussions/348423): I think disconnecting the client is the issue. And if you break between `Start` and `Disconnect` you may also halt the forwarding. – Maarten Bodewes Aug 29 '13 at 10:11
  • There seem to be a number of bugs in older versions of the library as well, make sure you are using the latest version. – Maarten Bodewes Aug 29 '13 at 10:15
  • @owlstead Thanks - I've checked, and I'm using 2013.4.7.0, the latest version. – Adrian Wragg Aug 29 '13 at 10:20
  • @owlstead The client isn't disconnecting, and I'm not 'breaking' as such - I just have a breakpoint that the code hits, at which point I go to my telnet client. Note that the code I've commented out is designed to use a tunnel, and if I run that independently (with the tunnel created using Putty instead) it succeeds. – Adrian Wragg Aug 29 '13 at 10:25

2 Answers2

21

By changing the parameters of ForwardedPortLocal to:

    var port = new ForwardedPortLocal("localhost", 3306, "localhost", 3306);

(to make it explicit which interface I was binding to), and adding the following code in just before port.Start();:

    port.RequestReceived += delegate(object sender, PortForwardEventArgs e)
    {
        Console.WriteLine(e.OriginatorHost + ":" + e.OriginatorPort);
    };

I noticed the following being output:

    ::1:60309

The e.OriginatorHost part of this was ::1, which is the IPv6 equivalent of localhost; however, the destination server was using IPv4. Changing the parameters to:

    var port = new ForwardedPortLocal("127.0.0.1", 3306, "localhost", 3306);

forced the tunnel to run over IPv4 instead, and my code then worked exactly as I'd expected it to.

Adrian Wragg
  • 7,311
  • 3
  • 26
  • 50
  • 1
    Thank you so much for the solution. I tried to work on this since hours >. – Keenora Fluffball Sep 27 '13 at 11:29
  • See my question if your struggling like I was with a local MySQL instance on your dev machine :-) http://stackoverflow.com/questions/40592492/ssh-access-using-renci-ssh-to-mysql-server/40606542#40606542 – Captain John Nov 15 '16 at 09:44
0

After hitting the same problem and analyzing it, and considering I came to the conclusion that it is a bug (though it might be considered arguable, clearly the behavior surprises users of SSH.NET API).

So I reported it on Unexpected behavior (a.k.a. bug) on local tunnel · Issue #117 · sshnet/SSH.NET · GitHub.

Until it is fixed, the workaround in c# - Creating a forwarded port within an SSH tunnel - Stack Overflow works.

Community
  • 1
  • 1
Stéphane Gourichon
  • 6,493
  • 4
  • 37
  • 48