■ ProFTPD FTPサーバの構築 (RedHat、CentOS) 2010/03/11 更新
細かい設定ができるというProFTPD、使ってみると確かに Linux 標準の vsftp よりも細かい要件に対応できますが、rpmパッケージが公式に配布されていないのが難点で、rpmbuild をしようとしてもSPECファイルの不備なんかで、一筋縄ではいかないことが多いです。 何度かパッケージ化を試みましたが、結局はソースからインストールする方法が一番簡単だと思います。 (ソースからの build 、srpm からの rebuild でも、エラーになったりモジュールが正しく組み込まれなかったりと、問題だらけでした。 テク不足で解決できませんでした。) ProFTPD の構築について解説します。
 構築するサーバーのポリシー
  1. rpmパッケージを作成することができなかったんで、ソースファイルからインストール。
  2. mod_ldap.c を組み込み ProFTPD から直接LDAPサーバに認証できるようにしておく。
  3. サービスはスタンドアロン型で常時起動。
  4. パッシブポート接続を可能とし、ポート番号は 49152~49200 を使用する。
  5. anonymous ログインはしない。
  6. adminsグループ以外は、ホームディレクトリに chroot する。
  7. ログインバナーにはバージョンを表示しない。
  8. 時間はローカルタイムを表示。 (デフォルトはGMT表示です。)
 構築手順
  1. 本家からソースファイルをダウンロードする。 http://www.proftpd.org/  2010/02/19 現在のStable版 Ver.1.3.2d
  2. インストールを行う。 インストールパスは /usr/local/proftpd-1.3.2c とし、後ほど /usr/local/proftpd からリンクする。
    $ tar -xvjf proftpd-1.3.2c.tar.bz2
       :
    $ cd proftpd-1.3.2c
    $
    $ ./configure --prefix=/usr/local/proftpd-1.3.2c --with-modules=mod_ldap
       :
       :  --prefix    : インストールするパス
       :  --with-modules : 組み込むモジュール
       :
    $ make
    # make install
       :
    #
     
  3. 組み込んだモジュールを確認する。
    # /usr/local/proftpd-1.3.2c/sbin/proftpd -l
    Compiled-in modules:
    mod_core.c
    mod_xfer.c
    mod_auth_unix.c
    mod_auth_file.c
    mod_auth.c
    mod_ls.c
    mod_log.c
    mod_site.c
    mod_delay.c
    mod_facts.c
    mod_ident.c
    mod_auth_pam.c
    mod_ldap.c ※1
    #
    ※1 --with-modules=mod_ldap で追加したモジュールが表示されること。
     
  4. 起動スクリプトのコピーと修正
    # cd /usr/local/src/proftpd-1.3.2c/contrib/dist/rpm/
    # cp proftpd.init.d /etc/init.d/proftpd
    # chmod 755
    # vi /etc/init.d/proftpd
    緑:デフォルト、オレンジ:変更箇所
     
    #!/bin/sh
    #
    # Startup script for ProFTPD
    #
    # chkconfig: 345 85 15 ※1
    # description: ProFTPD is an enhanced FTP server with \
    #       a focus toward simplicity, security, and ease of configuration. \
    #       It features a very Apache-like configuration syntax, \
    #       and a highly customizable server infrastructure, \
    #       including support for multiple 'virtual' FTP servers, \
    #       anonymous FTP, and permission-based directory visibility.
    # processname: proftpd
    # config: /etc/proftpd.conf ※2
    #
    # By: Osman Elliyasa <osman@Cable.EU.org>
    # $Id: proftpd.init.d,v 1.7 2002/12/07 21:50:27 jwm Exp $

    # Source function library.
    . /etc/rc.d/init.d/functions

    if [ -f /etc/sysconfig/proftpd ]; then
       . /etc/sysconfig/proftpd
    fi

    #PATH="$PATH:/usr/local/sbin"
    PATH="$PATH:/usr/local/proftpd/sbin" ※3

    # See how we were called.
    case "$1" in
      start)
        echo -n "Starting proftpd: "
        daemon proftpd $OPTIONS
        echo
        touch /var/lock/subsys/proftpd ※4
        ;;
      stop)
        echo -n "Shutting down proftpd: "
        killproc proftpd
        echo
        rm -f /var/lock/subsys/proftpd ※4
        ;;
      status)
        status proftpd
        ;;
      restart)
        $0 stop
        $0 start
        ;;
      reread)
        echo -n "Re-reading proftpd config: "
        killproc proftpd -HUP
        echo
        ;;
      suspend)
        hash ftpshut >/dev/null 2>&1
        if [ $? = 0 ]; then
          if [ $# -gt 1 ]; then
            shift
            echo -n "Suspending with '$*' "
            ftpshut $*
          else
            echo -n "Suspending NOW "
            ftpshut now "Maintanance in progress"
          fi
        else
          echo -n "No way to suspend "
        fi
        echo
        ;;
      resume)
        if [ -f /etc/shutmsg ]; then
          echo -n "Allowing sessions again "
          rm -f /etc/shutmsg
        else
          echo -n "Was not suspended "
        fi
        echo
        ;;
      *)
        echo -n "Usage: $0 {start|stop|restart|status|reread|resume"
        hash ftpshut
        if [ $? = 1 ]; then
          echo '}'
        else
          echo '|suspend}'
          echo 'suspend accepts additional arguments which are passed to ftpshut(8)'
        fi
        exit 1

    esac
    if [ $# -gt 1 ]; then
        shift
        $0 $*
    fi

    exit 0
    ※1 chkconfig -add でサービス登録する際に参照される情報。
    ※2 config ファイルへのパス。 実際はインストールディレクトリ配下の proftpd.conf が使われるので、
    そこからシンボリックリンクを /etc/proftpd.conf に張って運用することにします。 (この作業は後で実施)
    ※3 実行ファイルへのパスを指定する。 /usr/local/proftpd/sbin に変更する。
    ※4 動スクリプトの後半に case から始まる条件分岐が記述されている中に、幾つかあるロックファイルへのパスを確認。
     
  5. コンフィグファイルの準備とシンボリックリンクの作成
    # ln -s /usr/local/proftpd-1.3.2c /usr/local/proftpd ※1
    # mv /usr/local/proftpd-1.3.2c/etc/proftpd.conf /etc/ ※2
    # ln -s /usr/local/proftpd-1.3.2c/etc/proftpd.conf /etc/proftpd.conf ※2
    # mkdir /var/log/proftpd ※3
    ※1 /usr/local/proftpd からインストールディレクトリにリンクを張る。 バージョンアップの場合、このリンクを切り替える。
    ※2 インストールディレクトリ配下の etc ディレクトリにあるサンプルコンフィグファイルを移動し、シンボリックリンクを張る。
    ※3 ログファイルの出力先ディレクトリを作成。
     
  6. コンフィグファイルの編集
    # vi /etc/proftpd.conf
    # cat /etc/proftpd.conf | grep -v ^#
    緑:デフォルト、オレンジ:変更箇所
     
    ServerName              "ProFTPD Default Installation" ※1
    ServerType              standalone ※2
    DefaultServer           on ※3

    Port                    21 ※4

    # Specify the ftp-data port range to be used
    #PassivePorts           49152 65534
    PassivePorts            49152 49200
    ※5

    ## ProFTPD に組み込んだ mod_ldap.c を使い LDAP 認証を行う場合 ※6
    LDAPDoAuth              on "o=****,dc=com" "(&(uid=%v)(objectclass=posixAccount))" ※6-1
    LDAPServer              192.168.100.10 192.168.100.20 ※6-2
    LDAPDNInfo              "cn=********,o=****,dc=com" password ※6-3
    LDAPForceDefaultGID     on ※6-4
    LDAPDefaultGID          600 ※6-5

    ## PAM経由で 認証を行う場合 ※7
    AuthPAM                 on ※7-1
    AuthPAMConfig           ftp ※7-2
    PersistentPasswd        off ※7-3

    UseIPv6                 off ※8

    Umask                   022 ※9

    #MaxInstances           30
    MaxInstances            300 ※10

    #User                   nobody
    #Group                  nogroup
    User                    ftp ※11
    Group                   ftp ※11


    #DefaultRoot            ~
    DefaultRoot             ~ !admins ※12

    TimeoutIdle             600 ※13
    TimeoutNoTransfer       600 ※14
    MaxStoreFileSize        1Gb ※15
    MaxStoreFileSize        1Mb user anonymous ※16


    AllowRetrieveRestart on ※17
    AllowStoreRestart on ※18

    DeleteAbortedStores on ※19

    AllowOverwrite          on ※20

    #<Limit SITE_CHMOD> ※21
    # DenyAll
    #</Limit>

    # Set the message displayed on connect
    ServerIdent              on "FTP Server Ready" ※22

    # Toggle time display between GMT and local
    TimesGMT                 off ※23


    #<Anonymous ~ftp>
    <Anonymous /anonymous> ※24
     User                  ftp ※11
     Group                 ftp ※11
     UserAlias             anonymous anon_usr ※25

     MaxClients            10 ※26

     DisplayLogin          welcome.msg ※27
     DisplayChdir          .message ※28

     <Limit WRITE LIST NLST> ※29
       DenyAll
     </Limit>
    </Anonymous>
    ※1 サーバの名前を設定。 (動作に影響はない)
    ※2 スタンドアロンサービスとして実行する。
    ※3 バーチャルホスト運用時などで、複数のアドレスが接続を待ち受ける場合、どのアドレスにも該当しない接続要求を最終的に受付ける。 (デフォルト: on)
    ※4 FTPサービスをリッスンするポート番号を指定する。 (デフォルト: 21)
    ※5 パッシブモードで使用するポートの範囲を制限する。
    ※6 ProFTPDに組み込んだ mod_ldap.c を使い、デーモンから直接LDAPサーバを参照させる場合に設定する。
    6-1
    on
    o=****,dc=com
    (&(uid=%v)(objectclass=posixAccount))
     : mod_ldap.c による認証を有効にする。(デフォルト:off)
     : 検索するディレクトリを指定。
     : 検索フィルタ (この値はデフォルト値です)
    6-2 LDAPサーバをスペース区切りで指定する。
    LDAPマスターサーバのサービスが停止した場合、すぐにスレーブサーバで認証を行うが、IPレベルでの通信断 (OS停止や断線状態) が発生した場合はスレーブサーバへの認証に時間がかかる。
    PAM を使う場合の "bind_timelimit" みたいな定義がよくわかりません。。。
    6-3 LDAPサーバに接続するためのユーザとパスワードを指定。 BindDN と DNPassword です。
    6-4 LDAP認証後に使用する gid 番号を指定した値に強制する。
    6-5 強制使用する gid 番号を指定。
    ※7 PAMを使用してユーザ認証を行う場合に設定する。
    7-1 PAMを有効にする。 (デフォルト: on)
    7-2 PAMで使用する設定ファイルを指定する。 この設定だと /etc/pam.d/ftp となる。
    ftpファイルでは内容が不十分なため、同じディレクトリにある login をコピーして使用する。
    7-3 LDAPユーザでログインを行う場合は "off" にしないとダメなようです。
    ※8 IPV6は使用しない。
    ※9 ディレクトリの作成やアップロード時に適応される Umask
    ※10 子プロセスを起動する最大値。 デフォルトの 30 だと、ffftp がハングアップするという情報が飛び交っている。
    試すのも面倒なので、10倍の 300 辺りにしておこう。
    ※11 デーモンを実行するユーザとグループを指定。
    ※12 chroot するディレクトリとユーザを指定。
    この設定の例では admins グループ以外のユーザは ~ (ホームディレクトリ)に chroot する。
    ※13 ログイン後の無通信タイムアウト (デフォルト 300秒)
    ※14 サーバ/クライアント間における無通信タイムアウト (デフォルト 300秒)
    ※15 1回の put で転送可能な最大サイズを指定。 全てのユーザで 1GB の制限をかける。 (単位 Mb Kb B)
    ※16 こちらの、"user anonymous" は anonymous ログイン時は1MBしか put することができない。
    ※15、16 は排他利用です。
    ※17 ダウンロード時のレジューム機能の設定。 (デフォルト: on)
    ※18 アップロード時のレジューム機能の設定。 (デフォルト: off)
    ※19 アップロードを中断した場合、転送途中のファイルを削除する。 回線切断の場合は削除されない。
    ※20 既存のファイルへの上書きを許可する。 (デフォルト: on)
    ※21 制限するFTPコマンド。 デフォルトではパーミッション変更操作が制限されているので、コメントアウトする。
    ※22 機能には直接関係ないが、デフォルトだとバナーにバージョンが表示されるので、それを防ぐ。
    ※23 時刻の表示方法。 デフォルトはGMT表記なのでローカル表記に変える。
    ※24 anonymous 接続用の設定。 anonymous接続時のディレクトリを指定する。
    ※25 anonymous ログインした際にマッピングされるユーザ。 anon_usr にマッピングされる。
    ※26 anonymous でログインできる最大数。
    ※27 ログイン時にユーザに表示するメッセージ。
    ※28 ディレクトリを移動した際に表示するメッセージ。
    ※29 このディレクティブの意味は ※21 と同じだが、<Anonymous> ディレクティブ内に記述されているので、Anonymous
    ログイン時に適応される。 この例だと、書き込みと一覧の表示が制限される。

    コンフィグは他にも、たくさんありますがキリがないので、この辺りで次へ進みます。
     
  7. サービスへの登録と起動 ( もし Solaris10 の構築事例で、このページを見ている方は、こちらへどうぞ
    # chkconfig --add proftpd

    # chkconfig --list proftpd
    proftpd 0:off 1:off 2:off 3:on 4:on 5:on 6:off

    # service proftpd start
    Starting proftpd: [ OK ]
     
  8. ログロテートの設定
    # cd /usr/local/src/proftpd-1.3.2c/contrib/dist/rpm/
    # cp proftpd.logrotate /etc/logrotate.d/proftpd ※1
    # vi /etc/logrotate.d/proftpd
    緑:デフォルト、オレンジ:変更箇所
     
    /var/log/xferlog /var/log/proftpd/*.log ※2 {
     missingok
     notifempty
     postrotate
      #/usr/sbin/kill -HUP `cat /var/run/proftpd.pid 2>/dev/null || true
      /usr/sbin/kill -HUP `cat /usr/local/proftpd/var/proftpd.pid 2>/dev/null || true ※3
     endscript
    }

    # logrotate -f /etc/logrotate.conf ※4
    ※1 展開したソースファイルにあるので、これを流用する。 無ければ新規作成です。
    ※2 ローテーションするログファイルをスペース区切りで記述する。 ワイルドカードもOKです。
    ( "*" だけにするとログロテートするたびに all.log.1 ⇒ all.log.1.1 ⇒ all.log.1.1.1 となってしまいます。)
    ※3 proftpd.pid の場所を探して、そのパスを書く。 デフォルトのままだと、kill -HUP しないので注意。
    ※4 ログロテートをすぐに実行して動作確認。 全てのログがローテーションされます。
    ProFTPDのログだけローテーションしたい場合は、/etc/logrotate.conf と同じように、"create" と "rotate 4" を
    追記してから logrotate -f /etc/logrotate.d/proftpd 実行する。
     
まぁ、こんな感じかな??