JSch 倍数 tunnels/jumphosts

JSch multiple tunnels/jumphosts

我不确定这是否是由于使用私钥而不是端口转发密码引起的,但这是我正在尝试做的事情

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

我可以 运行 在我本地的终端中完成类似的事情

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

或 运行 我本地的第一部分,然后是 jumpbox 的第二部分。两者都工作正常,我可以连接到我的 localhost: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);

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

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

我是不是在 JSch 或端口转发方面做错了什么?

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

当您想使用 Java 实现相同的功能时,您有两个选择:

  1. 在Java中做同样的事情,即在“跳转框”上使用session到运行ssh -L 3307:mysqlDB:3306 username@server

    参见

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

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

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

    另见 Does OpenSSH support multihop login?

    我更喜欢这种方法。


要实施后一种方法:

  • 您必须将一些本地端口转发到 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.

的保护

有关正确(和安全)的方法,请参阅: