如何使用JSch SSH连接到另一台SSH服务器后面的服务器?

问题描述 投票:5回答:3

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

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

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

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

添加:

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

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

java ssh jsch
3个回答
10
投票

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

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

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

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


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

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

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

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

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

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

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


1
投票

使用SSH tunnel,又名local port forwarding,通过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

你可能需要deal with UnknownHostKey exception


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!");
          }
     }
 }
© www.soinside.com 2019 - 2024. All rights reserved.