将文件上载到仅可通过其他SSH / SFTP服务器访问的SFTP服务器

时间:2018-04-24 14:48:04

标签: java ssh spring-integration sftp spring-integration-sftp

有一个用例,我必须:

  1. 在应用程序服务器上的应用程序中生成文件。让我们称这台机器为 A * 。 (这是我的Java代码运行的地方,用于生成文件)
  2. 从应用程序本身,我希望使用SFTP将此文件以固定路径(例如/home/fixed/file.xlsx)传输到列入白名单的服务器 B
  3. 第1点和第2点是直截了当的。

    现在有一个外部服务器 C (我提供的凭据)

    1. 现在,应用程序正在服务器A上运行。
    2. 文件现在位于服务器B at ==> /home/fixed/file.xlsx
    3. 我必须通过SFTP将文件从服务器 B 传输到服务器 C
    4. 如何实现这种多跳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();
          }
        }
      

1 个答案:

答案 0 :(得分:2)

使用SSH tunnel,又称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");