Port Forwarding Java SSH Example

Introduction

In addition to remote shells and secure file transfer, SSH provides a port forwarding feature that allows users to connect to arbitrary services on the remote network. Users can forward TCP data from a local IP address and port to another address on the remote network. This is called local forwarding.

It’s also possible to do this in reverse and called remote forwarding. A user connects to a socket on the remote server, and the data is forwarded back to a host in the client’s local network.

Source Code

package examples;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.sshtools.client.SshClient;
import com.sshtools.common.permissions.UnauthorizedException;
import com.sshtools.common.ssh.SshException;
import com.sshtools.common.util.Utils;

public class PortForwarding {

   public static void main(String[] args) throws IOException {

   try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
			
      String hostname = Utils.prompt(reader, "Hostname", "localhost");
      int port = 22;
      if (Utils.hasPort(hostname)) {
         port = Utils.getPort(hostname);
      }

      String username = Utils.prompt(reader, "Username", System.getProperty("user.name"));
      String password = Utils.prompt(reader, "Password");

      try (SshClient ssh = new SshClient(hostname, port, username, password.toCharArray())) {

         /**
          * First we must allow forwarding. Without this no forwarding is possible. This
          * will allow us to forward from localhost and accept remote forwarding from the
          * remote server.
          */
         ssh.getContext().getForwardingPolicy().allowForwarding();
				
         /**
          * A local forward allows the ssh client user to connect to a resource
          * on the remote network
          */
         ssh.startLocalForwarding("127.0.0.1", 8443, "www.jadaptive.com", 443);
				
         /**
          * A remote forward allows a user to connect from the remote computer to 
          * a resource on the client's network
          */
         ssh.startRemoteForwarding("127.0.0.1", 8080, "service.local", 80);

         /**
          * If we want to allow other local computers to connect to our forwarding we can
          * allow gateway forwarding. This allows a local forwarding to be started on a
          * wildcard or IP address of the client that can accept connections from external
          * computers. With this enabled, we have to start the forwarding so that we are 
          * listening on a publicly accessible interface of the client.
          */
				                                             
         ssh.getContext().getForwardingPolicy().allowGatewayForwarding();
				
         /**
          * We we start a local forwarding that is accessible by any IP on the clients
          * network. This is called "Gateway Forwarding"
          */
         ssh.startLocalForwarding("::", 9443, "www.jadaptive.com", 443);
				
         /**
          * Wait for the connection to be disconnected.
          */
         ssh.getConnection().getDisconnectFuture().waitForever();
				
         } catch (UnauthorizedException e) {
            System.out.println(e);
         } 

      } catch (IOException | SshException e) {
         System.out.println(e);
      }
   }
}