FTPD(8)

名称
ftpd, ftpd.conf - インターネット File Transfer Protocol サーバ

書式
ftpd [-dls] [-a anondir] [-c confdir] [-C user]

解説
ftpd は、Internet File Transfer Protocol (インターネットファイル転送プロトコル) サーバです。サーバは、 TCP プロトコルを用いて、 “ftp” サービスに割り当てられたポートを listen() します (services(5) 参照)。

利用可能なオプションは以下の通りです:

-a  anonymous ログインで chroot(2) するディレクトリを定義します。 デフォルトは ftp ユーザのホームディレクトリです

-c  コンフィギュレーションファイルを探すディレクトリを “/etc” から directory に変更します。

-C  指定されたユーザが、 /etc/ftpusers の制限下でアクセスが許可されるかどうかをチェックし、コネクションを張らずに 終了します。 ftpd は、 アクセスが許可されていれば 0 を、許可されていなければ 1 を返します。 コンフィギュレーションのテストに有効です。

-d  syslog の LOG_FTP のファシリティを用いてデバッグ情報を出力します。

-l  ftp(1) セッションの成功や失敗を、syslog の LOG_FTP のファシリティを用いて ログに残します。このオプションが 2 回指定されると、 retrieve (get), store (put), append, delete, make directory, remove directory, rename 命令およびそれらの引数のファイル名も記録されます。

-s  Kerberos や S/Key などのような、セキュリティのしっかりした認証メカニズムを 使うよう要求します。

ファイル /etc/nologin は、ftp アクセスを拒否するのに使うことが出来ます。このファイルが存在する場合、 ftpd はそのファイルの内容を表示して終了します。 /etc/ftpwelcome ファイルが存在する場合、 ftpd は “ready” メッセージを表示する前にその内容を表示します。 もし /etc/motd ファイルが存在する場合、ログイン成功後にその内容を出力します。

この ftp サーバは、現在、以下の ftp リクエストをサポートしています。 リクエストの文字の大小は無視されます。
Request | Description
ABOR | abort previous command
ACCT | specify account (ignored)
ALLO | allocate storage (vacuously)
APPE | append to a file
CDUP | change to parent of current working directory
CWD | change working directory
DELE | delete a file
FEAT | list extra features that are not defined in RFC 959
HELP | give help information
LIST | give list files in a directory (“ls -lgA”)
MKD | make a directory
MDTM | show last modification time of file
MODE | specify data transfer mode
NLST | give name list of files in directory
NOOP | do nothing
OPTS | define persistent options for a given command
PASS | specify password
PASV | prepare for server-to-server transfer
PORT | specify data connection port
PWD | print the current working directory
QUIT | terminate session
REST | restart incomplete transfer
RETR | retrieve a file
RMD | remove a directory
RNFR | specify rename-from file name
RNTO | specify rename-to file name
SITE | non-standard commands (see next section)
SIZE | return size of file
STAT | return status of server
STOR | store a file
STOU | store a file with a unique name
STRU | specify data transfer structure
SYST | show operating system type of server system
TYPE | specify data transfer type
USER | specify user name
XCUP | change to parent of current working directory (deprecated)
XCWD | change working directory (deprecated)
XMKD | make a directory (deprecated)
XPWD | print the current working directory (deprecated)
XRMD | remove a directory (deprecated)

以下に示した、標準でないもしくは UNIX に特有のコマンドが、SITE リクエストでサポートされています。

Request | Description
CHMOD | change mode of a file, e.g. ``SITE CHMOD 755 filename''
HELP | give help information.
IDLE | set idle-timer, e.g. ``SITE IDLE 60''
UMASK | change umask, e.g. ``SITE UMASK 002''

RFC 959 で規定されている ftp リクエストのうち、ACCT, SMNT, REIN は 解釈はされますがインプリメントされていません。 MDTM および SIZE は RFC 959 では規定されていませんが、次に改訂される FTP RFC には登場するでしょう。

ftp サーバがアクティブなファイル転送を中断するのは、ABOR コマンドの前に、 Telnet "Interrupt Process" (IP) シグナルか Telnet "Synch" シグナルが Telnet ストリーム内にある場合だけです。 これは Internet RFC 959 に記述されています。 もし、データの転送中に STAT コマンドを受けとった場合は、その前に Telnet IP や Synch を受け取った場合にのみ、転送ステータスが返されます。

ftpd は、 csh(1) で使われているファイル名展開を解釈します。これにより、 ユーザはメタキャラクタ “*?[]{}~” を利用できます。

  ユーザ認証
ftpd は、5 つのルールに従ってユーザの認証を行います。

1.  ログイン名はパスワードデータベース /etc/pwd.db になければならず、空のパスワードであってはいけません。 この場合、あらゆるファイルの操作の前に、クライアント側からパスワードが 提供されていなければなりません。ユーザが S/Key のキーを持っている場合は、 USER コマンドに対する応答に S/Key チャレンジが含められます。 クライアントは、PASS コマンドに 通常のパスワードか S/Key のワンタイムパスワードのどちらをつけて応答 するかを選択できます。サーバはどちらのパスワードを受け取ったかを自動的に 判定し、それに応じて認証を試みます。S/Key の認証に関する詳細は skey(1) を参照してください。S/Key は Bellcore 社の商標です。

2.  ログイン名は、 /etc/ftpusers (下記参照) 内の情報で許可されていなければなりません。

3.  ユーザは getusershell(3) で帰ってくる標準のシェルを持っていなければなりません。 パスワードデータベース内のそのユーザの shell フィールドが空であれば、 シェルは /bin/sh であるとみなされます。

4.  ユーザ名がファイル /etc/ftpchroot (下記参照) にある時は、そのセッションのルートディレクトリは、 “anonymous” や “ftp” の場合と同様に (次の項目を参照してください)、 chroot(2) によってそのユーザのログインディレクトリに変更されます。 しかしながら、ユーザはまだパスワードを与えなければなりません。 この特色は、完全に anonymous (匿名) なアカウントと 完全な特権のあるアカウントの間で妥協するという利用を意図しています。 このアカウントは anonymous アカウントと同様に設定されていなければなりません。

5.  もしユーザ名が “anonymous” または “ftp” の場合は、匿名の ftp アカウントがパスワードファイル (ユーザ “ftp”) で提供されていなければなりません。 この場合は、ユーザはどのようなパスワードでも許可されます (慣習としては ユーザの email アドレスをパスワードとして用いるべきです)。 サーバは “ftp” ユーザのホームディレクトリへ chroot(2) します。 もしこれ以外の制限 (あるコマンドを利用できないようにしたり、特定の umask を 設定するなど) を必要とした場合には、適切なエントリを /etc/ftpd.conf に書く必要があります。

  /etc/ftpusers
ファイル /etc/ftpusers は、どのユーザが ftp を利用できるかを決定するためのものです。 もしこのファイルが存在しなければ、全てのユーザのアクセスを拒否します。 このファイルがある場合、その各行は、 “#” で始まるコメントか、/bin/sh と同じ文法の展開パターンのどちらかです。 後者には、その後ろに空白と “allow” “yes”, “deny”, “no” が続くこともあります。 ユーザ名に対して、マッチするものが見つかるまで、次々に各展開パターンとの 比較が行われます。マッチした展開パターンの後に “allow” または “yes” と書かれてあれば、そのユーザのアクセスは許可されます。 この単語が “deny” や “no” または何も書かれていない場合は、 そのユーザのアクセスは拒否されます。 最初にマッチしたエントリより後の比較は行われません。 どれにもマッチしない場合、そのユーザのアクセスは許可されます。 この文法は、古い文法に対して下位互換となっています。

あるユーザが guest としてログインしたいと要求してきたかどうかの判断は、 ftp サーバは、 “anonymous” がアクセスしてきたか “ftp” がアクセスしてきたかの両方をチェックすることで行います。 デフォルトで全てのユーザのアクセスを拒否している状態で ゲストログインを許可するためには、 /etc/ftpusers ファイルに “anonymous allow” と “ftp allow” の両方のエントリが必要です。

  /etc/ftpchroot
ファイル /etc/ftpchroot は、どのユーザがそのセッションのルートをそのユーザのホームディレクトリに 変えるかを決定するために使われます。 このファイルが存在しない場合、ルートの変更は行われません。 ファイルが存在する場合、各行は、 “#” で始まるコメントか、 /bin/sh と同じ文法を持つパターン文字列 (オプションとして、この後ろに 空白で区切って “yes” または “no” を書くことができます) です。 各パターン文字列は、一致するものが見つかるまで順番にユーザ名と比較されます。 マッチしたパターン文字列の後ろに “yes” があるか、または何もない場合、ルートが変更されます。 この単語が “no” か、もマッチしなかった場合、ルートは変更されません。 一番最初にマッチしたものより後に対しては、比較は行われません。 この文法は古いものとは下位互換となっています。

  /etc/ftpd.conf
ファイル /etc/ftpd.conf はさまざまなオプションのコンフィギュレーションに使われます。 “#” で始まる行はコメントで (無視されます)、 それ以外の空行でない行がコンフィギュレーション命令とみなされます。

各コンフィグレーション行は以下のいずれかの形式をとります:

checkportcmd class [off]
    PORT コマンドが正当かどうかをチェックします。 指定された IP アドレスがその ftp コマンドのコネクションのものと合わない場合や、 リモート側の TCP のポート番号が IPPORT_RESERVED より小さかった場合、 PORT コマンドは失敗します。 このコマンドを使うことを 強く 奨めます。特に ftp bounce attack のセキユリティ問題が起こる可能性のあるサイト には特に薦めます。 もし class が “none” であるか off が指定された場合には、この機能は無効になり、それ以外では有効になります。

conversion class
    suffix [type disable command] 自動的なファイルの変換を定義します。 もし、持ってこようとしているファイル名が suffix で終っている状態で、実際のファイルが (suffix なしで) 存在していれば、そのファイルの中身の代りに command の出力が返されます。

    suffix
        変換が行われるファイルの suffix です。

    type
        変換をしてもよいファイルタイプのリストです。 タイプには ‘f’ (ファイル) と ‘d’ (ディレクトリ) が指定可能です。

    disable
        ファイル名で、このファイルが存在すると変換が抑制されます。 ファイル名に ~. を指定すると、この無効化動作が抑制されます。

    command
        変換のために実行されるコマンドです。 最初の単語はコマンド名ですが、コマンドの実行には execv(3) が使われるため、コマンド名はフルパスで指定すべきです。 command 内の最初の ‘%s’ は、リクエストされたファイルに書きかわります (suffix なしで)。

    同一の suffix に対する conversion 命令が複数ある場合、 後に指定した方が前に指定した方を上書きします。 変換がマッチする順序は、ファイル中に現れる順番とは逆です (つまり LIFO です)。

display class [file]
    file が指定されていないか class が “none” の場合はこの機能は無効ですが、それ以外の場合は、 ユーザが新しいディレクトリに移動するたびに file が存在するかチェックされ、存在する場合にはその内容がユーザに対して 表示されます。

maxtimeout class time
    クライアントのリクエストに対するタイムアウトの最大時間を設定します。 デフォルトは 2 時間です。 この値は 30 秒より小さくは出来ません。また、 timeout の値よりも小さくできません。 class が “none” であるか time が指定されていない場合には無視されます。

modify class [off]
    class が “none” であるか、または off が指定されていると、コマンド CHMOD, DELE, MKD, RNFR, RMD, UMASK が無効になります。そうでない場合は有効になります。

notify class [fileglob]
    fileglob が指定されていないか class が “none” の場合はこの機能は無効になり、それ以外の場合には、 ユーザが新しいディレクトリに移動するたびに fileglob にマッチするファイルがあればそれを知らせます。

passive class [off]
    class に “none” または off が指定されていると、passive (PASV) コネクションが禁止されます。 これら以外では許可されます。

timeout class time
    タイムアウトの起こる時間の長さを設定します (デフォルトは 15 分です)。この値は 30 秒より小さくは出来ません。 また、 maxtimeout より大きくも出来ません。 class が “none” であるか、または time が指定されていない場合には無視されます。

umask class umaskval
    umask を umaskval に設定します。 class が “none” であるか、または umaskval が指定されていない場合には無視されます。

全ての設定行で、 class は以下のうちのいずれか 1 つです:
real
    通常のユーザ
chroot
    chroot(2) した ユーザ
guest
    “anonymous” および “ftp” ユーザ
all 全てのクラスにマッチします
none
    どのクラスにもマッチしません

デフォルト値は以下のようになっています:
    display       none
    maxtimeout    all    7200   # 2 hours
    modify        all
    modify        guest  off
    notify        none
    passive       all
    timeout       all    900    # 15 minutes
    umask         all    027
    umask         guest  0707

ファイルの後方にある命令は、その前の命令よりも優先されます。 これにより、まずデフォルトを定義する ‘wildcard’ エントリを作っておき、続いてクラス固有の設定をするエントリを作るということが できます。

STAT コマンドは、 /etc/ftpd.conf で定義されている現在のユーザ用のクラス設定を返します。

  制限つきの ftp 部分木の設定
システムのセキュリティが侵害されないようにするために、 “ftp” や “chroot” アカウント用の部分木は、以下のようなルールに従って細心の注意を払って 作成するようにしてください (以下のディレクトリ名内の “ftp” は ‘chroot’ ユーザ用の適切なアカウント名に読み換えてください):

~ftp
    ホームディレクトリを、所有者 “root” で誰も書き込めないものとして作成してください。

~ftp/bin
    このディレクトリは、所有者 “root” で誰も書き込めない (モード 555) ものとして作成してください。 ‘LIST’ コマンドをサポートするために、プログラム ls(1) がなければなりません。 このプログラムはモード 111 にすべきです。

~ftp/etc
    このディレクトリは、所有者 “root” で誰も書き込めない (モード 555) ものとして作成してください。 ls(1) コマンドで所有者の番号でなく名前を表示するためには、 ファイル pwd.db (passwd(5) を参照してください) と group (group(5) を参照してください) がなければなりません。 passwd(5) 内のパスワードフィールドは使われませんので、実パスワードを含めるべきでは ありません。 ファイル motd がもしあれば、ログインが成功した後でその中身が表示されます。 これらのファイルはモード 444 にすべきです。

~ftp/pub
    このディレクトリおよびその下のサブディレクトリは、 そこに置くファイルに対して責任を持つユーザとグループの所有にすべきで、 その人たちだけが書込み可能にすべきです (モードは 755 か 775)。 これの所有者をユーザ ftp やそのグループにしたり、彼らが書込み可能な 状態にすべきでは ありません 。

~ftp/incoming
    このディレクトリは、匿名のユーザがファイルをアップロードするための場所です。 所有者はユーザ “ftp” でかつ適切なグループに属すべきです。 このグループのメンバは、ファイルがアップロードされた後でそのファイルを アクセスする権限を持つユーザだけにします。 この人たちは、そのファイルをどのように扱うのが適切かを理解している人である べきです。 もしこのディレクトリにあるファイルの名前を anonymous ftp ユーザが 見ることができるようにしたい場合は、パーミッションは 770 にすべきです。 そうでない場合は 370 にすべきです。

    匿名のユーザがファイルをこのディレクトリにファイルをアップロードすることは できますが、umask の設定や上で示したコマンドの無効化のため、 そのファイルをダウンロードしたり、削除したり、上書きしたりすることは できません。

~ftp/tmp
    このディレクトリには、 conversion や ‘LIST’ コマンドで生成されたメッセージを保存しておくためのテンポラリファイルが 作られます。このディレクトリの所有者は “ftp” にすべきです。パーミッションは 300 にすべきです。

    conversion コマンドを有効にしない場合や、anonymous ユーザに ファイルのアップロード (前述の ~ftp/incoming 参照) をしてほしくない場合には、このディレクトリは作らないでください。 どのようにしても、conversion や ‘LIST’ コマンドからのエラーメッセージをユーザに返すことはできません。 (昔からこうです。)

関連ファイル
/etc/ftpchroot
    chroot される一般ユーザのリストです。
/etc/ftpd.conf
    ファイルの変換やその他の設定用のコンフィギュレーションファイルです。
/etc/ftpusers
    制限を受けるユーザのリストです。
/etc/ftpwelcome
    ログイン前に出る welcome メッセージです。
/etc/motd
    ログイン後の welcome メッセージです。
/etc/nologin
    このファイルが存在すると、内容を表示して、アクセスを拒否します。

関連項目
ftp(1), skey(1), getusershell(3), syslogd(8)

規格
ftpd は RFC 959 の全てのコマンドを認識し、 RFC 1123 のガイドラインに従い、 RFC 2228 の全てのコマンドを (まだサポートはしていませんが) 認識し 、 RFC 2389 を拡張したものをサポートしています。

歴史
ftpd コマンドは 4.2BSD から登場しました。

/etc/ftpd.conf の機能は、 Simon Burge の作業を元にして、Luke Mewburn によって NetBSD 1.3 でインプリメントされました。

バグ
特権ポート番号を用いてソケットを作成するために、ftpd はスーパーユーザの権限で 実行しなければなりません。サーバはログインユーザの実効ユーザ ID を 保持しておき、アドレスをソケットにバインドする場合にのみスーパユーザの権限で これを行います。

セキュリティに関する考察
RFC 959 では PORT コマンドに制限を設けていないので、 ftpd がだまされてどのホストからのどのようなサービスでも接続してしまう可能性があり、 セキュリティの問題を起こす可能性があります。 /etc/ftpd.conf で “checkportcmd” の機能を使えば、違うホストアドレスが指定された PORT コマンドや、 IPPORT_RESERVED よりポート番号の小さい TCP ポートからの接続を拒否します。 このオプションの利用を 強く お薦めします。