JSch多个隧道/跳跃主机

时间:2018-11-30 21:13:35

标签: java ssh jsch portforwarding ssh-tunnel

我不确定这是否是由于使用私钥而不是密码进行端口转发引起的,但这是我要尝试的操作

enter image description here

我需要将本地端口3308一直转发到3306的SQL DB。

我可以在本地终端上一起运行这样的事情

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

或者在本地运行第一部分,然后在Jumpbox上运行第二部分。两者都可以正常工作,我可以连接到本地主机:3308。

当我开始使用JSch时出现问题。这是我的代码

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);

第一个连接完成,但第二个连接超时。

  

线程“ main” com.jcraft.jsch.JSchException中的异常:java.net.ConnectException:操作超时(连接超时)

我在这里用JSch或端口转发做错什么了吗?

1 个答案:

答案 0 :(得分:2)

您的ssh命令正在使用在“跳转框”上运行的SSH客户端(另一个ssh)。

要使用Java实现相同功能时,有两个选择:

  1. 在Java中执行相同的操作,即使用session在“跳转框”上运行ssh -L 3307:mysqlDB:3306 username@server

    请参见Executing a command using JSch

    尽管如此,我不认为您应该依赖ssh程序进行第二次跳转,出于相同的原因,您为第一次跳转使用Java / JSch(而不是ssh程序)。

  2. 避免使用单独的ssh工具,而应通过另一个转发的端口在本地打开另一个SSH会话。实际上,您可以使用ssh的最新版本和-J (jump) switch(自OpenSSH 7.3开始受支持)执行相同的操作:

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

    我更喜欢这种方法。


要实施后一种方法:

  • 您必须将一些本地端口转发到server:22,以便可以打开到server的SSH连接:

    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();
    
  • 然后您通过server将另一个本地端口转发到MySQL端口:

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

    现在,您应该可以使用MySQL客户端连接到localhost:mysqlPort


强制性警告:请勿使用StrictHostKeyChecking=no盲目接受所有主机密钥。那是一个安全漏洞。您失去了针对MITM attacks的保护。

有关正确(且安全)的方法,请参见:
How to resolve Java UnknownHostKey, while using JSch SFTP library?