SSH tunnel Socks5 proxy

Oct 27, 2013 at 10:00 PM
Edited Oct 27, 2013 at 10:01 PM
Can this library mimic the ssh -D option where it will spawn a listening local port and the remote server will forward all client as if it was coming from it (via a socks proxy connection)? I've tried the ForwardedPortLocal, ForwardedPortRemote, ForwardedPortDynamic, functions with little to no luck (using firefox to test the connections).

What is the proper or easiest way to set something like this up. I'm starting to think that this library doesn't have this support, although I think it may be possible to work around this by forwarding to a web proxy on the server like squid.

Anyways any help is appreciated.
Oct 28, 2013 at 2:02 AM
Edited Oct 28, 2013 at 3:11 AM
After reading a bit more what I am looking for is definitely the ForwardedPortDynamic function, that creates a socks5 proxy tunnel to the server.

Here is my code
            using (SshClient client = new SshClient("192.168.0.173", "user", "pass")) {
                client.KeepAliveInterval = new TimeSpan(0, 0, 30);
                client.ConnectionInfo.Timeout = new TimeSpan(0, 0, 20);
                client.Connect();

                ForwardedPortDynamic port = new ForwardedPortDynamic("127.0.0.1", 10080);
                client.AddForwardedPort(port);
                client.SendKeepAlive();
                port.Start();
            }
This should work as this is what I've seen everywhere else using this library but yet it does not. When I launch the application and input the proxy settings into firefox, I get a "unable to connect, firefox cant establish a connection to the server" error, and when I close the application and try firefox again I get a "the proxy server is refusing connections" error. This makes be believe that there is something wrong trying to forward the data. Im pretty sure I am getting a valid connection to the ssh server, although I do not know how to verify this (credentials are correct).

Also putty works for connecting to the server, as well as setting up a dynamic socks5 tunnel proxy (it works in firefox).

Anyone have any ideas what is going on?

edit:: update, using the same code this project worked in a console based project, but when using this code in a gtk# project it behaves this wrong way.
using System;
using Gtk;
using Renci.SshNet;

namespace Testing
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            Application.Init();
            MainWindow win = new MainWindow();

            using (SshClient client = new SshClient("192.168.0.173", "user", "pass")) {
                client.KeepAliveInterval = new TimeSpan(0, 0, 30);
                client.ConnectionInfo.Timeout = new TimeSpan(0, 0, 20);
                client.Connect();

                ForwardedPortDynamic port = new ForwardedPortDynamic("127.0.0.1", 10080);
                client.AddForwardedPort(port);
                client.SendKeepAlive();
                port.Start();
            }

            win.Show();
            Application.Run();
        }
    }
}
Oct 28, 2013 at 6:56 AM
IMHO your code is wrong.
When the using-block is passed the Sshclient gets disposed, and therefore every forwarding and connection is closed.
I'm quite sure, if you remove the using it'll work.
Oct 28, 2013 at 7:24 AM
Edited Oct 28, 2013 at 7:27 AM
Upon further investigation it is a problem with the library itself. The using block was wrong, but the library itself does not parse the dns queries server side, resulting in a invalid ip error, because the client attempts to resolve the dns itself it seems.

I posted an issue here: https://sshnet.codeplex.com/workitem/1797

edit: it seems even if you turn off the socks_remote_dns option, it still throws the exception.
Oct 28, 2013 at 3:16 PM
This problem similar to mine. If you use socks5 (and mostly do) this exception happen when ForwardedPortDynamic.HandleSocks5() unable to parse the hostname to get the ipAddress.
You may wanna take a look at this https://sshnet.codeplex.com/discussions/463912
Oct 28, 2013 at 6:48 PM
Edited Oct 28, 2013 at 7:09 PM
Thanks for that ShienIkiru, I was also trying to patch the source itself, but your method is cleaner than mine. Your method also works and errors in the same way for my project. It works for the first few connections, then the listening port times out, ssh client connection gets aborted, then a SocketException gets thrown.

This is using the previous code in my issue work item post with modified DLL from your post.
Conected to
Key Exchange
Client is connected to sshd
Port forwarding started
Requested conection to ifconfig.me:80
Requested conection to ifconfig.me:80
Requested conection to ifconfig.me:80
Requested conection to ifconfig.me:80
Requested conection to ifconfig.me:80
Requested conection to ifconfig.me:80
Listenport error : Session operation has timed out
Client error : An established connection was aborted by the software in your host machine.
Listenport error : An established connection was aborted by the software in your host machine.
Listenport error : An established connection was aborted by the software in your host machine.
Requested conection to ifconfig.me:80
Listenport error : An established connection was aborted by the software in your host machine.
Requested conection to ifconfig.me:80
Listenport error : An established connection was aborted by the software in your host machine.

Unhandled Exception: System.Net.Sockets.SocketException: An established connection was aborted by the software in your host machine
   at System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at Renci.SshNet.Session.SocketWrite(Byte[] data)
   at Renci.SshNet.Session.SendMessage(Message message)
   at Renci.SshNet.Session.SendKeepAlive()
   at Renci.SshNet.BaseClient.SendKeepAlive()
   at Renci.SshNet.BaseClient.<set_KeepAliveInterval>b__0(Object state)
   at System.Threading._TimerCallback.TimerCallback_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading._TimerCallback.PerformTimerCallback(Object state)
Press any key to continue . . .

As you can tell I refreshed a few times, and It was working, then everything shut down unexpectedly.
Oct 30, 2013 at 11:57 AM
I've found a little fix. You may want to check it out.