在 Java 中通过 SSH 隧道运行远程命令

Posted

技术标签:

【中文标题】在 Java 中通过 SSH 隧道运行远程命令【英文标题】:Run remote commands through SSH tunnel in Java 【发布时间】:2012-03-06 04:11:41 【问题描述】:

我需要使用 SSH 连接从远程计算机运行一些命令,但问题如下:

客户端计算机(运行 Windows)连接到我可以看到远程服务器的网络(第二台 *nix 计算机,在同一网络中)。我可以使用它进行 SSH 连接,但是包含文件(运行 *nix)的计算机不在此网络中,我只能通过在第二台计算机上打开的动态 SSH 隧道与此连接,我通常使用 PuTTY 来配置此连接。然后我就可以访问远程文件了。

下图代表架构(防火墙就像第二台机器):

我需要自动完成这项工作,所以我用 Java 和 JSch 库做了一些测试,下面是一些代码:

/* Direccion y puerto del host local */
String host = "localhost";
int lport = 5040;


/* Direccion y puerto del host remoto*/
String rhost = "localhost";
int rport = 80;

/* Usuario y password para conectarse al servidor ssh*/
String user = "test";
String pwd = "test";

JSch jsch=new JSch();

Session session=jsch.getSession(user, host, 22);
session.setPassword("test");

Properties config = new Properties();
config.put("StrictHostKeyChecking","no");
session.setConfig(config);
session.connect();

int assinged_port=session.setPortForwardingL(lport, rhost, rport);
System.out.println("localhost:"+assinged_port+" -> "+rhost+":"+rport);

我得到了连接,但是当我使用对象session 运行命令时,答案来自第二台机器,而不是我预期的第三台机器。我想知道是否有另一个库可以帮助完成这项工作,或者我使用了错误的 JSch。

【问题讨论】:

【参考方案1】:

当然,如果你设置rhost = "localhost",连接将到达SSH服务器,而不是“资源”服务器。 输入正确的主机名,应该没问题。 (我做过一次。)

如果你想从 JSch 做两个连接,而不是做一个本地端口转发然后连接到这个转发端口,你可以使用我的 ProxySSH 类,找到 in the JSch wiki。 (我也这样做了,在与您类似的情况下。)

【讨论】:

能给我举个例子吗,我实现了连接成功 wiki 中的示例在我编写时(几个月前)确实对我有用,但当然您需要一个在目标服务器上具有执行权限的帐户。【参考方案2】:

您必须在端口转发后在第二台服务器上创建会话。然后与防火墙后面的服务器建立连接。

查看example的这段代码。这段代码所做的是创建一个本地端口转发到目标系统上的ssh端口,然后通过它进行连接。 hostname 命令的运行说明它确实在转发到的系统上运行。

【讨论】:

【参考方案3】:

您必须打开另一个使用转发端口的会话。

Session sessionA = jsch.getSession("usernameA", "hostA");
// ...
sessionA.connect();

int forwardedPort = 2222; // any port number which is not in use on the local machine
sessionA.setPortForwardingL(forwardedPort, "hostB", 22);

Session sessionB = jsch.getSession("usernameB", "localhost", forwardedPort);
// ...
sessionB.connect();

// Use sessionB here to execute your command

【讨论】:

以上是关于在 Java 中通过 SSH 隧道运行远程命令的主要内容,如果未能解决你的问题,请参考以下文章

在命令行中通过 ssh 在远程机器上运行 MySQL 查询

从 bash 脚本中通过 ssh 在远程主机上执行命令

在 DBeaver 中使用 ssh 隧道连接到远程数据库

Linux中通过ssh将客户端与服务端的远程连接

使用 Java 通过 SSH 隧道传输文件

在 GWT 应用程序中通过 SSH 与 DB 通信(使用 RPC)