CentOS 5.8 で vsftpd 3.0.2 を使用する
SERVER
vsftpd を 3.0.2 にアップデートする
CentOS 5.8 では vsftpd 2.0.x が、CentOS 6.2 では vsftpd 2.2.x が採用されています。
あるとき、CentOS 5.8 の vsftpd へ Microsoft Expression Web 4 から FTPS 接続できなくなりました。
このように "Fatal error 'UnknownCa' has been reported by the remote connection end." と表示されるので、SSL 証明書の有効期限が切れたりだとか、OpenSSL 周りの問題なのかと思ったのですけど、FTPS 用の SSL 証明書を更新してみても改善される様子がありません。
もともと Microsoft Expression Web は Web 3 の頃に HTTPS 接続ができなかったり、FTP 周りで満足にアップロードできない不備があったので Web 4 でもまだ何か相性的な問題が残っているのかとも思ったのですけど、もう一つの心当たりとしては、数日前に CentOS 標準機能の yum を使って vsftpd を含むシステムのアップデートをしていたことでした。
それより前の 1 か月以内には、Microsoft Expression Web 4 からも問題なく FTPS でのアップロードができていました。
様子を伺ってみると、FFFTP ではアップロードできるので、新しい vsftpd と Microsoft Expression Web 4 の相性かと思いながら過ごしていると、ある時 ホームページビルダー 14 から FTPRanger 0.05 経由での FTPS アップロードでも、ファイルを 1 つずつしかアップロードできないことに気が付きました。
ホームページビルダーと FTPRanger の組も、数か月前にはアップロードできていました。
そうなると、vsftpd 側に原因を持つ相性問題の可能性が高そうです。
平成 24 年 11 月 04 日現在、vsftpd は 3.0.2 がリリースされていましたので、それで直ってくれるかどうか、アップデートしてみることにしました。
標準のリポジトリから vsftpd 3.0.2 をインストールできれば簡単だったのですけど、残念ながら CentOS-Testing にも rpmforge にも vsftpd 3.0.2 はありませんでした。
vsftpd のサイト https://security.appspot.com/vsftpd.html からは tar.gz 形式のソースコードをダウンロードできるようになっているので、それを使って CentOS 5.8 にインストールしてみようと思います。
CentOS 5.8 は標準で yum による rpm パッケージ管理が行われているので、今回は tar.gz で入手した vsftpd 3.0.2 から RPM パッケージを作成して、インストールしようと思います。
vsftpd 3.0.2 の RPM パッケージに必要なファイルを準備する
今回は、従来の vsftpd 2.0.5 からのアップデートが目的なので、なるべく簡単に済ませられるように、RPM も既に vsftpd 2.0.5 がインストールされている前提で作成してみます。
tar.gz から RPM パッケージを作成するには、CentOS で RPM パッケージを作成できるようにする で記したように rpmbuild を使用します。
RPM をビルドするために、CentOS 5.8 の場合は "/usr/src/redhat/" ディレクトリに RPM を生成するためのファイル群を用意します。CentOS 6.0 の場合は "/root/rpmbuild/" ディレクトリになるようでした。
SPEC ファイルを用意する
まず、RPM を作成するにあたり、SPEC ファイルが必要になります。
ダウンロードした vsftpd 3.0.2 の tar.gz には SPEC ファイルは用意されていないので、自分でこれを作成しないといけません。
■ SPECS/vsftpd.spec
たとえば今回は vsftpd 2.0.4 の SRPM を参考に、このような感じにしてみました。
既存のファイルから必要なものを用意する
ただし vsftpd 3.0.2.tar.gz の中には、この SPEC で指定したファイルのすべては含まれていません。
足りないファイルは、インストール済みの vsftpd 2.0.5 からコピーしてきて利用することにします。
cp /etc/rc.d/init.d/vsftpd SOURCES/vsftpd-3.0.2-vsftpd.init
cp /etc/vsftpd/ftpusers SOURCES/vsftpd-3.0.2-vsftpd.ftpusers
cp /etc/vsftpd/user_list SOURCES/vsftpd-3.0.2-vsftpd.user_list
このようにして、インストール済みの vsftpd から、必要なファイルを SOURCES ディレクトリの中にコピーしました。
認証機構の pam 設定ファイルは、CentOS 6.2 の vsftpd 2.2 を参考にして、次のようにしてみました。
■ SOURCES/vsftpd-3.0.2-vsftpd.pam
これを SOURCES ディレクトリに "vsftpd-3.0.2-vsftpd.pam" という名前で保存します。
vsftpd 2.x との非互換部分を中和する
vsftpd 3.0.2 では、vsftpd 2.0.5 と比べて互換性のない部分があるので、それを中和するスクリプトを作成しました。
vsftpd 3.0.2 では、設定ファイルに background=YES としないとフォアグラウンドで動作するため、うっかりすると vsftpd 3.0.2 がハングアップしているのかと思ってしまいます。
vsftpd は CentOS 起動時からバックグラウンドで動作させておきたいため、従来の 2.0 通り vsftpd を実行後すぐにバックグラウンドに回ってくれるよう、今回はアップデート時にこのスクリプトを使って、既存の "/etc/vsftpd/vsftpd.conf" ファイルを書き換えるようにします。
■ SOURCES/vsftpd-3.0.2-vsftpd.vsftpd_conf_migrate.sh
これを SOURCES ディレクトリに "vsftpd-3.0.2-vsftpd.vsftpd_conf_migrate.sh" という名前で保存しておきます。
ソースコードの修正パッチを用意する (libcap)
CentOS 5.8 (x86_64) 環境で vsftpd 3.0.2 を利用する場合、そのままのソースコードだと、RPM コンパイル時に libcap のリンクで次のエラーが表示されてしまいます。
/lib/libcap.so.1: could not read symbols: File in wrong format
collect2: ld returned 1 exit status
make: *** [vsftpd] Error 1
error: Bad exit status from /var/tmp/rpm-tmp.93726 (%build)
これを回避するために、vsftpd-3.0.2 のソースファイル "vsf_findlib.sh" の libcap 検索まわりのコードを修正する必要があります。
# Look for libcap (capabilities)
#if locate_library /lib/libcap.so.1; then
#echo "/lib/libcap.so.1";
#elif locate_library /lib/libcap.so.2; then
#echo "/lib/libcap.so.2";
#else
locate_library /usr/lib/libcap.so && echo "-lcap";
locate_library /lib/libcap.so && echo "-lcap";
locate_library /lib64/libcap.so && echo "-lcap";
#fi
具体的にはこのように、"Look for libcap (capabilities)" の else ブロックを無条件で実行するように修正します。
このように修正して再アーカイブしてもいいでしょうけど、それは少し手間だったので、今回はパッチを作って RPM 作成時にそれを自動適用してもらいます。
■ SOURCES/vsftpd-3.0.2-vsf_findlibs.sh.patch
これを SOURCES ディレクトリに "vsftpd-3.0.2-vsf_findlibs.sh.patch" という名前で保存します。
ソースコードの修正パッチを用意する (FTPS)
また、今回は vsftpd 3.0.2 で FTPS を利用しようと思うので、ソースコード "builddefs.h" も併せて修正します。
具体的には、"#undef VSF_BUILD_SSL" となっている行を "#define VSF_BUILD_SSL" に置き換えます。これでビルドすれば、vsftpd 3.0.2 で SSL が利用できるようになります。
ちなみに、これを #undef のままビルドしてしまうと、vsftpd の起動中に次のエラーが発生する場合があります。
500 OOPS: SSL: ssl_enable is set but SSL support not compiled in
ついでに、従来の vsftpd 2.0.5 でも有効だった VSF_BUILD_TCPWRAPPERS も有効にして、それらを適用するパッチは次の通りになりました。
■ SOURCES/vsftpd-3.0.2-builddefs.h.patch
これを SOURCES ディレクトリに "vsftpd-3.0.2-builddefs.h.patch" という名前で保存します。
vsftpd 3.0.2 の RPM パッケージを作成する
これで、必要なファイルの準備が整いました。
最初に示した SPEC ファイルの中で、これらのファイルを使用するように指定してあるので、後は rpmbuild を使って RPM パッケージを作成します。
rpmbuild -ba --define="dist .el5" SPECS/vsftpd.spec
このように、作成した SPEC ファイル (vsftpd.spec) を指定して rpmbuild を実行すると、SPEC ファイルに指定されているソースコードやパッチなどを使って RPM を感性させてくれます。
エラーがなければ、これで "RPMS/x86_64/" ディレクトリの中に "vsftpd-3.0.2-7_es.el5.x86_64.rpm" という名前の RPM ファイルが出来上がります。
ちなみに "--define" オプションを指定しているのは、SPEC ファイル内の "%dist" という記述を別の文字に置き換えるためです。
今回の SPEC ファイルでは、RPM パッケージのファイル名としても使用される "Release" 情報のところで "%dist" を使用しています。ここに ".el5" を指定することで、CentOS 5 用の RPM だということが目で見て判りやすくなります。
vsftpd 3.0.2 のインストールと最終調整
vsftpd 3.0.2 の RPM が作成できたら、次のようにして既存の vsftpd 2.0.5 をアップデートします。
rpm -Uvh vsftpd-3.0.2-7_es.el5.x86_64.rpm
これで vsftpd を 3.0.2 にアップデートすることができました。
ただし、新しい vsftpd 3.0.2 は設定周りで vsftpd 2.0.5 と互換性がない部分が多いようで、設定ファイル ("/etc/vsftpd/vsftpd.conf") をもう少し調整する必要がありました。
chroot 環境での対応
vsftpd 2.0.5 を chroot で利用していた場合、設定ファイル内に次の行を追加する必要がありました。
allow_writeable_chroot=YES
これを指定しておかないと、chroot が有効に設定されているアカウントが軒並み、パスワード認証直後にログインできずにはじかれる様子です。
これをしないと、例えば FFFTP の場合、">PASS [xxxxxx]" のログに続けて "「ログインできません」" というログが表示されて終わってしまいます。
FTPRanger 経由でのアクセスの場合
また、ホームページビルダーから FTPS を利用したい場合に役立つ FTPRanger を利用している場合、そのままだと、次のようなエラーが発生してしまいました。
150 Here comes the directory listing.
522 SSL connection failed; session reuse required: see require_ssl_reuse option in vsftpd.conf man page
これを解消するためには、設定ファイルに次の行を追加します。
require_ssl_reuse=NO
エラーメッセージだけ見ると "require_ssl_reuse" オプションを YES にしたくなる気がするんですけど、ここは NO にしないといけません。
vsftpd 3.0.2 を起動する
これらの準備が整ったら、次のようにして vsftpd を再起動します。
service vsftpd restart
これで vsftpd 3.0.2 を利用できるようになりました。
もしこれで vsftpd 3.0.2 がハングアップしてしまう場合、実際にはハングアップしていなくて、単純にフォアグラウンド動作になっている可能性があります。
その場合は vsftpd.conf 内に "background=YES" という行を追加することで、従来の vsftpd 2.0.5 と同じように、バックグラウンドで動作させることができます。
そんなこんなで vsftpd を 2.0.5 から 3.0.2 にアップデートしてみると、Microsoft Expression Studio Web 4 で正常に FTPS 接続できるようになりました。
ホームページビルダー 14 + FTPRanger の組でも、正常に 2 つ以上のファイルをアップロードできるようになりました。
しかしこれだけ既定の設定でも動作が違うとなると、もしかすると vsftpd 2.0.5 にアップデートしておかしくなった時でも、設定をどこか調整すれば、正常に動作するようになったのかもしれないですね。
ともあれこれで vsftpd の動作不良からの復旧を、vsftpd 3.0.2 へのアップデートとともに無事に終えることができました。