首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java11+上的Apache embeded FTPS (Mina)问题

Java11+上的Apache embeded FTPS (Mina)问题
EN

Stack Overflow用户
提问于 2021-03-31 05:11:17
回答 2查看 271关注 0票数 3

我有一个非常简单的Java8项目(FTP服务器),它使用Apache FTPS (Mina)服务器库(v1.1.1)。它就像下面的代码一样简单:

代码语言:javascript
运行
复制
    ListenerFactory factory = new ListenerFactory();
    factory.setPort(2221);
    
    // SSL config
    SslConfigurationFactory ssl = new SslConfigurationFactory();
    ssl.setKeystoreFile(new File("keystore.jks"));
    ssl.setKeystorePassword("password");
    // set the SSL configuration for the listener
    factory.setSslConfiguration(ssl.createSslConfiguration());
    factory.setImplicitSsl(true);

    FtpServerFactory serverFactory = new FtpServerFactory();
    // replace the default listener
    serverFactory.addListener("default", factory.createListener());
    
    //Configure user manager and set admin user
    PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
    userManagerFactory.setFile(new File("users.properties"));
    UserManager userManager = userManagerFactory.createUserManager();
    if (!userManager.doesExist("admin")) {
        BaseUser user = new BaseUser();
        user.setName("admin");
        user.setPassword("password");
        user.setEnabled(true);
        user.setHomeDirectory(USER_HOME_DIR);
        user.setAuthorities(Collections.<Authority>singletonList(new WritePermission()));
        userManager.save(user);
    }
    serverFactory.setUserManager(userManager);

   // start the server
   FtpServer server = serverFactory.createServer(); 
   server.start();

所需的maven依赖项:

代码语言:javascript
运行
复制
    <dependency>
        <groupId>org.apache.ftpserver</groupId>
        <artifactId>ftpserver-core</artifactId>
        <version>1.1.1</version>
    </dependency>

要简单地创建自签名密钥库:

代码语言:javascript
运行
复制
keytool -genkey -keyalg RSA -alias self-signed -keystore keystore.jks -validity 360 -keysize 2048

我遵循官方指南编写了以下代码:https://mina.apache.org/ftpserver-project/embedding_ftpserver.html

如果我用Java8编译和运行这段代码,我的FTPS服务器工作得很好,我可以通过localhost:2221和用户名"admin“和密码" password”到达这个服务器。从我的FTP客户端(我使用Filezilla),我可以看到TLS连接已成功建立。

如果我使用Java编译并运行相同的代码(我尝试使用11和15),我在11+客户端看到以下消息,并且目录列表失败:

代码语言:javascript
运行
复制
Status:         Connecting to 127.0.0.1:2223...
Status:         Connection established, initializing TLS...
Status:         Verifying certificate...
Status:         TLS connection established, waiting for welcome message...
Status:         Logged in
Status:         Retrieving directory listing...
Command:    PWD
Response:   257 "/" is current directory.
Command:    TYPE I
Response:   200 Command TYPE okay.
Command:    PASV
Response:   227 Entering Passive Mode (127,0,0,1,225,229)
Command:    MLSD
Response:   150 File status okay; about to open data connection.
Error:          Received TLS alert from the server: User canceled (90)
Error:          Could not read from transfer socket: ECONNABORTED - Connection aborted
Response:   226 Closing data connection.
Error:          Failed to retrieve directory listing

下面是完整的应用程序日志(带有VM参数):

代码语言:javascript
运行
复制
2021-03-30 22:59:09.304  INFO 10557 --- [           main] com.example.ftp.demo.DemoApplication     : Starting DemoApplication using Java 11.0.7 on Kara's-MBP with PID 10557 (...)
2021-03-30 22:59:09.306  INFO 10557 --- [           main] com.example.ftp.demo.DemoApplication     : No active profile set, falling back to default profiles: default
2021-03-30 22:59:09.601  INFO 10557 --- [           main] com.example.ftp.demo.DemoApplication     : Started DemoApplication in 0.487 seconds (JVM running for 1.046)
javax.net.ssl|DEBUG|01|main|2021-03-30 22:59:09.886 CEST|SSLCipher.java:438|jdk.tls.keyLimits:  entry = AES/GCM/NoPadding KeyUpdate 2^37. AES/GCM/NOPADDING:KEYUPDATE = 137438953472
2021-03-30 22:59:09.966  INFO 10557 --- [           main] o.a.ftpserver.impl.DefaultFtpServer      : FTP server started
2021-03-30 22:59:24.393  INFO 10557 --- [ NioProcessor-3] o.a.f.listener.nio.FtpLoggingFilter      : CREATED
2021-03-30 22:59:24.395  INFO 10557 --- [pool-3-thread-1] o.a.f.listener.nio.FtpLoggingFilter      : OPENED
javax.net.ssl|DEBUG|1B|NioProcessor-3|2021-03-30 22:59:24.443 CEST|SSLCipher.java:1840|KeyLimit read side: algorithm = AES/GCM/NOPADDING:KEYUPDATE-countdown value = 137438953472
javax.net.ssl|DEBUG|1B|NioProcessor-3|2021-03-30 22:59:24.444 CEST|SSLCipher.java:1994|KeyLimit write side: algorithm = AES/GCM/NOPADDING:KEYUPDATE-countdown value = 137438953472
javax.net.ssl|DEBUG|1B|NioProcessor-3|2021-03-30 22:59:24.472 CEST|SSLCipher.java:1994|KeyLimit write side: algorithm = AES/GCM/NOPADDING:KEYUPDATE-countdown value = 137438953472
javax.net.ssl|DEBUG|1B|NioProcessor-3|2021-03-30 22:59:24.490 CEST|SSLCipher.java:1840|KeyLimit read side: algorithm = AES/GCM/NOPADDING:KEYUPDATE-countdown value = 137438953472
2021-03-30 22:59:24.493  INFO 10557 --- [pool-3-thread-1] o.a.f.listener.nio.FtpLoggingFilter      : SENT: 220 Service ready for new user.

2021-03-30 22:59:24.501  INFO 10557 --- [pool-3-thread-1] o.a.f.listener.nio.FtpLoggingFilter      : RECEIVED: USER admin
2021-03-30 22:59:24.503  INFO 10557 --- [pool-3-thread-1] o.a.f.listener.nio.FtpLoggingFilter      : SENT: 331 User name okay, need password for admin.

2021-03-30 22:59:24.503  INFO 10557 --- [pool-3-thread-1] o.a.f.listener.nio.FtpLoggingFilter      : RECEIVED: PASS *****
2021-03-30 22:59:24.505  INFO 10557 --- [pool-3-thread-1] org.apache.ftpserver.command.impl.PASS   : Login success - admin
2021-03-30 22:59:24.505  INFO 10557 --- [pool-3-thread-1] o.a.f.listener.nio.FtpLoggingFilter      : SENT: 230 User logged in, proceed.

2021-03-30 22:59:24.505  INFO 10557 --- [pool-3-thread-2] o.a.f.listener.nio.FtpLoggingFilter      : RECEIVED: OPTS UTF8 ON
2021-03-30 22:59:24.506  INFO 10557 --- [pool-3-thread-2] o.a.f.listener.nio.FtpLoggingFilter      : SENT: 200 Command OPTS okay.

2021-03-30 22:59:24.506  INFO 10557 --- [pool-3-thread-1] o.a.f.listener.nio.FtpLoggingFilter      : RECEIVED: PBSZ 0
2021-03-30 22:59:24.506  INFO 10557 --- [pool-3-thread-1] o.a.f.listener.nio.FtpLoggingFilter      : SENT: 200 Command PBSZ okay.

2021-03-30 22:59:24.507  INFO 10557 --- [pool-3-thread-2] o.a.f.listener.nio.FtpLoggingFilter      : RECEIVED: PROT P
2021-03-30 22:59:24.508  INFO 10557 --- [pool-3-thread-2] o.a.f.listener.nio.FtpLoggingFilter      : SENT: 200 Command PROT okay.

2021-03-30 22:59:24.508  INFO 10557 --- [pool-3-thread-1] o.a.f.listener.nio.FtpLoggingFilter      : RECEIVED: OPTS MLST size;modify;type;
2021-03-30 22:59:24.509  INFO 10557 --- [pool-3-thread-1] o.a.f.listener.nio.FtpLoggingFilter      : SENT: 200 Command OPTS okay.

2021-03-30 22:59:24.509  INFO 10557 --- [pool-3-thread-2] o.a.f.listener.nio.FtpLoggingFilter      : RECEIVED: CWD /
2021-03-30 22:59:24.511  INFO 10557 --- [pool-3-thread-2] o.a.f.listener.nio.FtpLoggingFilter      : SENT: 250 Directory changed to /

2021-03-30 22:59:24.511  INFO 10557 --- [pool-3-thread-2] o.a.f.listener.nio.FtpLoggingFilter      : RECEIVED: TYPE I
2021-03-30 22:59:24.512  INFO 10557 --- [pool-3-thread-2] o.a.f.listener.nio.FtpLoggingFilter      : SENT: 200 Command TYPE okay.

2021-03-30 22:59:24.512  INFO 10557 --- [pool-3-thread-1] o.a.f.listener.nio.FtpLoggingFilter      : RECEIVED: PASV
2021-03-30 22:59:24.513  INFO 10557 --- [pool-3-thread-1] o.a.f.listener.nio.FtpLoggingFilter      : SENT: 227 Entering Passive Mode (127,0,0,1,226,235)

2021-03-30 22:59:24.513  INFO 10557 --- [pool-3-thread-2] o.a.f.listener.nio.FtpLoggingFilter      : RECEIVED: MLSD
javax.net.ssl|DEBUG|1D|pool-3-thread-2|2021-03-30 22:59:24.526 CEST|SSLCipher.java:1840|KeyLimit read side: algorithm = AES/GCM/NOPADDING:KEYUPDATE-countdown value = 137438953472
javax.net.ssl|DEBUG|1D|pool-3-thread-2|2021-03-30 22:59:24.527 CEST|SSLCipher.java:1994|KeyLimit write side: algorithm = AES/GCM/NOPADDING:KEYUPDATE-countdown value = 137438953472
javax.net.ssl|DEBUG|1D|pool-3-thread-2|2021-03-30 22:59:24.528 CEST|SSLCipher.java:1994|KeyLimit write side: algorithm = AES/GCM/NOPADDING:KEYUPDATE-countdown value = 137438953472
javax.net.ssl|DEBUG|1D|pool-3-thread-2|2021-03-30 22:59:24.529 CEST|SSLCipher.java:1840|KeyLimit read side: algorithm = AES/GCM/NOPADDING:KEYUPDATE-countdown value = 137438953472
javax.net.ssl|ALL|1D|pool-3-thread-2|2021-03-30 22:59:24.533 CEST|SSLSocketImpl.java:994|Closing output stream
javax.net.ssl|DEBUG|1D|pool-3-thread-2|2021-03-30 22:59:24.533 CEST|SSLSocketImpl.java:466|duplex close of SSLSocket
javax.net.ssl|DEBUG|1D|pool-3-thread-2|2021-03-30 22:59:24.534 CEST|SSLSocketImpl.java:1372|close the SSL connection (passive)
2021-03-30 22:59:24.535  WARN 10557 --- [pool-3-thread-2] org.apache.ftpserver.impl.PassivePorts   : Releasing unreserved passive port: 58091
2021-03-30 22:59:24.535  INFO 10557 --- [pool-3-thread-2] o.a.f.listener.nio.FtpLoggingFilter      : SENT: 150 File status okay; about to open data connection.

2021-03-30 22:59:24.535  INFO 10557 --- [pool-3-thread-2] o.a.f.listener.nio.FtpLoggingFilter      : SENT: 226 Closing data connection.

此外,如果我从代码中去掉了SSL支持,我的FTP服务器甚至在使用Java 11+时也能很好地工作。

你们中有谁在Apache FTPS和Java 11+上遇到过类似的问题吗?如果是,您是如何找到解决方案的?

EN

回答 2

Stack Overflow用户

发布于 2021-06-26 06:02:32

只有在使用FileZilla时,我才能重现问题。例如,当我使用lftp时,我可以成功地连接到服务器(在信任自签名证书之后)。

FileZilla对TLSv1.3的实现似乎有问题。在Filezilla的bugtracker 1中有一个关于这个的关闭(被拒绝)的标签。

另外,我可以在使用jdk 8时重现这个问题。TLSv1.3是从8u261-b12 2开始在jdk 8中添加并启用的。

作为一种变通方法,您可以通过使用安全属性JVM3禁用TLSv1.3,这将强制jdk.tls.disabledAlgorithms选择另一种安全握手算法(希望是TLSv1.2)。(由于这是一个安全设置,如果您的公司中有安全团队,最好与您的安全团队讨论它)。

可以在jdk的配置文件java.security中设置或更新安全属性。它的路径取决于您使用的jdk和操作系统。

通常在$JAVA_HOME/jre/lib/security$JAVA_HOME/lib/security.下

如果找不到,可以通过使用-Djava.security.debug=all启动jvm来打印它的路径。您应该会在启动日志中看到打印的路径(可能有几个文件)。查找类似于以下行的内容:

代码语言:javascript
运行
复制
properties: reading security properties file: /usr/lib/jvm/java-11-openjdk-11.0.11.0.9-4.fc34.x86_64/conf/security/java.security
...
properties: reading system security properties file /etc/crypto-policies/back-ends/java.config

您还可以通过在ssl.createSslConfiguration()之前添加以下两行来以编程方式更新jdk.tls.disabledAlgorithms

代码语言:javascript
运行
复制
String disabledAlgorithms = Security.getProperty("jdk.tls.disabledAlgorithms") + ", TLSv1.3";
Security.setProperty("jdk.tls.disabledAlgorithms", disabledAlgorithms);

下面是添加了两行代码的完整程序:

代码语言:javascript
运行
复制
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.ssl.SslConfigurationFactory;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import org.apache.ftpserver.usermanager.impl.WritePermission;

import java.io.File;
import java.security.Security;
import java.util.Collections;

public class Main {
    public static void main(String[] args) throws FtpException {
        String disabledAlgorithms = Security.getProperty("jdk.tls.disabledAlgorithms") + ", TLSv1.3";
        Security.setProperty("jdk.tls.disabledAlgorithms", disabledAlgorithms);

        ListenerFactory factory = new ListenerFactory();
        factory.setPort(2221);

        // SSL config
        SslConfigurationFactory ssl = new SslConfigurationFactory();
        ssl.setKeystoreFile(new File("keystore.jks"));
        ssl.setKeystorePassword("password");
        // set the SSL configuration for the listener
        factory.setSslConfiguration(ssl.createSslConfiguration());
        factory.setImplicitSsl(true);

        FtpServerFactory serverFactory = new FtpServerFactory();
        // replace the default listener
        serverFactory.addListener("default", factory.createListener());

        //Configure user manager and set admin user
        PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
        userManagerFactory.setFile(new File("users.properties"));
        UserManager userManager = userManagerFactory.createUserManager();
        if (!userManager.doesExist("admin")) {
            BaseUser user = new BaseUser();
            user.setName("admin");
            user.setPassword("password");
            user.setEnabled(true);
            user.setHomeDirectory("/tmp/admin");
            user.setAuthorities(Collections.<Authority>singletonList(new WritePermission()));
            userManager.save(user);
        }
        serverFactory.setUserManager(userManager);

        // start the server
        FtpServer server = serverFactory.createServer();
        server.start();
    }
}

1:https://trac.filezilla-project.org/ticket/12099

2:https://www.oracle.com/java/technologies/javase/8u261-relnotes.html

3:https://docs.oracle.com/en/java/javase/11/security/java-secure-socket-extension-jsse-reference-guide.html#GUID-0A438179-32A7-4900-A81C-29E3073E1E90

票数 1
EN

Stack Overflow用户

发布于 2021-12-28 02:12:42

感谢来自@Mohamed的详细信息。

我最近才遇到这个问题,想和大家分享一下最近的测试结果。我可以用带有FileZilla pro 3.57.1的JDK 16.0.1_64重现这个问题;带有winscp 5.15.5的JDK 16.0.1_64工作正常;带有FileZilla pro 3.57.1的JDK 17.0.1_64工作正常;

这意味着使用JDK 17.0.1_64可以是一种解决方案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66878534

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档