我想通過使用jcraft版本0.1.52的ssh跳轉主機代理連接到SFTP位置。但得到「連接關閉外國主機」在我的代碼異常。我花了好足夠的時間在看文檔,但無法弄清楚的問題是什麼無法使用jcraft JSch連接到SFTP
2016-11-18 14:53:14,091 44977 [main] ERROR c.w.v.r.ftp.JschSftpConnect -
- com.jcraft.jsch.JSchException: connection is closed by foreign host
at com.jcraft.jsch.Session.connect(Session.java:269)
at com.jcraft.jsch.Session.connect(Session.java:183)
at com.x.y.ftp.JschSftpConnect.connect(JschSftpConnect.java:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
,因爲我能夠連接通過unix命令到SFTP服務器沒有與私鑰沒有問題。
sftp -o UserKnownHostsFile=/dev/null
-o StrictHostKeyChecking=no
-i /path/to/host/private-key-file
-o 'ProxyCommand=ssh
-o UserKnownHostsFile=/dev/null
-o StrictHostKeyChecking=no
-i /path/to/jumphost/private-key-file
-l jumphostuser jump.host.com nc sftp.host.com 22'
- 下面是我運行
代碼代碼:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Properties;
import org.apache.commons.lang3.exception.ExceptionUtils;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Proxy;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SocketFactory;
public class JschSftpConnect {
public static void main(String args[]) {
String sftpHostKeyFilePath = "/path/to/host/private-key-file";
String sftpHost="sftp.host.com";
String sftpUser="user";
String proxyHostName="jump.host.com";
String proxyKeyPath ="/path/to/jumphost/private-key-file";
String proxyUserName="jumphostuser";
log.debug("Executing JSCH code.....");
try {
JSch jsch = new JSch();
Path path = FileSystems.getDefault().getPath(sftpHostKeyFilePath);
byte[] filearray = Files.readAllBytes(path);
jsch.addIdentity("ID", filearray, null, null);
Session session = jsch.getSession(sftpUser, sftpHost, 22);
Properties props = new Properties();
props.put("StrictHostKeyChecking", "no");
session.setConfig(props);
String command = "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i "
+ localKeyFileDirectoryName + proxyKey + " -l " + proxyUserName + " " + proxyHostName
+ " nc %h %p";
session.setProxy(new JumpHostProxyCommand(command));
log.debug("Connecting session .......................");
session.connect();
log.debug("Session openend .......................");
Channel ch = session.openChannel("sftp");
ch.connect();
log.debug("SFTP channel connected .......................");
ChannelSftp channelSftp = (ChannelSftp) ch;
channelSftp.cd("/");
log.debug("Working directory is/.......................");
byte[] buffer = new byte[1024];
BufferedInputStream bis = new BufferedInputStream(channelSftp.get("/some_file_.psv"));
File newFile = new File("some_file_.psv");
OutputStream os = new FileOutputStream(newFile);
BufferedOutputStream bos = new BufferedOutputStream(os);
int readCount;
// System.out.println("Getting: " + theLine);
while ((readCount = bis.read(buffer)) > 0) {
// System.out.println("Writing: ");
bos.write(buffer, 0, readCount);
}
log.debug("File should have been written/.......................");
while (session != null) {
System.out.println("Killing the session");
session.disconnect();
bis.close();
bos.close();
System.exit(0);
}
} catch (Exception e) {
log.error(ExceptionUtils.getStackTrace(e));
}
}
}
class JumpHostProxyCommand implements Proxy {
String command;
Process p = null;
InputStream in = null;
OutputStream out = null;
public JumpHostProxyCommand(String command) {
this.command = command;
}
public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws Exception {
String cmd = command.replace("%h", host);
cmd = cmd.replace("%p", new Integer(port).toString());
p = Runtime.getRuntime().exec(cmd);
log.debug("Process returned by proxy command {} , {}", command, p);
in = p.getInputStream();
log.debug("Input stream returned by proxy {}", in);
out = p.getOutputStream();
log.debug("Output stream returned by proxy {}", out);
}
public Socket getSocket() {
return null;
}
public InputStream getInputStream() {
return in;
}
public OutputStream getOutputStream() {
return out;
}
public void close() {
try {
if (p != null) {
p.getErrorStream().close();
p.getOutputStream().close();
p.getInputStream().close();
p.destroy();
p = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
真的很感激,如果有人可以幫助。謝謝!
通知connect()方法,而不是'調用Runtime.getRuntime()EXEC(命令);'它應該是'調用Runtime.getRuntime()EXEC(CMD);'太 –
塞吉本納2,那是我現在編輯的帖子中的一個錯字。雖然很漂亮! – Techji