user3079266
user3079266

Reputation:

Java: SSH tunneling - set local SOCKS as the listener

What I want to do is to set up a SOCKS server and then add its port as the local listening port in an SSH tunnel connection. What I want to achieve is dynamic port forwarding (the -D option in ssh, if I remember correctly). I'm using JSch for SSH tunneling. Here's the code that I have so far (copied from http://kahimyang.info/kauswagan/code-blogs/1337/ssh-tunneling-with-java-a-database-connection-example):

int assigned_port;   
int local_port=<local listening port goes here>;

// Remote host and port
int remote_port=<remote port goes here>;
String remote_host = "<SSH host goes here>";
String login = "<SSH login goes here>";
String password = "<SSH password goes here>";

try {
    JSch jsch = new JSch(); 

    // Create SSH session.  Port 22 is your SSH port which
    // is open in your firewall setup.
    Session session = jsch.getSession(login, remote_host, 22);
    session.setPassword(password);

    // Additional SSH options.  See your ssh_config manual for
    // more options.  Set options according to your requirements.
    java.util.Properties config = new java.util.Properties();
    config.put("StrictHostKeyChecking", "no");
    config.put("Compression", "yes");
    config.put("ConnectionAttempts","2");

    session.setConfig(config);

    // Connect
    session.connect();            

    // Create the tunnel through port forwarding.  
    // This is basically instructing jsch session to send 
    // data received from local_port in the local machine to 
    // remote_port of the remote_host
    // assigned_port is the port assigned by jsch for use,
    // it may not always be the same as
    // local_port.

    assigned_port = session.setPortForwardingL(local_port, 
            remote_host, remote_port);

} catch (JSchException e) {            
    System.out.println("JSch:" + e.getMessage());
    return;
}

if (assigned_port == 0) {
    System.out.println("Port forwarding failed!"); 
    return;
}

However, If I start up a local SOCKS proxy on my client machine, JSch cannot use its port as a local listening port saying that it cannot be bound. I gather that is because the port is occupied by the SOCKS server (which is pretty obvious, huh). The question is, what is the correct way to do dynamic port forwarding with JSch?

Upvotes: 2

Views: 3109

Answers (2)

David Ehrmann
David Ehrmann

Reputation: 7576

Here's the description of -D:

Specifies a local "dynamic" application-level port forwarding. This works by allocating a socket to listen to port on the local side, optionally bound to the specified bind_address. Whenever a connection is made to this port, the connection is forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. Currently the SOCKS4 and SOCKS5 protocols are supported, and ssh will act as a SOCKS server. Only root can forward privileged ports. Dynamic port forwardings can also be specified in the configura- tion file.

@Kenster's right about what ssh does, but I think what you want isn't to run a SOCKS proxy remotely, but to implement a Java SOCKS proxy server server in jsch (then contribute it back to jsch).

Upvotes: 2

Kenster
Kenster

Reputation: 25380

If the SOCKS proxy were running on the remote server, you could make an SSH tunnel from a port on the local server to the SOCKS proxy port on the remote server. Once you set that up, your SOCKS-capable client could use the local tunnel port as if it were the SOCKS proxy.

The OpenSSH ssh program and the windows Putty utility have built-in SOCKS proxy capability. You could just use one of them.

Upvotes: 3

Related Questions