我需要能够从Java程序ssh到远程服务器,从那里SSH到另一台服务器。我的客户端上有两台服务器的凭据。
命令将作为常规字符串(无用户输入)从应用程序内自动传递。我需要能够在第二台服务器上运行这些自定义命令,并能够根据输出和一些简单的逻辑确定在运行时期间要发出的命令。
我可以使用JSch来做到这一点,如果是的话,我应该从哪里开始研究? (例子,信息)
=============================================== ==============
增加:
直到现在,我通过修改known_hosts文件并在那里手动添加主机来解决这个问题。 我可以通过设置一个选项告诉JSch在询问这个YES-NO问题时自动按YES来绕过这个小问题吗?线程中的异常" main" com.jcraft.jsch.JSchException: UnknownHostKey:host.net。 RSA密钥指纹是' blahblahblah'
答案 0 :(得分:10)
要连接防火墙后面的第二台服务器,原则上有两种选择。
天真的就是在第一台服务器上调用ssh
(来自exec频道),指示正确的服务器。这需要使用JSch进行代理转发,并且也不提供JSch API来访问第二个服务器,只提供ssh命令行。
更好的方法是使用与第一台服务器的连接来构建TCP隧道,并使用此隧道连接到第二台服务器。 JSch Wiki包含ProxySSH class(以及一些示例代码),允许使用JSch会话作为第二个JSch会话的隧道。 (免责声明:本课程主要由我撰写,得到了JSch作者的一些支持。)
当您连接到第二台服务器时,请使用shell
频道或一系列exec
频道来执行您的命令。 (有关概述,请参阅JSch Wiki中的Shell, Exec or Subsystem Channel,有关详细信息,请参阅Javadocs。)
对于 unknown-host-key 问题:
安全版本将在之前收集所有主机密钥(以安全的方式)并将它们放入known_hosts文件中。 (如果您只是信任提供给您的密钥,则您很容易受到中间人攻击。如果您的网络无关紧要,因为它是物理安全的,对您有利。)
方便版本将configuration option StrictHostKeyChecking
设置为no
- 这会将未知主机密钥添加到主机密钥文件中:
JSch.setConfig("StrictHostKeyChecking", "no");
(您也可以在会话中单独设置它,如果您只想为代理会话设置它而不是为隧道会话设置它。或者为yes
或{{1}的隧道会话覆盖它 - 那里的MITM危险可能更大。)
中间路径将启用实际询问用户(然后应将指纹与某些列表进行比较) - 为此,实现UserInfo
接口并将对象提供给会话。 (JSch Wiki包含一个example implementation using Swing JOptionPanes,如果您的客户端程序在带有GUI的系统上运行,您可以使用它。)
要保存已接受的主机密钥,必须使用带有文件名参数的JSch.setKnownHosts
方法,而不是带有InputStream参数的方法 - 否则每次重新启动时都必须重复接受客户端。
答案 1 :(得分: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
答案 2 :(得分: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!");
}
}
}