7

我需要能够从 Java 程序 ssh 到远程服务器,然后从那里 SSH 到另一台服务器。我的客户端上的两台服务器都有凭据。

命令将在应用程序内作为常规字符串自动传递(无需用户输入)。我需要能够在第二台服务器上运行这些自定义命令,并能够根据输出和一些简单的逻辑决定在运行时发出哪些命令。

我可以使用 JSch 来做到这一点吗?如果可以,我应该从哪里开始研究?(示例,信息)

==================================================== ===========

添加:

线程“主”com.jcraft.jsch.JSchException 中的异常:UnknownHostKey:host.net。RSA 密钥指纹是“blahblahblah”

到目前为止,我正在通过修改 known_hosts 文件并在其中手动添加主机来解决这个问题。我可以通过在某处设置一个选项来绕过这个小问题,告诉 JSch 在询问这个 YES-NO 问题时自动按 YES 吗?

4

3 回答 3

12

要连接到防火墙后面的第二台服务器,原则上有两种选择。

天真的方法是调用ssh第一台服务器(从 exec 通道),指示正确的服务器。这需要使用 JSch 进行代理转发,并且不提供 JSch API 来访问第二个服务器,只有 ssh 命令行。

更好的方法是使用与第一台服务器的连接来建立 TCP 隧道,并使用此隧道连接到第二台服务器。JSch Wiki 包含一个ProxySSH 类(连同一些示例代码),它允许将 JSch 会话用作第二个 JSch 会话的隧道。(免责声明:本课程主要由我编写,并得到了 JSch 作者的一些支持。)

当您连接到第二台服务器时,使用一个shell通道或一系列exec通道来执行您的命令。(有关概述,请参阅 JSch Wiki 中的Shell、Exec 或子系统通道,有关详细信息,请参阅Javadocs。)


对于您的未知主机密钥问题:

安全版本是在之前收集所有主机密钥(以安全方式)并将它们放入 known_hosts 文件中。(如果您只是信任提供给您的密钥,那么您很容易受到中间人攻击。如果这些在您的网络中无关紧要,因为它是物理安全的,对您有好处。)

方便的版本是将配置选项 StrictHostKeyChecking设置为no- 这会将未知的主机密钥添加到主机密钥文件中:

JSch.setConfig("StrictHostKeyChecking", "no");

(您也可以在会话中单独设置它,如果您只想为代理会话而不是隧道会话设置它。或者为隧道会话覆盖它,yes或者ask - 中间人危险可能更大。)

一种中间方法是启用实际询问用户(然后应该将指纹与某个列表进行比较) - 为此,实现UserInfo接口并将对象提供给会话。(JSch Wiki 包含一个使用 Swing JOptionPanes 的示例实现,如果您的客户端程序在具有 GUI 的系统上运行,您可以简单地使用它。)

为了保存已接受的主机密钥,您必须使用JSch.setKnownHosts带有文件名参数的方法,而不是带有 InputStream 参数的方法 - 否则每次重新启动客户端时都必须重复接受。

于 2011-07-21T00:51:01.510 回答
1

使用SSH 隧道,也就是本地端口转发,通过 A 打开到 B 的 SSH/SFTP 连接。

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 for shell/exec/sftp

您可能需要处理UnknownHostKey异常

于 2018-05-02T07:58:33.193 回答
0

这可以帮助任何人。工作正常:

 public static void sesionA(){
     try {
        Session sessionA = jSch.getSession(username, hostA);  
        Properties config = new Properties(); 
        config.put("StrictHostKeyChecking", "no");
        sessionA.setConfig(config);
        sessionA.setPassword(passwordA);
        sessionA.connect();


        if(sessionA.isConnected()) {
            System.out.println("Connected host A!");
            forwardedPort = 2222;
            sessionA.setPortForwardingL(forwardedPort, hostB, 22);      
        }

    } catch (JSchException e) {
        e.printStackTrace();
    }
 }

 public static void sesionB(){


        try {
            Session sessionB = jSch.getSession(username, "localhost", forwardedPort);

            Properties config = new Properties(); 
            config.put("StrictHostKeyChecking", "no");
            sessionB.setConfig(config);
            sessionB.setPassword(passwordB);
            sessionB.connect();

          if(sessionB.isConnected()) {
             System.out.println("Connected host B!");
          }
     }
 }
于 2018-07-26T00:05:55.280 回答