将文件上传到只能通过另一台 SSH/SFTP 服务器访问的 SFTP 服务器
Upload file to SFTP server accessible via another SSH/SFTP server only
有一个用例,我必须:
- 在应用程序服务器上的我的应用程序中生成一个文件。让我们称这台机器为 A*。 (这是我的 Java 代码运行的地方,用于生成文件)
- 从应用程序本身,我希望使用 SFTP 将此文件传输到列入白名单的 服务器 B,固定路径(比如
/home/fixed/file.xlsx
)
第 1 点和第 2 点是直截了当的。
现在有一个外部服务器C(我得到了它的凭据)
- 现在,应用程序 运行 在服务器 A 上。
- 文件现在位于 服务器 B 中 ==>
/home/fixed/file.xlsx
。
- 我必须将文件从 Server B 传输到 Server C,通过 SFTP。
如何实现这种多次跳转的 SFTP 传输?
(B不需要文件,成功发送到C)
编辑:Martin Prikryl 的回答帮助我实现了这一目标。
@Override
public void createOurChannel(Path lastModifiedBankFile) {
LOG.info("Initiating SFTP for white-listed Server B for file: {}",
lastModifiedBankFile);
String host = properties.getServerBSftpHost();
String port = properties.getServerBSftpPort();
String password = properties.getServerBSftpPassword();
String username = properties.getServerBSftpUsername();
Session session = null;
try {
JSch ssh = new JSch();
JSch.setConfig("StrictHostKeyChecking", "no");
session = ssh.getSession(username, host, Integer.parseInt(port));
session.setPassword(password);
session.connect();
this.sendFileToBank(lastModifiedBankFile, session, ssh);
} catch (JSchException e) {
LOG.error("Jsch Exception occurred while SFTP.", e);
} finally {
if (session != null && session.isConnected())
session.disconnect();
LOG.info("Successfully disconnected from SFTP. {}");
}
}
@Override
public void sendFileToBank(Path lastModifiedBankFile, Session session, JSch ssh) {
Session sessionBank = null;
Channel channelBank = null;
ChannelSftp channelSftp = null;
String host = properties.getBankSftpHost();
String port = properties.getBankSftpPort();
String password = properties.getBankSftpPassword();
String username = properties.getBankSftpUsername();
String bankSftpDir = properties.getBankSftpEmiDir();
try {
int portForwarded = 2222;
session.setPortForwardingL(portForwarded, host, Integer.parseInt(port));
sessionBank = ssh.getSession(username, "localhost", portForwarded);
sessionBank.setPassword(password);
sessionBank.connect();
channelBank = sessionBank.openChannel("sftp");
channelBank.connect();
channelSftp = (ChannelSftp) channelBank;
channelSftp.put(lastModifiedBankFile.toAbsolutePath().toString(),
bankSftpDir + lastModifiedBankFile.getFileName().toString());
channelSftp.exit();
} catch (JSchException e) {
LOG.error("Jsch Exception occurred while SFTP.", e);
} catch (SftpException e) {
LOG.error("SFTP Exception occurred while SFTP.", e);
} finally {
if (channelBank != null && channelBank.isConnected())
channelBank.disconnect();
if (sessionBank != null && sessionBank.isConnected())
sessionBank.disconnect();
}
}
使用 SSH tunnel, aka local port forwarding,通过 B 打开与 C 的 SSH/SFTP 连接。然后您可以直接从本地计算机 (A) 将文件上传到 C,而无需先将其上传到 B :
Session sessionB = jsch.getSession("usernameB", "hostB", 22);
// ...
sessionB.connect();
int forwardedPort = 2222; // any port number which is not in use on the local machine
sessionB.setPortForwardingL(forwardedPort, "hostC", 22);
Session sessionC = jsch.getSession("usernameC", "localhost", forwardedPort);
// ...
sessionC.connect();
Channel channel = sessionC.openChannel("sftp");
channel.connect();
ChannelSftp channelSftp = (ChannelSftp)channel;
channelSftp.put("C:\local\path\file.txt", "/remote/path/on/C/file.txt");
必须注意:不要使用StrictHostKeyChecking=no
。这样做会失去安全感。参见
有一个用例,我必须:
- 在应用程序服务器上的我的应用程序中生成一个文件。让我们称这台机器为 A*。 (这是我的 Java 代码运行的地方,用于生成文件)
- 从应用程序本身,我希望使用 SFTP 将此文件传输到列入白名单的 服务器 B,固定路径(比如
/home/fixed/file.xlsx
)
第 1 点和第 2 点是直截了当的。
现在有一个外部服务器C(我得到了它的凭据)
- 现在,应用程序 运行 在服务器 A 上。
- 文件现在位于 服务器 B 中 ==>
/home/fixed/file.xlsx
。 - 我必须将文件从 Server B 传输到 Server C,通过 SFTP。
如何实现这种多次跳转的 SFTP 传输?
(B不需要文件,成功发送到C)
编辑:Martin Prikryl 的回答帮助我实现了这一目标。
@Override
public void createOurChannel(Path lastModifiedBankFile) {
LOG.info("Initiating SFTP for white-listed Server B for file: {}",
lastModifiedBankFile);
String host = properties.getServerBSftpHost();
String port = properties.getServerBSftpPort();
String password = properties.getServerBSftpPassword();
String username = properties.getServerBSftpUsername();
Session session = null;
try {
JSch ssh = new JSch();
JSch.setConfig("StrictHostKeyChecking", "no");
session = ssh.getSession(username, host, Integer.parseInt(port));
session.setPassword(password);
session.connect();
this.sendFileToBank(lastModifiedBankFile, session, ssh);
} catch (JSchException e) {
LOG.error("Jsch Exception occurred while SFTP.", e);
} finally {
if (session != null && session.isConnected())
session.disconnect();
LOG.info("Successfully disconnected from SFTP. {}");
}
}
@Override
public void sendFileToBank(Path lastModifiedBankFile, Session session, JSch ssh) {
Session sessionBank = null;
Channel channelBank = null;
ChannelSftp channelSftp = null;
String host = properties.getBankSftpHost();
String port = properties.getBankSftpPort();
String password = properties.getBankSftpPassword();
String username = properties.getBankSftpUsername();
String bankSftpDir = properties.getBankSftpEmiDir();
try {
int portForwarded = 2222;
session.setPortForwardingL(portForwarded, host, Integer.parseInt(port));
sessionBank = ssh.getSession(username, "localhost", portForwarded);
sessionBank.setPassword(password);
sessionBank.connect();
channelBank = sessionBank.openChannel("sftp");
channelBank.connect();
channelSftp = (ChannelSftp) channelBank;
channelSftp.put(lastModifiedBankFile.toAbsolutePath().toString(),
bankSftpDir + lastModifiedBankFile.getFileName().toString());
channelSftp.exit();
} catch (JSchException e) {
LOG.error("Jsch Exception occurred while SFTP.", e);
} catch (SftpException e) {
LOG.error("SFTP Exception occurred while SFTP.", e);
} finally {
if (channelBank != null && channelBank.isConnected())
channelBank.disconnect();
if (sessionBank != null && sessionBank.isConnected())
sessionBank.disconnect();
}
}
使用 SSH tunnel, aka local port forwarding,通过 B 打开与 C 的 SSH/SFTP 连接。然后您可以直接从本地计算机 (A) 将文件上传到 C,而无需先将其上传到 B :
Session sessionB = jsch.getSession("usernameB", "hostB", 22);
// ...
sessionB.connect();
int forwardedPort = 2222; // any port number which is not in use on the local machine
sessionB.setPortForwardingL(forwardedPort, "hostC", 22);
Session sessionC = jsch.getSession("usernameC", "localhost", forwardedPort);
// ...
sessionC.connect();
Channel channel = sessionC.openChannel("sftp");
channel.connect();
ChannelSftp channelSftp = (ChannelSftp)channel;
channelSftp.put("C:\local\path\file.txt", "/remote/path/on/C/file.txt");
必须注意:不要使用StrictHostKeyChecking=no
。这样做会失去安全感。参见