JSch 多个隧道/跳转主机
Posted
技术标签:
【中文标题】JSch 多个隧道/跳转主机【英文标题】:JSch multiple tunnels/jumphosts 【发布时间】: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 或端口转发方面做错了吗?
【问题讨论】:
【参考方案1】:您的 ssh
命令正在使用在“跳转框”上运行的 SSH 客户端(另一个 ssh
)。
如果您想使用 Java 实现相同的功能,您有两种选择:
在 Java 中做同样的事情,即使用session
在“跳转框”上运行ssh -L 3307:mysqlDB:3306 username@server
。
见Executing a command using JSch。
不过,我认为您不应该依赖 ssh
程序进行第二次跳转,原因与您使用 Java/JSch 进行第一次跳转的原因相同(而不是 ssh
程序)。
避免使用单独的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?
【讨论】:
以上是关于JSch 多个隧道/跳转主机的主要内容,如果未能解决你的问题,请参考以下文章