连接OpenShift集群FTP服务器时遇SSLException问题求助
问题描述
尝试连接OpenShift集群中运行的FTP服务器上传文件时,遭遇SSL关闭状态异常。代码基于Apache Mina FTPServer嵌入指南编写,求可行解决方案。
错误信息
javax.net.ssl.SSLException: Improper close state: Status = OK HandshakeStatus = NEED_WRAP bytesConsumed = 0 bytesProduced = 7 sequenceNumber = 0 at org.apache.mina.filter.ssl.SslHandler.closeOutbound(SslHandler.java:496) at org.apache.mina.filter.ssl.SslFilter.initiateClosure(SslFilter.java:773) at org.apache.mina.filter.ssl.SslFilter.filterClose(SslFilter.java:704) at org.apache.mina.core.filterchain.DefaultIoFilterChain.callPreviousFilterClose(DefaultIoFilterChain.java:776) at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1600(DefaultIoFilterChain.java:49) at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.filterClose(DefaultIoFilterChain.java:1155) at org.apache.mina.core.filterchain.IoFilterEvent.fire(IoFilterEvent.java:88) at org.apache.mina.filter.logging.MdcInjectionFilter.filter(MdcInjectionFilter.java:162) at org.apache.mina.filter.util.CommonEventFilter.filterClose(CommonEventFilter.java:60) at org.apache.mina.core.filterchain.DefaultIoFilterChain.callPreviousFilterClose(DefaultIoFilterChain.java:776) ...(省略重复栈帧) at java.base/java.lang.Thread.run(Thread.java:829)
Spring Boot 代码
@Configuration public class FtpServerConfig { @Bean public FtpServerFactory ftpServerFactory() throws FtpException { FtpServerFactory serverFactory = new FtpServerFactory(); ListenerFactory factory = new ListenerFactory(); // 设置服务器地址 factory.setServerAddress("localhost"); // 设置端口 factory.setPort(50001); // SSL 配置 SslConfigurationFactory ssl = new SslConfigurationFactory(); ssl.setKeystoreFile(new File("/tmp/tls/keystore.jks")); ssl.setKeystorePassword("passward"); // 为监听器设置SSL配置 factory.setSslConfiguration(ssl.createSslConfiguration()); factory.setImplicitSsl(true); // 数据连接配置 DataConnectionConfigurationFactory dataConnectionConfigFactory = new DataConnectionConfigurationFactory(); // 禁用主动模式,使用被动连接 dataConnectionConfigFactory.setActiveEnabled(false); // 设置被动端口范围 dataConnectionConfigFactory.setPassivePorts("50000-60100"); factory.setDataConnectionConfiguration(dataConnectionConfigFactory.createDataConnectionConfiguration()); // 添加监听器 serverFactory.addListener("default", factory.createListener()); // 设置用户管理器 serverFactory.setUserManager(getUserManager()); return serverFactory; } private UserManager getUserManager() throws FtpException { PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory(); UserManager userManager = userManagerFactory.createUserManager(); BaseUser user = new BaseUser(); user.setName("user"); user.setPassword("123"); FileUtil.createNewDirectory(ftpServerDir); user.setHomeDirectory("/tmp/my_ftp_server"); user.setEnabled(true); List<Authority> authorities = new ArrayList<>(); authorities.add(new WritePermission()); authorities.add(new ConcurrentLoginPermission(0, 0)); authorities.add(new TransferRatePermission(0, 0)); user.setAuthorities(authorities); userManager.save(user); return userManager; } } @SpringBootApplication public class FtpServerApplication implements CommandLineRunner { @Autowired private FtpServerFactory ftpServerFactory; public static void main(String[] args) { SpringApplication.run(FtpServerApplication.class, args); } @Override public void run(String... args) throws Exception { FtpServer ftpServer = ftpServerFactory.createServer(); ftpServer.start(); } }
解决方案
针对该SSL异常,结合OpenShift环境特性,可从以下方向排查修复:
1. 修正SSL握手匹配逻辑
异常源于SSL握手未完成时触发连接关闭,大概率是客户端与服务器的SSL模式不匹配:
- 调整隐式SSL设置:如果客户端使用显式SSL(需发送
AUTH TLS命令触发加密),将factory.setImplicitSsl(true)改为false,让连接先以明文建立,再通过命令切换到SSL。 - 验证密钥库有效性:确保容器内
/tmp/tls/keystore.jks路径正确、权限可读,密码与配置一致。可在容器内执行keytool -list -keystore /tmp/tls/keystore.jks验证密钥库状态。
2. 适配OpenShift网络配置
OpenShift Pod网络有严格的端口暴露和路由规则,需调整FTP服务器的网络相关配置:
- 暴露被动端口范围:在Deployment的
ports字段中添加50000-60100端口范围,或通过Service的nodePort/clusterIP配置确保端口可访问;若需外部访问,需配置Route并映射对应端口。 - 修改服务器绑定地址:
localhost仅允许容器内部访问,改为绑定0.0.0.0让服务器监听所有网卡;同时配置被动连接的外部地址,确保客户端能获取到可访问的IP/域名:factory.setServerAddress("0.0.0.0"); dataConnectionConfigFactory.setPassiveExternalAddress("your-openshift-route-hostname");
3. 自定义连接关闭逻辑
重写Mina的IoHandler,避免在SSL握手未完成时强制关闭连接:
public class CustomFtpHandler extends IoHandlerAdapter { @Override public void inputClosed(IoSession session) throws Exception { SslHandler sslHandler = session.getAttribute(SslHandler.class); if (sslHandler != null && !sslHandler.isHandshakeComplete()) { session.closeOnFlush(); return; } super.inputClosed(session); } }
在FtpServerFactory中设置自定义Handler:
serverFactory.setFtpHandler(new CustomFtpHandler());
4. 检查依赖版本兼容性
老旧版本的Apache Mina FTPServer可能存在SSL处理bug,尝试升级到最新稳定版,确保与Spring Boot版本兼容。
内容的提问来源于stack exchange,提问作者Chetan
相关产品推荐
相关产品推荐

