You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过中转SFTP服务器C将服务器A生成的文件上传至白名单服务器B?

SFTP Transfer via Intermediate Server C: Implementation Solutions

Alright, let's tackle this problem where you need to route a file from Java app server A to server B (via whitelisted SFTP path /home/fixed/file.xlsx) using an intermediate server C that you already have credentials for. Here are two practical, production-ready approaches:

Approach 1: Two-Stage Transfer (A → C → B)

This is the most straightforward method, especially if you don't want to deal with SSH tunneling. It involves transferring the file to a temporary location on C first, then moving it to B from there.

Step-by-Step Breakdown

  1. Upload from A to C's temporary directory
    Use a Java SFTP library like JSch or Apache Commons VFS to push the generated file to a secure temp path on C (e.g., /tmp/sftp_transfers/). Make sure the temp directory has restricted permissions (only your user can read/write) to avoid security risks.

    Example JSch code snippet for A → C:

    import com.jcraft.jsch.*;
    
    public class SftpUploadToC {
        public static void main(String[] args) {
            String hostC = "server-c-ip";
            String userC = "your-c-username";
            String passwordC = "your-c-password"; // Or use key-based auth for better security
            String localFilePath = "/path/to/generated/file.xlsx";
            String remoteTempPath = "/tmp/sftp_transfers/file.xlsx";
    
            JSch jsch = new JSch();
            Session session = null;
            ChannelSftp channel = null;
    
            try {
                session = jsch.getSession(userC, hostC, 22);
                session.setPassword(passwordC);
                session.setConfig("StrictHostKeyChecking", "no"); // Disable for testing; use known hosts in production
                session.connect();
    
                channel = (ChannelSftp) session.openChannel("sftp");
                channel.connect();
    
                channel.put(localFilePath, remoteTempPath);
                System.out.println("File uploaded to C's temp path successfully");
            } catch (JSchException | SftpException e) {
                e.printStackTrace();
                // Add error handling/alerts here (e.g., notify on failure)
            } finally {
                if (channel != null) channel.disconnect();
                if (session != null) session.disconnect();
            }
        }
    }
    
  2. Transfer from C to B
    Once the file is on C, you have a few options to move it to B:

    • Shell Script on C: Create a bash script that uses the sftp command to push the file to B's fixed path. You can trigger this script from A via SSH, or set up a cron job on C to watch the temp directory.
      Example script (transfer_to_b.sh):
      #!/bin/bash
      SFTP_USER_B="your-b-username"
      SFTP_PASS_B="your-b-password" # Replace with key-based auth in production
      SFTP_HOST_B="server-b-ip"
      REMOTE_TEMP_PATH="/tmp/sftp_transfers/file.xlsx"
      REMOTE_FIXED_PATH="/home/fixed/file.xlsx"
      
      # Use batch mode to avoid interactive prompts
      echo -e "put $REMOTE_TEMP_PATH $REMOTE_FIXED_PATH\nexit" | sftp -o StrictHostKeyChecking=no $SFTP_USER_B@$SFTP_HOST_B
      
      # Clean up temp file after successful transfer
      if [ $? -eq 0 ]; then
          rm $REMOTE_TEMP_PATH
          echo "File transferred to B and temp file cleaned up"
      else
          echo "Transfer to B failed"
          exit 1
      fi
      
    • Java Program on C: If C has a Java runtime, you can run a similar JSch-based program to handle the C→B transfer directly.
  3. Trigger the C→B Transfer
    From server A, execute the script on C via SSH using JSch's ChannelExec:

    // Add this to A's code right after uploading the file to C
    ChannelExec execChannel = (ChannelExec) session.openChannel("exec");
    execChannel.setCommand("bash /path/to/transfer_to_b.sh");
    execChannel.connect();
    
    // Read script output/errors to confirm success
    InputStream in = execChannel.getInputStream();
    byte[] buffer = new byte[1024];
    while (in.read(buffer) != -1) {
        System.out.print(new String(buffer));
    }
    execChannel.disconnect();
    

Approach 2: SSH Tunneling (A → C → B Directly)

This method avoids storing the file on C entirely by using C as an SSH jump host. You'll create a port forwarding tunnel from A to B via C, then upload the file directly to the forwarded port (which maps to B's SFTP service).

Step-by-Step Breakdown

  1. Establish SSH Tunnel from A to B via C
    In Java, use JSch to create a local port forward:
    import com.jcraft.jsch.*;
    
    public class SftpTunnelToB {
        public static void main(String[] args) {
            String hostC = "server-c-ip";
            String userC = "your-c-username";
            String passwordC = "your-c-password";
            String hostB = "server-b-ip";
            int localPort = 2222; // Local port on A to forward to B's SFTP port (22)
            int remotePortB = 22;
    
            JSch jsch = new JSch();
            Session sessionC = null;
    
            try {
                sessionC = jsch.getSession(userC, hostC, 22);
                sessionC.setPassword(passwordC);
                sessionC.setConfig("StrictHostKeyChecking", "no");
                sessionC.connect();
    
                // Set up port forwarding: localhost:2222 → B:22 via C
                sessionC.setPortForwardingL(localPort, hostB, remotePortB);
                System.out.println("SSH tunnel established: localhost:" + localPort + " → " + hostB + ":" + remotePortB);
    
                // Upload file to localhost:2222 (which routes to B's SFTP)
                uploadToSftp("localhost", localPort, "your-b-username", "your-b-password",
                            "/path/to/generated/file.xlsx", "/home/fixed/file.xlsx");
    
            } catch (JSchException e) {
                e.printStackTrace();
            } finally {
                if (sessionC != null) sessionC.disconnect();
            }
        }
    
        private static void uploadToSftp(String host, int port, String user, String pass, String localPath, String remotePath) throws JSchException, SftpException {
            JSch jsch = new JSch();
            Session session = jsch.getSession(user, host, port);
            session.setPassword(pass);
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect();
    
            ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
            channel.connect();
            channel.put(localPath, remotePath);
    
            channel.disconnect();
            session.disconnect();
        }
    }
    

Key Considerations for Both Approaches

  • Security: Always prefer SSH key-based authentication over passwords for all SFTP/SSH connections. Restrict file permissions on temp directories (e.g., chmod 700 for directories, chmod 600 for files) to prevent unauthorized access.
  • Error Handling: Implement retry logic for failed transfers, add detailed logging for each step, and set up alerts (e.g., email, team chat) for transfer failures.
  • Whitelisting: Ensure server C's IP is included in B's SFTP whitelist, otherwise the C→B transfer will be blocked.
  • Cleanup: For Approach 1, always clean up temp files on C after successful transfers to avoid unnecessary disk usage.

内容的提问来源于stack exchange,提问作者Black Diamond

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:33:32