Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
214 views
in Technique[技术] by (71.8m points)

java - JSch multiple tunnels/jumphosts

I'm not sure if this is caused by using a private key instead of password for the port forwarding but here's what I'm trying to do

enter image description here

I need to forward local port 3308 all the way to the my SQL DB at 3306.

I can run things like this all together in terminal on my local

ssh -L 3308:localhost:3307 username@jumpbox "ssh -L 3307:mysqlDB:3306 username@server"

Or run the first part on my local and then the second part on the jumpbox. Both works fine and I can connect to my localhost:3308.

The problem comes when I start using JSch. Here is my code

JSch jsch = new JSch();
jsch.addIdentity("~/.ssh/id_rsa");

Session session = jsch.getSession("username", "jumpbox");
session.setConfig("StrictHostKeyChecking", "no");
session.connect();

int assinged_port = session.setPortForwardingL(3308, "localhost", 3307);
Session mysqlSession = jsch.getSession("username", "server", assinged_port);
mysqlSession.setConfig("StrictHostKeyChecking", "no");
mysqlSession.connect(); // Connection timed out here
mysqlSession.setPortForwardingL(3307, "mysqlDB", 3306);

The first connection is done but the second one timed out.

Exception in thread "main" com.jcraft.jsch.JSchException: java.net.ConnectException: Operation timed out (Connection timed out)

Am I doing something wrong here with JSch or port forwarding?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Your ssh command is making use of an SSH client (another ssh) running on "jump box".

When you want to implement the same using Java, you have two options:

  1. Do the same in Java, i.e. use session to run ssh -L 3307:mysqlDB:3306 username@server on the "jump box".

    See Executing a command using JSch.

    Though, I do not think you should rely on ssh program for the second jump, for the same reason you use Java/JSch for the first jump (and not ssh program).

  2. Avoid using a separate ssh tool, and instead open the other SSH session locally via yet another forwarded port. You can actually do the same using recent versions of ssh, with -J (jump) switch (supported since OpenSSH 7.3):

    ssh -L 3308:mysqlDB:3306 -J username@jumpbox username@server
    

    See also Does OpenSSH support multihop login?

    I prefer this approach.


To implement the latter approach:

  • You have to forward some local port to server:22, so that you can open SSH connection to the server:

    JSch jsch = new JSch();
    jsch.addIdentity("~/.ssh/id_rsa");
    
    Session jumpboxSession = jsch.getSession("username", "jumpbox");
    jumpboxSession.connect();
    
    int serverSshPort = jumpboxSession.setPortForwardingL(0, "server", 22);
    Session serverSession = jsch.getSession("username", "localhost", serverSshPort);
    serverSession.connect();
    
  • Then you forward another local port via server to MySQL port:

    int mysqlPort = serverSession.setPortForwardingL(0, "mysqlDB", 3306);
    

    Now you should be able to connect to localhost:mysqlPort using MySQL client.


Obligatory warning: Do not use StrictHostKeyChecking=no to blindly accept all host keys. That is a security flaw. You lose a protection against MITM attacks.

For a correct (and secure) approach, see:
How to resolve Java UnknownHostKey, while using JSch SFTP library?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...