Apache FtpServer で FTPS サーバーを組み込み実行
Apache FtpServer を使って Groovy で FTPS (FTP over SSL/TLS) サーバーの組み込み実行を試してみました。
ソースは http://github.com/fits/try_samples/tree/master/blog/20140916/
FTP サーバーの組み込み実行
まずは、普通の FTP サーバーを組み込み実行してみます。
簡単にするため、ユーザー定義をプロパティファイルから読み出すようにし、平文のパスワードを設定するようにします。
プロパティファイルは ftpserver.user.<ユーザー名>.<プロパティ>=<値>
のフォーマットで定義します。
一応、下記のような設定を定義すれば動作するようです。 (書き込み不可でよければ writepermission
の設定は不要)
user.properties (プロパティファイル)
ftpserver.user.u1.userpassword=p1
ftpserver.user.u1.homedirectory=./data
ftpserver.user.u1.writepermission=true
プロパティファイルからユーザー定義を読み込むには PropertiesUserManagerFactory
を使います。
PropertiesUserManagerFactory の passwordEncryptor
プロパティへ ClearTextPasswordEncryptor
を設定する事で平文のパスワードが使えます。
ftp_server.groovy (FTP サーバー組み込み実行スクリプト)
@Grab('org.apache.ftpserver:ftpserver-core:1.0.6') @Grab('org.slf4j:slf4j-api:1.7.7') @Grab('org.slf4j:slf4j-simple:1.7.7') import org.apache.ftpserver.FtpServerFactory import org.apache.ftpserver.usermanager.ClearTextPasswordEncryptor import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory def factory = new FtpServerFactory() // user.properties プロパティファイルを使用 factory.userManager = new PropertiesUserManagerFactory( file: new File('user.properties'), passwordEncryptor: new ClearTextPasswordEncryptor() ).createUserManager() // サーバー起動 factory.createServer().start()
実行すると FTP サーバーが起動します。
実行例
> groovy ftp_server.groovy [main] INFO org.apache.ftpserver.impl.DefaultFtpServer - FTP server started
cURL を使って動作確認してみます。
FTP 接続
$ curl -u u1:p1 ftp://localhost/ dr-x------ 3 user group 0 Sep 15 20:18 a dr-x------ 3 user group 0 Sep 15 20:18 b
特に問題なく FTP サーバーへ接続できました。
FTPS サーバーの組み込み実行
次に、本題の FTPS (FTP over SSL/TLS) サーバーを組み込み実行してみます。
FTPS 実行にはキーストアが必要となりますので、JDK 付属の keytool
コマンドを使って作成しておきます。
keytool -genkey -keypass <パスワード> -storepass <パスワード> -keystore <ファイル名>
で最低限のキーストアファイルを作成できます。
「姓名」とか聞かれますが、テスト用に使うだけなら全て Unknown のままで構いません。
キーストアの作成例
> keytool -genkey -keypass sample -storepass -keystore sample.jks 姓名は何ですか。 [Unknown]: 組織単位名は何ですか。 [Unknown]: 組織名は何ですか。 [Unknown]: 都市名または地域名は何ですか。 [Unknown]: 都道府県名または州名は何ですか。 [Unknown]: この単位に該当する2文字の国コードは何ですか。 [Unknown]: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknownでよろしいで すか。 [いいえ]: はい
上記でカレントディレクトリへ sample.jks ファイルが作成されます。
FTPS を使えるようにするには SslConfiguration
(上記で作成した sample.jks を keystoreFile へ設定) を設定した Listener
を FtpServerFactory
へ addListener
します。
ftps_server.groovy (FTPS サーバー組み込み実行スクリプト)
・・・ import org.apache.ftpserver.listener.ListenerFactory import org.apache.ftpserver.ssl.SslConfigurationFactory ・・・ def factory = new FtpServerFactory() def ssl = new SslConfigurationFactory( keystoreFile: new File('sample.jks'), keystorePassword: 'sample' ) def listenerFactory = new ListenerFactory( sslConfiguration: ssl.createSslConfiguration() ) factory.addListener('default', listenerFactory.createListener()) factory.userManager = new PropertiesUserManagerFactory( ・・・ ).createUserManager() factory.createServer().start()
実行すると FTP・FTPS のどちらでも接続できるサーバーが起動します。
実行例
> groovy ftps_server.groovy [main] INFO org.apache.ftpserver.impl.DefaultFtpServer - FTP server started
まずは FTP で動作確認してみます。
FTP で接続
$ curl -u u1:p1 ftp://localhost/ dr-x------ 3 user group 0 Sep 15 20:18 a dr-x------ 3 user group 0 Sep 15 20:18 b
特に問題なく FTP で接続できました。
次に --ssl -k
オプションを追加指定して FTPS 接続してみます。 (正式な証明書を使っていれば -k
オプションは不要)
今回は -v
オプションも指定して詳細出力してみました。
FTPS で接続
$ curl --ssl -k -u u1:p1 -v ftp://localhost/ ・・・ > AUTH SSL ・・・ * SSLv3, TLS handshake, Client hello (1): * SSLv3, TLS handshake, Server hello (2): * SSLv3, TLS handshake, CERT (11): * SSLv3, TLS handshake, Server key exchange (12): * SSLv3, TLS handshake, Server finished (14): * SSLv3, TLS handshake, Client key exchange (16): * SSLv3, TLS change cipher, Client hello (1): * SSLv3, TLS handshake, Finished (20): * SSLv3, TLS change cipher, Client hello (1): * SSLv3, TLS handshake, Finished (20): * SSL connection using TLSv1.2 / DHE-DSS-AES128-GCM-SHA256 * Server certificate: * subject: C=Unknown; ST=Unknown; L=Unknown; O=Unknown; OU=Unknown; CN=Unknown * start date: 2014-09-15 11:46:38 GMT * expire date: 2014-12-14 11:46:38 GMT * issuer: C=Unknown; ST=Unknown; L=Unknown; O=Unknown; OU=Unknown; CN=Unknown * SSL certificate verify result: self signed certificate (18), continuing anyway. ・・・ dr-x------ 3 user group 0 Sep 15 20:18 a dr-x------ 3 user group 0 Sep 15 20:18 b ・・・
SSL 接続を行っている事が確認できました。