FTPサーバ(ProFTPD)の構築(SuSE編)


諸般の事情からFTPサーバはどうしてもProFTPDを使用したかったのですが、RPM は提供されていませんでした。そのため、自分で作成しようとしましたが SuSE の環境ではすんなりとは行かず、またインターネット上にもまるで情報がありませんでした。いろいろ追いかけた結果、何とか RPM 作成からインストール、基本動作、TLS まではできましたが、バーチャルホストがまともに動きませんでした。IP アドレスのバインド処理で、 IP の二重使用がないかチェックしているところで問題があるようです。特定環境下では 1.2.9 でも発生するようでパッチを見つけましたが、1.2.10rc1 にはすでに組み込み済みということで、現時点ではお手上げです。但し、おやじは動的 IP サービスのNAT ルータ環境下で PASV モードを動かしているため、xinetd 経由で起動せざるを得ずこちらで対策しましたので、実効的には問題は発生していません。

本件については対策が判明し、VirutualHost ディレクティブを使用してバーチャルホストで動作させることができましたので、こちらを参考にしてください。 もちろん xinetd 経由で2つの conf ファイルを使用する方法でも当然問題はありません。

このデーモンは、設定で NAT ルータ越えで PASV モ−ドでの FTP サービスの提供ができます。PASV モードでの NAT ルータ越えのインターネット公開の設定や、FTP サーバの公開サーバ公開のための設定も参考にしてください。

ProFTPD1.2.10rc1から「NLST」のオプション指定が未サポートになり、FFFTPなどではデフォルトのままではファイル一覧が取得できないので注意が必要です。これはRFC959に基づく変更であり、クライアントの設定を変更して「LIST」コマンドでファイル一覧を取得するようにすれば大丈夫です。
なお、このままではドットファイルが見えなくなるので、見せる必要があるなら、「ListOptions」ディレクティブを 「ListOptions "-a"」のように、proftpd.conf に追記してください。

Timing attack対策 (mod_delayの組み込み) を追加しました。

■ProFTPDのダウンロードとRPMの作成

ここでは、SSL/TLS 対応で RPM を作成することにしますが、SSL/TLS を使用しない場合は設定をしなければ良いだけです。SSL/TLS 対応にする設定については、RedHat の時と何も違いがありませんのでこちらを参照ください。なお、RPM を作成するには、pam-devel と openssl-devel と heimdal-lib/devel が必要なので YaST で検索して入っていなければインストールしておいてください。

  1. まずは、作業ディレクトリ(いつもの/usr/local/src)に移動して、ProFTPD を本家のこちらからダウンロードして解凍する。(おやじがダウンロードしたのは、proftpd-1.2.10rc3.tar.bz2。)

    # cd /usr/local/src
    # wget ftp://ftp.proftpd.org/distrib/source/proftpd-1.2.10rc3.tar.bz2
    # tar -jxf proftpd-1.2.10rc3.tar.bz2

  2. 解凍してできた spec ファイルとソースを SuSE の RPM 作成環境にコピーする。

    # cp ./proftpd-1.2.10rc3/proftpd.spec /usr/src/packages/SPECS
    # cp proftpd-1.2.10rc3.tar.bz2 /usr/src/packages/SOURCES

  3. SuSE の環境では、デフォルトの spec ファイルままでは RPM を作成できないので、何箇所か spec ファイルを変更する必要がある。

    • SuSE の起動スクリプトのパスは、一般的な /etc/rc.d/init.d 配下ではなく、/etc/init.d になっている(/etc/rc.d が/etc/init.d にリンクされている)ので、RPM 作成時にフォルダがないと怒られる。 この関連が、spec ファイル内に 3個所あるので、/etc/rc.d/init.d を /etc/init.d に変更する。

    • SuSE は kerberos をサポートしておらず、替わりに heimdal をサポートしている。従って、そのままでは RPM を作成できないので、kerberos に替えて、下記3個所の緑字部分を修正する。

      BuildRoot:  %{_builddir}/%{name}-%{version}-root
      Requires:  pam >= 0.72, /sbin/chkconfig, %{?_with_mod_tls:openssl heimdal-lib}
      BuildPreReq: pam-devel %{?_with_mod_tls:openssl-devel heimdal-devel}

       (snip)

        CFLAGS="$RPM_OPT_FLAGS" ./configure \
          --prefix=%{prefix} \
          --sysconfdir=/etc \
          --localstatedir=/var/run \
          --mandir=%_mandir \
          %{?_with_mod_tls:--with-includes=/usr/include/heimdal} \
          %{?_with_mod_sql_mysql:--with-includes=/usr/include/mysql} \
          %{?_with_ipv6:--enable-ipv6} \
          --with-modules=${MODULES}


    • この spec ファイルでは inetd と xinetd の両方に対応しており、両方ともインストールされていないと RPM は作成できるが、inetd の RPM をインストールできない。 SuSE はデフォルトで inetd はインストールされないので、xinetd を要求するように、spec ファイルを編集した。下記の緑字部分を変更する。

      %package inetd
      Summary: ProFTPD -- Setup for inetd/xinetd operation.
      Group:  System Environment/Daemons
      Requires: proftpd, xinetd
      Obsoletes: proftpd-standalone


    • /etc/ftpusers に users グループも取り込まれてしまい一般ユーザがアクセスできなくなるのと、基本パッケージと inetd パッケージをインストールすると、standalone モードが起動し、xinetd 経由でも起動でき、且つ、config ファイルは inetd 用になっているというおかしな状態になるので、spec ファイルを少し編集し、inetd パッケージをインストールしたときには、standalone モードを停止し、起動スクリプトを無効にするように変更した。(青字は削除、赤字は追加、緑字は変更したものです。)
      注:ProFTPD 標準の起動スクリプトでは、SuSE の環境では standalone モードでは起動できない。おやじは、ftp を常時稼動させる必要もないのと、NAT ルータ配下でのPASV 対応/バーチャルホスト対応が必須なので、xinetd モードでしか動作できません。従って、特に見直していないため、どうしても standalone モードで起動したい場合は、自分で見直してください。
      なお、どうしても standalone モードで動作させたい方は、こちらに参考スクリプトを置いておきますので活用ください。


      # vi /usr/src/packages/SPECS/proftpd.spec

           (snip)

      %pre
        if [ ! -f /etc/ftpusers ]; then
          touch /etc/ftpusers
          IFS=":"
          while { read username nu nu gid nu; }; do
            if [ $gid -le 99 -a "$username" != "ftp" ]; then
                echo $username
            fi
          done </etc/passwd >/etc/ftpusers
        fi

           (snip)

      %post inetd
        # Standalone mode stop
        /etc/init.d/proftpd stop
        /sbin/chkconfig --del proftpd


           (snip)

      [Esc]、[:]、[w]、[q]で保存。


  4. バイナリRPMを作成する。下記操作で、/usr/src/packages/RPMS/i586配下にRPMが作成される。

    # cd /usr/src/packages/SPECS
    # rpmbuild -ba proftpd.spec --with mod_tls

  5. 上記で作成されたバイナリ RPM をインストールするが、inetd で使用するので下記のように2つのRPM(proftpd-1.2.10rc3-1.i586.rpm、proftpd-inetd-1.2.10rc3-1.i586.rpm)をインストールすること。

    # cd /usr/src/packages/RPMS/i586
    # rpm -ivh proftpd-1.2.10rc3-1.i586.rpm proftpd-inetd-1.2.10rc3-1.i586.rpm

■ProFTPDの設定

上記で作成した RPM は、SSL/TLS に対応していますので設定だけで動作させることができます。SSL/TLS 対応については RedHat のときと同様なのでこちらを参照ください。バーチャルホストについては、こちらを参考にしてください。ここでは、基本的な設定のみ示します。ProFTPDの設定は、/etc/proftpd.conf を編集します。FTP の用途は、WWW サーバへのコンテンツのアップロード(パーミッションの設定が楽)と家庭内でのデータのやり取りだけであり、anonymousFTP は公開しないというポリシーで設定してあります。設定は、例によってエディタで簡単に。修正した部分のみ記載しています。(青字は削除、赤字は追加、緑字は変更したものです。)

  1. サーバ名の変更(どうでもいい)

    ServerName "ProFTPD Default Installation"

           ↓追加、変更

    #ServerName "ProFTPD Default Installation"
    ServerName "ProFTPD"

  2. サーバタイプの変更( RPM の場合はデフォルトでinetdになっているので不要)

    ServerType standalone

           ↓追加、変更

    #ServerType standalone
    ServerType inetd

     デフォルトは、デーモン起動のstandaloneですが常時使用するものでもないので、メモリ利用効率を考え xinetd.d 経由の起動とし、inetdに変更。
     MaxInstances ディレクティブは、許可された同じ接続の最台数をコントロールするもので DoS attacks 等に有効。inetd モードでは無効なため、特にコメントアウトしていない。

  3. NAT ルータ越えで PASV モードでインターネット公開する場合の設定の追加

     最近は、いくつかのメーカや機種で本設定を行わなくてもルータで同等の対応を行うものが増えてきているので、まずは、本設定を行わずにPASVを動かしてみるとよい。対応済みルータで本設定を行うと逆にLISTで止まるようになるので注意が必要。

    # PASV モードでインターネット公開する場合の設定
    MasqueradeAddress    ルータのWAN側アドレス 又は ドメイン名
    PassivePorts        最小ポート番号 最大ポート番号

    ・MasqueradeAddress
     MasqueradeAddress では、ルータの WAN 側アドレス又はドメイン名が指定できるが、固定IPの場合はルータの WAN 側アドレスでも良いが、動的IPの場合は、必然的に DDNS でのドメイン名になる。一般的には関係ないが、おやじのようにインターネットと同じドメイン名で内向き DNS を建てていると、自宅 DNS では自分のドメイン(おやじの場合なら、ftp.aconus.com)は牽けないため接続できない。従って、これ専用に自宅DDNSにWAN側IPアドレスを牽けるようなaconusftp.aconus.comというホストを登録し、そのホスト名を登録した。以前、Zive.netを使用していた場合は、3つまでホスト名登録ができるので、FTP 専用のホスト名(ex. exampleftp.zive.net)を登録し、このドメイン名を MasqueradeAddress に記述することで、この問題を回避できる。
     なお、動的IPの場合、サーバタイプが standalone になっていると IP の変化が起きても DNS を牽き直さないので、必ず inetd で走らせる必要がある。

    ・PassivePorts
     PassivePorts では、PASV モードで使用するポート番号(1024以上)の最小と最大で範囲指定する。おやじは、家庭用なのでそれほど多くは必要ないのと使いまわしされるので、MaxInstances と同じ30ポートとし、他のデーモンで使ってない4000-4029とした。
     なお、このポートはインターネット側から接続が開始されるので、ルータのスタティックNATでサーバにNATすると同時に、フルタリングも開ける必要がある。

  4. PAM認証の設定の追加

    # PAM認証の設定
    AuthPAMConfig ftp


     ログイン時に、PAM のエラーログが毎回出ていた(接続はできるが)ので設定を追加した。

  5. ユーザ・グループの変更

    User nobody
    Group nogroup

           ↓追加、変更

    User nobody
    #Group nogroup
    Group nobody

     デフォルトでは、nogroup というグループになっていますが、SuSE には nogroup というグループはないため、追加してもいいがここでは、権限の低い既存の nobody に変更。

  6. アクセスディレクトリの制限

    DefaultRoot                     ~ !wheel

     ”~” 指定により、接続ユーザにユーザのhome以上を見せないようにするが、これでは不便なのでwheelグル−プのユーザ(おやじ)のみ自由にアクセスできるように設定。

     上記設定では、/houme/user以下がrootディレクトリとなり、Maildir等システム関係のディレクトリ・ファイルが見え、誤操作でおかしてしまう可能性もある。従って、以下のように設定変更し、一般ユーザはpublic_html以下しかアクセスできないようにした。

    DefaultRoot                     ~/public_html !wheel

     更に、グループの制御に関してはカンマで区切って複数のグループを記述でき、それらのアンド条件で適用される。従って、下記の例では、ftpユーザで且つwheelユーザではないユーザがpublic_html以下しかアクセスできないようになる。ただ、この設定はDefaultRootと~ftp,!wheelの間は[Space]にしないと有効にならなかった。他のディレクティブは、[Tab]で問題はないのだが?

    DefaultRoot                     ~/public_html ftp,!wheel

  7. アクセスユーザの制限(追加)

    <Limit LOGIN>
     Order allow, deny
      Allow from 127.0.0.1, 192.168.1.0/24
      Deny from all
    </Limit LOGIN>


     localhost とおやじ宅内(192.168.1.0/24)からのみ、アクセスを許容しそれ以外は拒否するように設定。

     
  8. 詳細ログの取得設定

    LogFormat allinfo "%t :  %u (%a [%h]) : [%s], %T, %m (%f)"
    LogFormat write "%t : %u : %F (%a)"
    LogFormat read "%t : %u : %F (%a)"
    LogFormat auth "%t : %u (%a [%h])"

    ExtendedLog /var/log/proftpd/all.log ALL allinfo
    ExtendedLog /var/log/proftpd/write.log WRITE write
    ExtendedLog /var/log/proftpd/read.log  READ read
    ExtendedLog /var/log/proftpd/auth.log AUTH auth


     下記で、ログファイルのディレクトリを作成しておく。

    # mkdir /var/log/proftpd

  9. ログイン時間の短縮化 (追加)

    UseReverseDNS off   (DNS逆引きを停止:時間短縮にはさほど効果なし)
    IdentLookups off     (Identの停止。効果絶大)

  10. anonymousFTPの停止

    anonymousFTPは、運用しないため、全項目をコメントアウト。

◆追加の設定

上記以外で、使用環境によっては設定しておいたほうが良いと思われるパラメータを参考までに上げておきます。
  1. 時刻表示の変更

    時刻表示はデフォルトでGMTになっており、日本を対象にするなら下記設定を追加することにより、local timeに変更される。

    TimesGMT off

  2. Resume機能のサポート

    大きなファイルのダウンロードやアップロード中に回線断等のトラブルにより転送が中断してしまった場合、クライアントがサポートしていれば、中断点から再開できるのが、Resume機能である。ダウンロードはデフォルトで機能が有効になっているが、アップロードは無効になっている。有効にしたければ、下記設定を追加する。但し、アップロードを許可すると言うことは、REST コマンドによって再開するので、クライアントのオペミス(同一名称のままアップロード)で、先に保存されたファイルが壊れたりすることがあるので、特にanonymousでは絶対に使用しないほうが良い。

    # Allow clients to resume downloads (default on)
    AllowRetrieveRestart on


    # Allow clients to resume uploads (default off)
    AllowStoreRestart on


  3. アップロード中断ファイルの自動削除

    大きなファイルをアップロードすることがない場合は意味がないが、アップロード中に回線断等ではなく、クライアント操作で転送を中断(ABORコマンドによる中断)した場合に、下記設定を行っておくと自動的に中途半端なファイルを削除してくれる。上記、AllowStoreRestartとは背反である。

    # Enable automatic deletion of partially uploaded files (default off)
    DeleteAbortedStores on

  4. 同一ホストからの同時接続数の制限

    ダウンロードツール等を使用すると、複数セッションを設定して高速でダウンロードできるが、特定ユーザに細い回線を占有されてしまう。これを制限するのが下記設定で、数字は同時接続数であり、デフォルトは無制限である。制限されたときは、下記メッセージが返送される。

    # The maximum number of clients allowed to connect per host.(default none: no limit)
    MaxClientsPerHost 1

    [デフォルトメッセージ]

     Results in: 530 Sorry, the maximum number clients (%m) from your host are already connected. (%mは制限値)

  5. 異なるホストからの同一ユーザでの同時接続数の制限

    違った場所からの同一ユーザでのログインを制限できる。制限するには下記設定を行うが、数字は同時接続数である。制限されたときは、下記メッセージが返送される。

    # The the maximum number of times different hosts. (default none: no limit)
    MaxHostsPerUser 1

    [デフォルトメッセージ]

     Results in: 530 Sorry, the maximum number of hosts (%m) for this user already connected. (%mは制限値)

  6. アップロードファイル容量の制限

    アップロードを許可している場合、オペミスで大容量のファイルをアップしてしまったり、anonymousでいたずらされたりすることを防止できる。最悪はHDDを使い切ってシステムロックすることも考えられるので、設定しておいたほうが良い。但し、この設定で制限できるのはファイルの大きさだけなので、quotaでHDDの使用量制限を併用することを勧める。なお、ダウンロードの制限もMaxRetrieveFileSizeで可能であるが、あまり意味はない。
    下記の上の例は全てを3MByteに制限する例であり、下の例はanonymousのみ50KByteに制限する例である。 単位は、"Gb" (Gigabytes), "Mb" (Megabytes), "Kb" (Kilobytes), "B" (bytes)である。

    # Restrict upload to only 3 megabytes
    MaxStoreFileSize 3 Mb

    # Restrict anonymous uploads to 50k, but allow unlimited upload size for everyone else
    MaxStoreFileSize 50 Kb user anonymous
    MaxStoreFileSize *


  7. タイマ関係の設定

    タイマ関係としては、以下が設定可能であるが、家庭内で使用するには基本的にデフォルト値で問題ないはずなので、特に追加記述は不要である。各自の動作環境を想定して変更すると良い。敢えて変更するなら、TimeoutStalledで、ストール(止まった)したままでいつまでも繋いでおく必要もないので、10分(600)程度で切断しても良いと思われる。トータル時間を制限するなら、TimeoutSession を指定すれば、転送の遅いユーザは切ることもできる。
    なお、ここで無制限としても、巨大なファイルを細い回線で時間をかけて転送していると、転送が切れてしまう(転送完了後に切れることが多いはず)ことがある。これは、クライアントの実装にもよるが、データ転送中は制御コネクションにデータが流れないためルータのNATテーブルが消えてしまうことから発生する。制御コネクションのKeepaliveとしてNOOPコマンドを投げているクライアントもある。

     
    # Sets the idle connection timeout (default: 600)
    TimeoutIdle 600

    # Sets the login timeout (default: 300)
    TimeoutLogin 300 

    #  Sets the connection without transfer timeout (default: 600)
    TimeoutNoTransfer 600

    # Sets a timeout for an entire session (default: none)
    TimeoutSession none

    # Sets the timeout on stalled downloads (default: 0 {no limit})
    TimeoutStalled 600

  8. 転送量の制御

    [ProFTPd 1.2.8RC1以降]

    従来、転送量の制御は、RateRead* と RateWrite* で行えるようになっていたが、1.2.8rc1 から本ディレクティブは廃止され TransferRate というディレクティブに変更、集約された。
    TransferRate ディレクティブのパラメータは以下のとおりであり、コンテキストはserver config, <VirtualHost>, <Global>, <Anonymous>, <Directory>, .ftpaccessなので、制御単位に合わせて適宜設定する。

    TransferRate [ cmds] [ kilobytes-per-sec[:free-bytes]] [ ["user"|"group"|"class" expression]]


    下記設定例では、ダウンロードにおいて wheel グループ以外は、5KByte/sに転送量を制限されるが、1Kbyte以下のファイルはこの限りではないとなる。

     TransferRate RETR 5.0:1024 group !wheel


    [ Class ディレクティブ]

    Class ディレクティブは、 server config (共通部)に下記のように記述する。

     Class [ "name" limit|regex|ip value]

    下記の例では、local と default の二つのクラスを作成している。この設定では、デフォルトは最大10コネクションしか張れないが、ホスト名が *.foo.com で且つアドレスが 172.16.1.* なら最大100コネクション張れることになる。

    Classes on
    Class local limit 100
    Class default limit 10
    Class local regex *.foo.com
    Class local ip 172.16.1.0/24

◆Timing attack対策(mod_delayモジュールの組み込み)

2004年10月現在でProFTPDにログイン中のコマンド実行タイミングを測定して、そのタイミングを元にアタックすると外部から有効なユーザアカウントを識別することができるという問題があり、その対策として「mod_delay」というモジュールが提供されています。次期バージョンでは対策されるようなので細かい説明は省略しますが、本モジュールを組みこんだrpm( proftpd-1.2.10-2.i586.rpm )をダウンロードにおいておきますので、インストールして下記内容をproftp.confに追加してください。proftpd-1.3.0rc1以降ではデフォルトで組み込まれました。
詳細については、ProFTPDのサイトを見てください。
  1. mod_delayモジュールの組み込み

    下記の設定をproftpd.confに追加(コンテキストは"server config")設定する。

    # DelayEngine directive enables
    <IfModule mod_delay.c>
      DelayEngine on
    </IfModule>
    # The DelayTable directive configures a path to a file that mod_delay
    # uses for storing its timing data.
    DelayTable          /var/proftpd/proftpd.delay


  2. 組み込み確認

    xinetdもしくはproftpdを再起動し、下記でmod_delay.cが存在し組み込みができているか確認してください。

    # /usr/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_auth_pam.c
    mod_ratio.c
    mod_readme.c
    mod_tls.c
    mod_delay.c
    mod_cap.c

  3. 動作確認

    実際にftp接続を行った際に、タイミングデータを書き込むファイル(/var/proftpd/proftpd.delay)が作成されているか確認してください。
    SuSEの場合は、/var/log/messagesに接続で使用したタイミングデータが出力され、毎回値が異なっているはずです。

■PAM 認証の設定

RPM からインストールすると、/etc/pam.d 配下に ftp というファイルが作成されますが、SuSE のモジュールと合わないためログインはできますがエラーがでます。vsFTPD がインストールされていれば、それを ftp として下記のようにコピーしてください。

# cp /etc/pam.d/vsftpd /etc/pam.d/ftp

vsFTPD がインストールされていない場合は、ftp を下記内容(vsFTPD の内容)に書き換えてください。

#%PAM-1.0

auth       required    pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed
auth       required    pam_unix2.so
auth       required    pam_shells.so
account  required    pam_unix2.so
password required    pam_unix2.so
session   required    pam_unix2.so


■起動設定の確認

一応、下記により起動設定に問題がないか確認してください。standalone モードの起動オフと xinetd 経由での起動設定の確認を行い、xinetd を再起動しておきます。

# chkconfig proftpd off
# chkconfig --list proftpd
proftpd                    0:off   1:off   2:off   3:off   4:off   5:off   6:off
xinetd based services:
         proftpd:           on
# /etc/init.d/xinetd restart
なお、どうしても standalone モードで動作させたい方は、こちらに参考スクリプトを置いておきますので活用ください。

■logrotateの設定

RPM からインストールすると、/etc/logrotate.d 配下に proftpd というファイルが作成されるので、上記でログをカストマイズした場合は下記のように赤字部分を追加してください。他のlog同様、1週間毎にlogrotateされます。

# vi /etc/logrotate.d/proftpd
/var/log/xferlog
/var/log/proftpd/*.log {
   missingok
   notifempty
   
sharedscripts
   postrotate
     /usr/bin/kill -HUP `cat /var/run/proftpd.pid 2>/dev/null` 2>/dev/null || true
   endscript
}

「Esc」、「:」、「w」、「q」で保存する。


SSL/TLS 対応にする設定については、RedHat の時と何も違いがありませんのでこちらを参照ください。


Top Pageへ