Apache VFS SFTP连接在RHEL环境挂起,Java代码卡于resolveFile求助
Apache VFS SFTP连接挂起问题排查(RHEL连接AWS Transfer SFTP)
问题背景
需求为通过Apache VFS实现SFTP文件上传,仅在本地文件更新或服务器无对应文件时执行操作,采用SSH密钥认证。
- Windows环境连接本地SFTP服务器完全正常
- RHEL环境下,Shell执行
sftp -oIdentityFile=/path/to/test.ppk USER@xxx.xxx.xxx.xxx可成功连接,但Java代码调用manager.resolveFile时直接挂起,半小时后系统日志出现session退出记录 - 使用的SSH密钥为PuTTYGen导出的旧版OpenSSH格式(
-----BEGIN RSA PRIVATE KEY-----开头) - 已禁用SELinux,排除其干扰可能
涉事代码片段
DefaultFileSystemManager manager = new DefaultFileSystemManager(); manager.addProvider("sftp", new SftpFileProvider()); manager.init(); FileSystemOptions opts = createDefaultOptions(); BytesIdentityInfo identityInfo = new BytesIdentityInfo(server.sshKey.getBytes(), null); SftpFileSystemConfigBuilder.getInstance().setIdentityProvider(opts, identityInfo); remoteFileObject = manager.resolveFile(new URI("sftp",server.UserName,server.HostName,server.Port,remoteFilePath,null,null).toString(), createDefaultOptions(server.Key)); FileContent content = remoteFileObject.getContent(); return content.getLastModifiedTime();
可能的原因及排查步骤
1. 密钥加载的编码/格式问题
- RHEL与Windows默认字符编码不同,
server.sshKey.getBytes()使用平台默认编码可能导致密钥内容损坏。建议强制指定UTF-8编码:server.sshKey.getBytes(StandardCharsets.UTF_8),确保密钥内容与本地文件完全一致。 - 尝试改用文件路径加载密钥,避免字节数组转换可能带来的问题:
FileIdentityInfo identityInfo = new FileIdentityInfo(new File("/path/to/test.ppk"));
2. Apache VFS配置不一致或缺失
- 代码中两次调用
createDefaultOptions(),可能导致身份认证配置被覆盖。统一使用同一个FileSystemOptions对象,确保所有配置(认证、超时等)都生效:FileSystemOptions opts = createDefaultOptions(); // 在这里统一设置所有SFTP配置(身份认证、超时等) remoteFileObject = manager.resolveFile(uri.toString(), opts); - 缺少超时配置,导致连接无响应时无限挂起。添加超时参数限制:
SftpFileSystemConfigBuilder builder = SftpFileSystemConfigBuilder.getInstance(); builder.setTimeout(opts, 30000); // 30秒连接超时 builder.setConnectTimeout(opts, 30000);
3. AWS Transfer SFTP的SSH算法兼容性问题
AWS Transfer SFTP对SSH算法有特定支持要求,Apache VFS默认算法可能不匹配,导致协商阶段卡住。手动指定兼容的算法:
SftpFileSystemConfigBuilder builder = SftpFileSystemConfigBuilder.getInstance(); builder.setPreferredAuthentications(opts, "publickey"); builder.setAllowedSshCipherSuites(opts, "aes256-ctr,aes192-ctr,aes128-ctr"); builder.setAllowedSshKeyExchangeAlgorithms(opts, "diffie-hellman-group-exchange-sha256");
同时确认AWS Transfer SFTP控制台是否允许RSA密钥类型的认证。
4. RHEL环境网络/防火墙限制
- 虽然Shell能连接,但Java进程可能受iptables规则限制,或AWS安全组未正确开放RHEL服务器的出站IP。用
tcpdump抓取Java进程的SFTP连接包,检查是否有SYN包无响应、协商包异常等情况。 - 排查DNS解析问题:尝试用AWS Transfer SFTP的IP地址替代HostName,测试是否能正常连接。
5. Apache VFS/JSch版本兼容性问题
旧版本的Apache VFS或其依赖的JSch库可能存在与新版SSH服务器兼容的bug。升级Apache VFS到最新稳定版,同时确保JSch版本匹配(建议使用0.1.55及以上版本)。
内容的提问来源于stack exchange,提问作者simonalexander2005
相关产品推荐
相关产品推荐

