Uploaded image for project: 'MINA SSHD'
  1. MINA SSHD
  2. SSHD-1066

Support multiple local interfaces in PortForwarding

    XMLWordPrintableJSON

Details

    • New Feature
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 2.5.1
    • 2.6.0
    • None

    Description

      I'm trying to listen in same port on 2 IPs of same machine, multihomed, the equivalent in openssh is:

      # ssh -L 127.0.0.2:8080:test.javastack.org:80 -L 127.0.0.3:8080:test.javastack.org:80 test-sshd@server -N
      # sudo netstat -lntp | grep :8080
      tcp  0 0  127.0.0.3:8080  0.0.0.0:*  LISTEN  2650/ssh
      tcp  0 0  127.0.0.2:8080  0.0.0.0:*  LISTEN  2650/ssh
      

      Sample code to reproduce the test case:

      	public static final int DEFAULT_TIMEOUT = 10000;
      
      	public static void test(final String username, final String password, final String host, final int port)
      			throws IOException {
      		boolean testLocal = true;
      		try (SshClient client = SshClient.setUpDefaultClient()) {
      			client.setServerKeyVerifier(AcceptAllServerKeyVerifier.INSTANCE);
      			client.start();
      			try {
      				ConnectFuture connect = client.connect(username, host, port);
      				connect.await(DEFAULT_TIMEOUT);
      				ClientSession session = connect.getClientSession();
      				session.addPasswordIdentity(password);
      				session.auth().verify(DEFAULT_TIMEOUT);
      
      				if (testLocal) {
      					System.out.println("================== Local 1 ==================");
      					ExplicitPortForwardingTracker localTracker1 = session.createLocalPortForwardingTracker(
      							new SshdSocketAddress("127.0.0.2", 8080),
      							new SshdSocketAddress("test.javastack.org", 80));
      					sleep(1000);
      					System.out.println("LocalPortForwarding: " //
      							+ localTracker1.getLocalAddress() + " -> " //
      							+ localTracker1.getRemoteAddress());
      					SshdSocketAddress localSocketAddress1 = localTracker1.getLocalAddress();
      					if (localSocketAddress1 != null) {
      						Proxy proxy = new Proxy(Proxy.Type.HTTP,
      								new InetSocketAddress(localSocketAddress1.getHostName(), //
      										localSocketAddress1.getPort()));
      						testRemoteURL(proxy, "http://test.javastack.org/");
      					}
      					System.out.println("================== Local 2 ==================");
      					ExplicitPortForwardingTracker localTracker2 = session.createLocalPortForwardingTracker(
      							new SshdSocketAddress("127.0.0.3", 8080),
      							new SshdSocketAddress("test.javastack.org", 80));
      					sleep(1000);
      					System.out.println("LocalPortForwarding: " //
      							+ localTracker2.getLocalAddress() + " -> " //
      							+ localTracker2.getRemoteAddress());
      					SshdSocketAddress localSocketAddress2 = localTracker2.getLocalAddress();
      					if (localSocketAddress2 != null) {
      						Proxy proxy = new Proxy(Proxy.Type.HTTP,
      								new InetSocketAddress(localSocketAddress2.getHostName(), //
      										localSocketAddress2.getPort()));
      						testRemoteURL(proxy, "http://test.javastack.org/");
      					}
      				}
      			} finally {
      				client.stop();
      			}
      		}
      
      	}
      
      	private static final void sleep(final long t) {
      		try {
      			Thread.sleep(t);
      		} catch (Exception ign) {
      		}
      	}
      
      	private static final void testRemoteURL(final Proxy proxy, final String url) throws IOException {
      		HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(proxy);
      		connection.setConnectTimeout(DEFAULT_TIMEOUT);
      		connection.setReadTimeout(DEFAULT_TIMEOUT);
      		System.out.println("Get URL: " + connection.getURL());
      		try {
      			BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
      			System.out.println("Response from server:");
      			String inputLine;
      			while ((inputLine = in.readLine()) != null) {
      				System.out.println(inputLine);
      			}
      			in.close();
      		} catch (Exception e) {
      			System.out.println("Failed: " + e);
      		}
      	}
      
      	public static void main(String[] args) throws Throwable {
      		test("test-sshd", "secret", "server", 22);
      		sleep(3000);
      	}
      

      Error received:

      Exception in thread "main" java.io.IOException: Multiple local port forwarding addressing on port=8080: current=test.javastack.org:80, previous=test.javastack.org:80
      	at org.apache.sshd.common.forward.DefaultForwardingFilter.startLocalPortForwarding(DefaultForwardingFilter.java:208)
      	at org.apache.sshd.client.session.AbstractClientSession.startLocalPortForwarding(AbstractClientSession.java:374)
      	at org.apache.sshd.client.session.ClientSession.createLocalPortForwardingTracker(ClientSession.java:316)
      	at org.javastack.jentunnel.sandbox.SimpleBindingTest.test(SimpleBindingTest.java:52)
      

      Result Expected:

      ================== Local 1 ==================
      LocalPortForwarding: 127.0.0.2:8080 -> test.javastack.org:80
      Get URL: http://test.javastack.org/
      Response from server:
      OK
      ================== Local 2 ==================
      LocalPortForwarding: 127.0.0.3:8080 -> test.javastack.org:80
      Get URL: http://test.javastack.org/
      Response from server:
      OK
      
      • Note-1: The usage of loopback addresses (127.0.0.0/8) and same destination is to simplify/reproduce easily, don't care.
      • Note-2: I don't checked if startRemotePortForwarding/startDynamicPortForwarding reproduce same issue as startLocalPortForwarding. But I suppose that yes.

      Attachments

        Issue Links

          Activity

            People

              lgoldstein Lyor Goldstein
              technobcn Guillermo Grandes
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 0.5h
                  0.5h