環境:Spring Integration 4.1.6(内部ではApache Commons Net 3.3をFTPSアクセス用に使用しているようです)を使用して、64ビットWindows 7上でSun Java JDK 1.8.0_60を使用しています。同じTLSセッションを使用してデータ接続してFTPSサーバに接続するにはどうすればよいですか?
私は、私たちのクライアントのFTPSサーバから自動ダウンロードをアプリケーションと統合しようとしています。私は問題なく他のクライアントに問題なくSpring Integrationを使ってSFTPサーバーを成功裏に実行しましたが、これはクライアントがFTPSを使用する必要があり、接続することが非常に不思議でした。私の実際のアプリケーションでは、XML Beansを使ってSpring Integrationを構成していて、何がうまくいかないのか理解しようとしています。私は実際のホスト/ユーザー名/パスワードをここで匿名化していますが、次のテストコードを使用しています:
final DefaultFtpsSessionFactory sessionFactory = new DefaultFtpsSessionFactory();
sessionFactory.setHost("XXXXXXXXX");
sessionFactory.setPort(990);
sessionFactory.setUsername("XXXXXXX");
sessionFactory.setPassword("XXXXXXX");
sessionFactory.setClientMode(2);
sessionFactory.setFileType(2);
sessionFactory.setUseClientMode(true);
sessionFactory.setImplicit(true);
sessionFactory.setTrustManager(TrustManagerUtils.getAcceptAllTrustManager());
sessionFactory.setProt("P");
sessionFactory.setProtocol("TLSv1.2");
sessionFactory.setProtocols(new String[]{"TLSv1.2"});
sessionFactory.setSessionCreation(true);
sessionFactory.setCipherSuites(new String[]{"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"});
final FtpSession session = sessionFactory.getSession();
//try {
final FTPFile[] ftpFiles = session.list("/");
logger.debug("FtpFiles: {}", (Object[]) ftpFiles);
//} catch (Exception ignored) {}
session.close();
-Djavax.net.debug=all
でこのコードを実行すると、すべてのTLSデバッグ情報が表示されます。
FTPSサーバーへの主な「制御」接続はうまくいきますが、リスト(または私が試した他のデータ接続)のデータ接続を開こうとするととなり、java.io.EOFException: SSL peer shut down incorrectly
が発生します。
main, READ: TLSv1.2 Application Data, length = 129
Padded plaintext after DECRYPTION: len = 105
0000: 34 35 30 20 54 4C 53 20 73 65 73 73 69 6F 6E 20 450 TLS session
0010: 6F 66 20 64 61 74 61 20 63 6F 6E 6E 65 63 74 69 of data connecti
0020: 6F 6E 20 68 61 73 20 6E 6F 74 20 72 65 73 75 6D on has not resum
0030: 65 64 20 6F 72 20 74 68 65 20 73 65 73 73 69 6F ed or the sessio
0040: 6E 20 64 6F 65 73 20 6E 6F 74 20 6D 61 74 63 68 n does not match
0050: 20 74 68 65 20 63 6F 6E 74 72 6F 6C 20 63 6F 6E the control con
0060: 6E 65 63 74 69 6F 6E 0D 0A nection..
:私は嚥下例外がsession.list
コマンド周りのブロックをキャッチコメントを解除した場合、私は、サーバーがデータ接続SSLハンドシェイクを拒否した後、次のメッセージを送っていること(javax.net.debug出力が)見ることができます何が起きているように見えますか(これはFTPSを初めて扱ったのですが、これまで私が普通のFTPを扱っていましたが)、サーバーが制御とデータ接続の両方で認証と暗号化を行う方法は、 TLS接続を確立して制御接続と認証を確立するには、各データ接続でクライアントが同じTLSセッションに接続する必要があります。これは仕事になる方法として私には意味がありますが、Apache Commons Net FTPSの実装はそうしていないようです。新しいTLSセッションを確立しようとしているようで、サーバーはその試みを拒否しています。
this question about resuming SSL sessions in JSSEに基づいて、Javaはホスト/ポストの組み合わせごとに異なるセッションを想定または必要としているようです。私の仮説は、FTPSデータ接続が制御接続とは異なるポートにあるので、既存のセッションを見つけることができず、新しい接続を確立しようとしているため接続が失敗するということです。
私は三つの主要な可能性を参照してください。
- サーバが制御ポート上のように、データポート上の同じTLSセッションを必要にFTPS基準を次されていませんが。 FileZilla 3.13.1を使用して、サーバーに接続できます(コードで使用しようとしているのと同じホスト/ユーザー/パスワードを使用しています)。サーバーはログイン時に "FileZilla Server 0.9.53 beta"と認識します。これは、FileZilla独自の方法です.Javaに同じTLSセッションを使用するように納得させるには、何か奇妙なことがあります。
- Apache Commons Netクライアントは、実際にはFTPS標準に準拠せず、データ接続のセキュリティを確保できないサブセットのみを許可します。これは、Java内からFTPSに接続するための標準的な方法のように思われるので、奇妙に思えるでしょう。
- 私は何かを完全に見逃しており、これを誤診しています。
この種のFTPSサーバーに接続する方法については、私がお答えしたいと思います。ありがとうございました。
詳細については、このリンクを参照してください。https://stackoverflow.com/questions/46631315/when-using-java-apache-ftpclient-for-ftp-tls-getting-remote-host-closed -connect/48616779#48616779 –