補足:
あまりにも内容が古くなっていたので2002年春に書き直しました。
FreeBSDに標準のftpdは普通に必要な機能はきちんと有し設定が簡単で優れています。雑誌やインストール本を読んで何も考えずにProFTPDやwu-ftpd等の導入を考えている人も今一度FreeBSDのftpdを見直してみてはどうでしょうか?
ftpdの起動方法として3つを挙げます。
1. スタンドアロンでの起動
2. inetdによる起動
3. tcpserver(ucspi-tcp)による起動
スタンドアロンでの起動はinetdによる起動よりも負荷が低いのでアクセスの多いFTPサーバでは特に有効です。ftpdに -D オプションを付けて起動します。
FTPサーバにアクセスがあれば必要なだけ自動的にコプロセスを立ち上げるので複数回起動する必要はありません。
ただし、スタンドアロンでの起動では起動プロセス数を制限したり、アクセス制御は殆どできないのでアクセス要求があれば可能な限り受けてしまいます。
起動例
/usr/libexec/ftpd -D
inetdでの起動はinetdによる起動回数制限ができます。また、FreeBSDは3.2R以降TCP Wrapperがシステムに組み込まれたので /etc/hosts.allow でIPアドレスによるアクセス制御を簡単に行うことができます。FreeBSDではこれがftpdのデフォルトの起動方法です。アクセス数が少ない場合にお勧めです。
/etc/inetd.confから抜粋
ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l
(上の例の行末にある -l については ログを録る を参照して下さい)
tcpserverは接続制御に特化したツールだけあってTCP Wrapperより更に細かな接続制御が可能でDOSアタックに強いという利点があります。
アクセス数が多いサーバでアクセス制御も行いたい場合に特に有効ですが、アクセス数が少なくてもTCP Wrapperよりしっかりしているでお勧めです。
tcpserverのインストール
cd /usr/ports/sysutils/ucspi-tcp
make install
これだけです。その後の設定などは特にありません。
tcpserverによる起動方法。
tcpserver [option][アクセス制御db] 0 ftp /usr/libexec/ftpd -l &
例1 制御無し,最大接続数40(default)の場合
/usr/local/bin/tcpserver -H -R -g 0 -u 0 0 ftp /usr/libexec/ftpd -l &
例2 制御あり,最大接続数10の場合
/usr/local/bin/tcpserver -H -R -g 0 -u 0 -c 10 -x /etc/ftpd.cdb 0 ftp /usr/libexec/ftpd -l &
tcpserverのオプション
-H リモートホスト名を調べない。
-R IDENTを行わない
-c ## 最大同時接続数
-u uid ユーザIDを uid に切り替える
-g gid グループIDを gid に切り替える
詳しくはtcpserverのマニュアルを読んで下さい。
/usr/local/etc/ftpd.cdbの作り方
/usr/local/etc/ftpd.rules
IPアドレス:allow
ユーザー名@IPアドレス:allow
:deny
tcprules /usr/local/etc/ftpd.cdb /tmp/ftpd_rules.tmp < /usr/local/etc/ftpd.rules
chroot機能を利用するとFTPサーバにアカウントを持つユーザーのアクセスに対しルートディレクトリを変更してユーザーをユーザーディレクトリに閉じ込めます。これによりシステム関連で公開してはいけないディレクトリやファイルに気を使う必要が無くなるのでセキュリティの面で管理者にとってかなり負担が軽減されます。また、ユーザーにとっても他のユーザーに自分のホームディレクトリを覗かれることがなくなるという利点があります。(ユーザー全員にchrootを適用した場合)
通常のFTPディレクトリ構造
設定が悪いとユーザーは全てのディレクトリを移動閲覧できるかもしれません。
chroot機能を利用した場合のFTPディレクトリ構造( user-c の場合)
user-cは赤字の部分のみ移動閲覧できる。また、黒字の部分は存在すらわからない。
/etc/ftpchroot というファイル(デフォルトでは存在しません)を作成してそこにユーザー名、またはグループ名を記入します
/etc/ftpchroot の記入例
user-a
user-b
user-c
@group-a
@group-b
@group-c
上の例のように1行につき1ユーザー名や1グループ名(/etc/groupに登録されたグループ名)を記述。
グループを指定する場合はグループ名の先頭に @ を付けます。
ユーザーを個別に拒絶したい場合
/etc/ftpusers ファイルにFTPアクセスを拒絶したいユーザー名を1行づつ記述します。
全てのFTPアクセスを一時的に拒絶したい場合
/var/run/nologin ファイルを用意します。このファイルにはサービスを中断中であるなどのメッセージを記述しておくとユーザーがFTPアクセスしてきた時にそのメッセージを表示して接続を拒否します。ユーザーのFTPクライアントが日本語に対応していない可能性があるのでメッセージは原則として英語で書いてください。
(この方法はメンテナンス時などに一時的にFTPサービスを中断したい時に使用します)
ftpdはログを録るように指定するとsyslogを利用してログを録ります。
syslogの設定
ftpdのログを独立させる場合(現在はこちらが標準)
/etc/syslog.confに追加
!ftpd
*.* /var/log/ftpd.log
さらに touch /var/log/ftpd.log としてログファイルを作成する。(なければ)
chmod 640 /var/log/ftpd.log として属性を制限する。
/etc/newsyslog.confに追加
/var/log/ftpd.log 640 10 * $W0D0 Z
この例では 属性640で /var/log/ftpd.log ログファイルを毎週日曜日の0時に入れ替え、古いログはgzipで圧縮して10個まで保存となる。(ファイルサイズ制限無し)
ftpdのログを/var/log/messagesに含ませる場合
/etc/syslog.confを編集
*.notice;kern.debug;lpr.info;mail.crit;news.err;ftp.debug /var/log/messages
/etc/shellsを確認する
ftpdは/etc/passwdで/etc/shellsに登録されていないshellを指定しているユーザーのアクセスは受け付けない。
例えばユーザーのshellを/sbin/nologin(アクセスお断りのメッセージを表示して切断するダミーshell)などにした場合、/etc/shellsに/sbin/nologin行を追加しておく必要がある。
ftpchrootでファイル転送した時間が9時間ずれて表示される
ホストマシンの内蔵時計を日本時間に合わせているとftpchrootでファイル転送した時間が本来より9時間ずれます。
昔のftpdの記事で古いftpdではftpchrootするとls出来なくなることに触れていますが、時間がずれるのも全く同じことが原因です。
FreeBSDでTIMEZONEをAsia/Tokyoに設定するとホストはJST(日本標準時間)となりGMT(世界標準時間)より+9:00であるとされます。
FreeBSDでTIMEZONEをJSTにするには/usr/share/zoneinfo/Asia/Tokyoを/etc/localtimeにコピーするわけですが(/stand/sysinstallで設定した場合も自動で行われる)、chrootすると/etc/localtimeが参照できなくなり、ホストマシンの内蔵時計を参照しそれをGMTとして認識します。 GMTはJSTより-9:00ですから、パソコンの内部時計を日本時間に合わせている場合に本来の時間より9時間遅れて表示されることになります。
試しにあるユーザーのホームディレクトリ(/home/UserA)にetcディレクトリを作成し、/etc/localtimeを/home/UserA/etc/にコピーしてファイル転送を行うとそのユーザーに限りファイル転送した時間が正しく表示されます。
解決方法としてはホストの内臓時計をGMT(日本時間より9時間遅れ)に合わせる方法があります。
合わせて /etc/wall_cmos_clock を削除し、マシンを再起動する必要があります。