【问题标题】:JSch multiple tunnels/jumphostsJSch 多个隧道/跳转主机
【发布时间】:2019-05-03 01:11:07
【问题描述】:

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

我需要将本地端口 3308 一直转发到我的 SQL DB 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);

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

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

我在 JSch 或端口转发方面做错了吗?

【问题讨论】:

    标签: java ssh jsch portforwarding ssh-tunnel


    【解决方案1】:

    您的 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
      

      另见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的保护。

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

    【讨论】:

      猜你喜欢
      • 2016-07-26
      • 2017-03-31
      • 1970-01-01
      • 2020-10-26
      • 2015-05-05
      • 2021-10-28
      • 2018-07-20
      相关资源
      最近更新 更多