要连接到防火墙后面的第二台服务器,原则上有两种选择。
天真的方法是调用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 参数的方法 - 否则每次重新启动客户端时都必须重复接受。