FTPサーバーを利用したファイル共有

以下のテキストは、執筆時当時の情報を元に書いたものであり、 現在の情勢にそぐわないことを含む場合があるので注意されたい。 また、テキストは最終提出原稿で校正を経る前のものなので、実際にUNIXUSER 本誌に記載されたものとは異なる。誤字脱字等そのままである。

致命的な誤り以外は加筆修正等は行なわないので情報の鮮度に気をつけつつ 利用して欲しい。

目次


Part I FTPサーバを利用したファイル共有


■ftpサーバの選択

ftpは初期の頃から利用されている非常に歴史の長いサービスである。WWWが登場
するまでは不特定多数の人へのファイル公開といえば Anonymous ftp が定番中
の定番だった。さらにそれを動かすためのプログラムでいえば、「Anonymous
ftpサーバといえば wu-ftpd」という定番が決まっていた。筆者の管理していた
サイトでも、Anonymous ftp サービスを開始するにあたってwu-ftpd を導入した。
wu-ftpdでは

	* ディレクトリを再帰的にまとめて tar や tar.gz で一括取得できる機能
	* 接続ホストに応じて切り替えるログインクラスによるアクセス制限
	* 取得ファイルの詳細なロギング
	* ディレクトリのalias機能
	* ユーザによるchrootディレクトリの切り替え

などの機能が付加されていて、システム標準(当時SunOS 4.0〜4.1を利用)のftpd 
とは比べ物にならない使い勝手の良さを誇っていた。このログファイルを解析し
て、ファイル転送の統計を取ってネットワーク利用率に関する報告書に利用した
ものだった。このように当時非常に充実した機能をもつプログラムだっただけに
相当満足して利用していたのだが、唯一の不満点は、「設定ファイルが難しい」
という点だった。しかし駆け出し管理者だった当時としては sendmail, BIND な
どを含め設定ファイルを難しく感じるのは自分が未熟なためだと思うのが精いっ
ぱいなので、とくに気にすることもなく使い続けて今日まで至った。

時代はいろいろな意味で変わった。PC-UNIXが普及してくるにつれシステムのイ
ンストーラはどんどん高機能化し、インストールメニューで YES/NO を選択する
だけで手軽に Anonymous ftp サーバが開設できるようになった。これにより複
雑な設定に悩まずとも誰でもサービスを開始できるようになった。そのいっぽう、
インターネット利用者人口の増加は、悪意ある人間の増加をももたらし、色々な
ネットワークサービスデーモンプログラムのセキュリティホールを探しては攻撃
をしかけるクラッカーたちが後を絶たない物騒な世の中になった。とくにftpサー
バに関しては格好の標的とされることが多く、インストールデフォルトでftpサー
バが起動するシステムが被害に遭う例が散見された。

ftpはきわめて基本的なインターネットサービスであるだけに適用範囲が広く、
クライアントにも特別な環境を要求しないなどのことから考えても、ファイルを
公開する手段としては非常に有効な選択肢の一つである。しかし、上述したセキュ
リティの問題があるため、もし利用するならシステムのインストーラ任せにせず
自覚を持って設定したいところである。そうしなければ、セキュリティホールの
修正の施された最新版への追随といったことはできないからである。幸いなこと
に現在では「管理者に優しい」ftpサーバプログラムがいくつか登場してきてい
る。これらを利用すれば、さほど頭を悩まさずにftpサーバを設置でき、最新版
への追随なども余裕を持って対処できることだろう。

Part I では、新世代のftpサーバプログラムの代表として、ProFTPDと
publicfileをとりあげ、それぞれの導入方法を紹介する。ProFTPDは分かりやす
いインストール手順と、十分にリーズナブルなデフォルト設定、きめ細やかな豊
富な機能が魅力である。publicfileは格段にすぐれたセキュリティ性の高さが魅
力である。いずれも知れば知るほど、どんどん管理者の欲求を満たす機能を引き
出せるソフトウェアであるが、ページ数の関係で典型的な利用を想定した標準的
な設定の部分しか紹介できなかった。それだけでも十分有用なサーバが構築でき
ると思うので、この解説を読んでぜひ設定にチャレンジし、さらに深い部分を探
していっていただきたい。

■ProFTPD

ProFTPDは、全く新しいコンセプトで柔軟でセキュアで、かつ設定方法の分かり
やすいftpサーバを作ることを目指してスクラッチから書かれたプログラムであ
る。http://www.proftpd.net/features.html によると、以下のような特徴を持っ
ている。

	* Apacheと似通った構文による単一の平易な設定ファイル

	  wu-ftpdの定義ファイルは何種類かあり、それらはwu-ftpd専用の構文
	  で書く必要があった。Apacheのhttpd.confと類似した構文であれば類
	  推が効きやすく管理者の学習負担が軽減される。

	* ディレクトリごとの .ftpaccess を認識

	  これもApacheの .htaccess と同様ユーザが個人権限でファイルコン
	  テンツのアクセス制御などを変更できるのでftpによるファイル公開
	  の柔軟度が増す。

	* virtual FTP サーバと anonymous FTP サーバを複数持てる

	  wu-ftpdなどでは全く違うコンテンツを指す anounymous ftp サーバ
	  を作りたい場合は別のサーバを立てる必要があった。ProFTPDでは
	  パスワードなしで入れる anonymous と等価のユーザをいくらでも作
	  れるうえ、Apacheでもおなじみの virtual host 機能によるコンテン
	  ツ切り替えも簡単に実現できる(IPアドレスベース)。

	* スタンドアロン、inetd/xinetd経由いずれでも起動できる設計

	  システム全体の負荷や、ftpサービスの利用頻度に応じて起動形態を
	  選択できるので効率的である。

	* Anonymous FTP 用のルートディレクトリに特別な構造を要求しない

	  通常 Anonymous FTP で見せるルートディレクトリには chroot する
	  ため、最低限のシステムファイルを揃えておかなければならず、これ
	  がしばしばftpサーバ管理を始める人の悩みの種だった。ProFTPDでは
	  その必要はない。

	* SITE EXEC コマンドの廃止

	  近年のインターネット環境ではセキュリティホールを誘発する原因と
	  なる外部コマンド実行は一切行わない設計とした。

	* 隠しディレクトリ機能

	  Unix-styleパーミッションを利用して、ディレクトリの存在自体を隠
	  すことができる。

	* 非特権ユーザでの起動

	  デーモンプログラムにroot権限を与えないことにより、アタックされ
	  た場合の被害を軽減する。

	* ロギングとutmp/wtmpのサポート

	  wu-ftpdで取れたような、取得ファイルリストなどの詳細なログが
	  ProFTPDでも取れるようになっている。

	* shadow password のサポート

	  最近のUnixとしては当然だろう。もちろんPAM(Pluggable
	  Authentication Modules)にも対応している。


やはり、もっとも管理者にとってありがたいのは設定の容易性ではなかろうか。
標準的なインストール手順を遂行するだけで、ほぼそのままftpサーバが稼動可
能となる。

■ProFTPDの導入

ご存じのようにftpサーバはクラッカーによる絶え間ないアタックの標的の最右
翼となっているので、セキュリティホールが見付かる頻度が非常に高くなってい
る。ProFTPDも開発途上の最も成長著しい時期にはいろいろなセキュリティホー
ルが報告されていた。しかし開発陣の対応もすばやく、すぐに修正パッチが出さ
れた。現在では大分落ち着いて来た感もあるが、やはりセキュリティ情報は鮮度
が大切なのでつねに注意を払うよう気をつけて欲しい。

さて、本原稿執筆時の最新版は ProFTPD 1.2.2rc3 で、
http://www.proftpd.net/ あるいは各所のftpサイトから入手できる。1.2.2rc3
のアーカイブ proftpd-1.2.2rc3.tar.gz を入手しての作業を追う形で解説しよ
う。繰り返しになるが、これを読む段階でより新しいバージョンが出ていたらそ
ちらを入手して利用するようにして欲しい。

導入の流れは以下のようになる。

	1. proftpdのコンパイルとインストール
	2. 動作定義ファイルの修正
	3. 起動

順を追って解説しよう。

  ●proftpdのコンパイルとインストール

  各種PC-UNIXでは、利用価値の高いソフトウェアをコンパイルした形、もしく
  はmakeコマンドを叩くだけでインストールできるような形にまとめてパッケー
  ジ化したものが利用できるようになっていることが多い。もし、最新版の
  ProFTPD のパッケージが利用できればそれを利用して手軽にインストールして
  も構わない。そうでない場合は自らコンパイルとインストールを行う必要があ
  る。いずれにせよ、常にProFTPDの最新版に追随するためには自分でコンパイ
  ル&インストールするしかないので以下の手順を覚えておくべきだろう。

  まずソースアーカイブを展開しドキュメントに目を通そう。

	# tar zxpf proftpd-1.2.2rc3.tar.gz
	# cd proftpd-1.2.2rc3
	# less INSTALL README*

  README* ファイル群には各種OSに応じた個別の注意点が書かれているので、
  該当するOSで作業している場合はこれも熟読しよう。

  続いて、configure を行う。標準では /usr/local をインストールプリフィ
  クスとしてさらにその下の bin/ etc/ man/ sbin/ var/ の各ディレクトリ
  に関連ファイルをインストールすることになる。ProFTPDをインストールし
  てみて、試験後すぐにアンインストールしたくなった場合などのことを考え
  ると、インストールプリフィクスは /usr/local/proftpd のように ProFTPD 
  専用のディレクトリにしておくと後々楽なことが多い。以下の例ではインス
  トールプリフィクスを /usr/local/proftpd にしたものとする。もちろんこ
  れは読者の環境と好みに応じて好きなディレクトリに変更して構わない。

	# ./configure --prefix=/usr/local/proftpd

  configure に成功したらコンパイルとインストールを行う。

	# make all install

  これにより、/usr/local/proftpd 以下に関連ファイルがインストールされ
  る。以後の説明では、/usr/local/proftpd を $ProFTPD と表記する。

  ●動作定義ファイルの修正

  インストールが正常に完了すると、$ProFTPD/etc/ にProFTPDの動作定義ファ
  イルである proftpd.conf がコピーされる。proftpd.conf の初期状態はリス
  ト【い】のようになっているので、必要に応じてこれを修正することになる。
  proftpd.conf は、先述の通りApacheの定義ファイル httpd.conf と類似した
  書式となっている。

--[リスト い]------------------------------------------------------------
# This is a basic ProFTPD configuration file (rename it to 
# 'proftpd.conf' for actual use.  It establishes a single server
# and a single anonymous login.  It assumes that you have a user/group
# "nobody" and "ftp" for normal operation and anon.

ServerName			"ProFTPD Default Installation"
ServerType			standalone
DefaultServer			on

# Port 21 is the standard FTP port.
Port				21
# Umask 022 is a good standard umask to prevent new dirs and files
# from being group and world writable.
Umask				022

# To prevent DoS attacks, set the maximum number of child processes
# to 30.  If you need to allow more than 30 concurrent connections
# at once, simply increase this value.  Note that this ONLY works
# in standalone mode, in inetd mode you should use an inetd server
# that allows you to limit maximum number of processes per service
# (such as xinetd)
MaxInstances			30

# Set the user and group that the server normally runs at.
User				nobody
Group				nogroup

# Normally, we want files to be overwriteable.

  AllowOverwrite		on


# A basic anonymous configuration, no upload directories.

  User				ftp
  Group				ftp
  # We want clients to be able to login with "anonymous" as well as "ftp"
  UserAlias			anonymous ftp

  # Limit the maximum number of anonymous logins
  MaxClients			10

  # We want 'welcome.msg' displayed at login, and '.message' displayed
  # in each newly chdired directory.
  DisplayLogin			welcome.msg
  DisplayFirstChdir		.message

  # Limit WRITE everywhere in the anonymous chroot
  
    DenyAll
  


-------------------------------------------------------------------------

  標準状態の proftpd.conf のままではうまく動かせない点があるのでいくつか
  修正する。

  ServerName には Greeting message に出る任意のサーバ名を指定する。自分
  のサイトにふさわしい名前を設定しよう。

	ServerName		"UNIXUSER FTP Server"

  必要ならftpデーモンの動作するUID, GIDを指定する

	User			nobody
	Group			nogroup

  また、Anonymous ftp サービスを指示するセクションに以下の項目を追加する。

	
	  User			ftp
	  Group			ftp
	  RequireValidShell	no
	  ~~~~~~~~~~~~~~~~~~~~~~~~
         〜以下略〜

  RequireValidShell 指示子(directive)は、ftpログインするユーザのシェルが
  /etc/shells に登録された「正当なシェル」であることを要求するか否かを指
  示する。歴史的にftpサーバプログラムでは、ログインするユーザが正当なユー
  ザかどうかを判定する手段として、passwdエントリ中のシェルの値を確認する。
  これが /etc/shells ファイルに登録されているものであればログインを許可
  されているユーザであると判定し、ftpログインも許可する。いくつかのシス
  テムでは、passwdデータベース中「ユーザftp」のシェルは存在せずなおかつ
  /etc/shellsにないものが指定してある(たとえばFreeBSDでは /nonexistent)。
  このため、「ユーザftp」アカウントを利用する Anonymos login が初期状態
  では不許可となっていて、この点はProFTPD以外も共通である。ProFTPD以外を
  利用する場合は /etc/shells に /nonexistent を登録する、などの処置で対
  処する必要があるが、ProFTPDでは必ずしもそうしなくても良く、
  RequireValidShell 指示子で挙動を変更できる。

  ●ProFTPDの起動

  proftpd.conf の修正が終わったら ProFTPD を起動する。ProFTPDの特徴説明
  にあったように、スタンドアロン起動とinetd経由起動が選べる。今回はデフォ
  ルトにしたがってスタンドアロン起動を選択してみる。

  まず最初に、システム標準のftpdが起動されないように確認する。最近のシス
  テムではデフォルトではftpdが起動しないよう、/etc/inetd.conf で該当部分
  がコメントアウトされていることが多い。

	===== /etc/inetd.conf =====
	#ftp	stream	tcp	nowait	root	/usr/libexec/ftpd	ftpd -l

  もしコメントアウトされていなかったら上記のように # でコメントアウトし、
  inetd にHUPシグナルを送る。

	# kill -HUP 「inetdのPID」

  この段階でlocalhostにftp接続できなくなっていることを確認しよう。
                              ~~~~~~~~~~~~~~~~~~
	# ftp localhost
	ftp: connect: Connection refused
	ftp> 

  続いてProFTPDを起動する

	# /usr/local/proftpd/sbin/proftpd

  起動がうまくいけば messages ファイル(脚註: PC-UNIX等は
  /var/log/messages、SunOS等は /var/adm/messages) に

	Jul 19 14:34:16 venus proftpd[66560]: venus - ProFTPD 1.2.2rc3 (release) (built Wed Jul 18 17:31:53 JST 2001) standalone mode STARTUP 

  といった起動ログが出力される。起動が確認できたらlocalhostにftp接続し、
  ProFTPD によるメッセージが表示されれば設定成功である。

	# ftp localhost
	Connected to localhost.
	220 ProFTPD 1.2.2rc3 Server (UNIXUSER FTP Server) [venus]
	Name (localhost:yuuji): 

  ためしに anonymous login してみよう。

	Name (localhost:yuuji): ftp
				~~~
	331 Anonymous login ok, send your complete email address as your password.
	Password: yuuji@ymzk.org
	          ~~~~~~~~~~~~~~(実際には画面に出力されない)

	230 Anonymous access granted, restrictions apply.
	Remote system type is UNIX.
	Using binary mode to transfer files.
	ftp>

  loginが許可されたら設定成功である。

  以上のように、ProFTPDを使った Anonymous FTP サーバの構築は、ユーザftp 
  のシェルという一点にさえ気をつければ何ら難しい設定の必要もなく完了する。
  続いて、ここで構築した「マイftpサーバ」を利用して、どこからでも気軽に
  利用できるファイルサーバに仕立てる方法を紹介しよう。

  ●ProFTPDによるファイル公開

  大手の Anonymous FTP サーバの場合は、非常に多くの人を対象とし、多くの
  内容を対象とするので Anonymous login したときに見えるディレクトリ空間
  には非常に多種多様のファイルを用意している。もっと小規模の集団を対象と
  する場合は、その集団が興味を持っている内容のファイルだけを見せた方が分
  かりやすい。

  ProFTPDではそのような、相手によって見せる内容を切り替えるための手段が
  いくつか用意されている。ここでは、ユーザによって切り替える方法と、アク
  セスしてきたホストに応じて制限をかける方法について解説しよう。

    ・ユーザによる切り替え

    通常のftpデーモンプログラムでは、anonymous login できるユーザは 
    "ftp" ユーザ、またはそのaliasである "anonymous" ユーザのみにかぎられ
    ているが、ProFTPDには、複数のユーザを anonymous login させることがで
    きる。ここでは、二つのユーザ fishing, driving を作り、それぞれに 
    anonymous login 権限を与えて、別々のコンテンツ(ディレクトリ)を見せる
    ための設定を行ってみよう。

    まず、それぞれのユーザにどのディレクトリを見せるかを決定して、そのディ
    レクトリをホームディレクトリとするようなアカウントを作成する。以下の
    ように決定したと仮定する。

	ユーザ		|
	----------------+--------------
	fishing		| /archive/pub/fishing
	driving		| /archive/pub/driving

	これらのディレクトリを用意し、必要なら初期コンテンツをいれておく。

	# mkdir /archive/pub/fishing
	# touch /archive/pub/fishing/JustFishing\!
	# mkdir /archive/pub/driving
	# touch /archive/pub/fishing/Justdriving\!

    各ユーザのホームディレクトリを上記のように設定してアカウントを作成する。

	(Solaris, NetBSD, OpenBSD, 各種Linuxの場合)
	# groupadd fishers
	# useradd -g fishers -d /archive/pub/fishing -s /noshell fishing
	# groupadd drivers
	# useradd -g drivers -d /archive/pub/driving -s /noshell driving

	(FreeBSDの場合)
	# pw groupadd fishers
	# pw useradd fishing -g fishers -d /archive/pub/fishing -s /noshell
	# pw groupadd drivers
	# pw useradd driving -g drivers -d /archive/pub/driving -s /noshell

    つづいて、二つのユーザを anonymous login 可能なユーザとして
    proftpd.conf に登録する。以下は、proftpd.conf への追加分である。

	
	  User                          fishing
	  Group                         fishers
	  RequireValidShell             no
	  
	    DenyAll
	  
	
	
	  User                          driving
	  Group                         drivers
	  RequireValidShell             no
	  
	    DenyAll
	  
	


    (スタンドアロン起動の場合)稼動中のProFTPDにHUPシグナルを送る。

	# kill -HUP `cat /usr/local/proftpd/var/proftpd.pid`

    実際にftpログインして確認してみよう。
	# ftp localhost
	Connected to localhost.
	220 ProFTPD 1.2.2rc3 Server (UNIXUSER FTP Server) [venus]
	Name (localhost:yuuji): fishing
	331 Anonymous login ok, send your complete email address as your password.
	Password:
	230 Anonymous access granted, restrictions apply.
	Remote system type is UNIX.
	Using binary mode to transfer files.
	ftp> dir
	227 Entering Passive Mode (127,0,0,1,14,34).
	150 Opening ASCII mode data connection for file list
	-rw-r--r--   1 yuuji    wheel           0 Jul 19 08:04 JustFishing!
	226 Transfer complete.

    同様に driving ユーザでログインして、全く違うディレクトリ空間が見え
    ることを確認しよう。

    ・ホストベースのアクセス制限

    ProFTPDでは複数のユーザ名に独立したanonymous権限を持たせ、それぞれ別々
    のディレクトリを見せることが可能である。これは何かのファイル群を公開
    したい対象が複数グループ存在するときに便利であるが、ユーザ名さえ分かっ
    てしまえば誰でもanonymousアクセスできるので場合によってはあまり見せ
    たくないものも簡単に見せることになる。「anonymous ftp サービスとして
    アクセスさせるのが手軽で良いが、誰にでも(どこからでも)アクセスできる
    ようにはしたくない」というコンテンツを置きたいのであれば、ホストベー
    スのアクセス制限を利用すると良い。

    この場合、Limit指示子を利用して設定する。先の例で、drivingユーザでの
    anonymousアクセスはLAN内のホストと、*.friend.example.co.jp からのア
    クセスしか認めないようにしてみよう。この場合、drivingのセクションを
    以下のようにすれば良い。

	
	  User                          driving
	  Group                         drivers
	  RequireValidShell             no
	  
	   Order Allow, Deny
	   Allow from localhost, 192.168.2., .friend.example.co.jp
	   Deny  from All
	  
	  
	    DenyAll
	  
	

    Limit指示子はftpコマンドの許可/禁止を設定できる。Limitの直後には、コ
    マンドまたはコマンドグループを指定できる【表ほ】
----[表 ほ ]----------------------------------------------------------
	【Limitに指定できるコマンド】
	CWD		ディレクトリ移動(Change Workin Directory)
	MKD		ディレクトリ作成(MaKe Directory)
	RNFR, RNTO	リネーム(ReName FRom/TO)
	DELE		ファイル消去(DELEte)
	RMD		ディレクトリ削除(ReMove Directory)
	RETR		ファイルのGET(RETRieve)
	STOR		ファイルのPUT(STORe)
	SITE_CHMOD	chmod(CHange MODe bits)

	【Limitに指定できるコマンドグループ】
	READ		「読み出し」に関連する全てのFTPコマンド(RETR, STATなど)
			ディレクトリリスティングは含まない
	WRITE		「書き込み/作成/削除」に関連する全てのFTPコマンド
			(MKD, RMDなど)
	DIRS		ディレクトリリスティング系コマンド(LIST, NLST)
	ALL		あらゆるFTPコマンド(READ WRITE DIRS全てと等価)

	【Limitに指定できる特殊コマンド】
	LOGIN		サーバへのログイン
----------------------------------------------------------------------

    この場合LOGIN動作の制限を行なう。Limit節内部にかかれた Order 指示子
    は後続する許可/不許可操作を解釈する順番を指定する。"Order
    Allow,Deny" と書かれているので、「まずAllowに指定されているアドレス
    かどうかのチェックを先にし、適用されるものがあればDenyの評価は行なわ
    ない。Allowで何も適用されなければDeny行が適用される」という規則の元
    に解釈が行なわれる。今回のように、一部のホストからのアクセスのみを許
    可したいときは "Order Allow, Deny" で、逆に一部のホストからのアクセ
    スを禁止したいときは "Order Deny, Allow" で制限を加えるとやりやすい
    だろう。

  ●その他のアクセス制限

  ProFTPDには便利な機能が他にもたくさんある。ここでは、安定していて、利
  用効率の高いサーバ運用を目指すために役立つものをいくつか紹介しよう。

    ・接続数の制限

    ProFTPDをスタンドアロンモードで起動する場合は、proftpd.conf 内で
    MaxClients指示子を利用する。

	MaxClients	30

    これは同時に接続を許可するクライアントの上限数を指定する。これはログ
    インの完了したクライアントの数を制限するもので、正当な利用者の同時接
    続数を制限するものと考えて良い。

    いっぽう、MaxInstances指示子は、接続要求を受けるために産出するチャイ
    ルドプロセスの上限数を決定する。DoS(Denial of Service: サービス不能
    可)攻撃からまもることを目的とする場合はこちらも指定するのが良いだろ
    う。

    ProFTPDはスタンドアロンモードではなく、inetd経由などでも起動できる。
    その場合は上記の接続数制限指定は無効になる。近年のPC-UNIXのinetd で
    は1分間当たりの最大接続数の制限ができるようになっていたりするが、商
    用UNIXではあまり見掛けない。いずれのプラットフォームでも共通の方法で
    同時接続クライアント数制限をしたい場合は次節の publicfile の導入時の
    解説で触れている ucspi-tcp とdaemontools を利用すると良い。これを用
    いて、ProFTPD を非スタンドアロンモードで起動する場合は、たとえば

	#!/bin/sh
	ProFTPD=/usr/local/proftpd
	exec env - \
	PATH=/usr/local/bin:$ProFTPD/sbin:$PATH \
	envuidgid nobody softlimit -o20 -d5000000 \
	tcpserver -DRHl0 -b20 -c40 0 ftp proftpd

    のような起動スクリプトを、システムのブート時に上がるようにしておくと
    良い。上記の例では、同時接続数を40個(-c40)に設定している。その他指定
    している数値パラメータは各自調整して利用することになる。これらのパラ
    メータの意味も含めた daemontools と tcpserver の利用方法については
    COLUMNで紹介する。


    ・帯域制御

    ftpはデータ転送に特化したプロトコルであるため、オーバーヘッドがすく
    なく、大きなデータを転送するときなどは回線容量ぎりぎりまで使える。こ
    のため、回線を一人占めできるような環境では非常に効率的にデータが転送
    できるのだが、複数人で利用しているネットワークではftpによるデータ転
    送によって回線を食いつくしてしまい、その他のユーザが非常に「重く」感
    じる結果をもたらし、サイト全体のユーザビリティは総体的に低下すること
    になる。

    アプリケーションレベルでの帯域制御をProFTPDで行うことができる。
    RateReadBPS指示子、RateReadFreeBytes指示子、RateReadHardBPS指示子が
    それに当たる。

	* RateReadBPS		クライアントが1ファイルを読みだすときのデー
				タ転送速度の上限を指定する。単位は
				Bytes/s(bitでないことに注意)。0を指定す
				ると回線状況に依存した最大速度での転送と
				なる。
	* RateReadFreeBytes	クライアントが1ファイルを読みだすときに、
				RateReadBPS の制約を受けずに自由に転送で
				きるデータサイズを指定する。大きなファイ
				ルを読みだす場合、この値を越えた場所から
				RateReadBPS の速度制限がかかる。
	* RateReadHardBPS	RateReadFreeBytes を指定している場合、ファ
				イル読みだし中に RateReadFreeBytes を越
				えた時点で、平均転送速度が RateReadBPS
				の値に落ちるまで帳尻を合わせるためにデー
				タ転送を停止するかどうかを on, off で指
				定する。RateFreeBytesに大きな値を指定し、
				ReteReadBPSに回線速度よりかなり小さな値
				を指定している場合は平均値を合わせるのに
				時間がかかるため、クライアントはかなり待
				たされることになる。

    これらの帯域制御はproftpdのインスタンスごとに機能するため、一つのク
    ライアントだけにかかる速度制限となる。つまり、複数のセッションで同時
    に読み出しを行う場合はそれぞれの転送速度をあわせたものがftpサーバ全
    体のデータ転送速度となる。回線負荷的に余裕のないサイトで ProFTPD の
    帯域制御に頼る場合は、接続クライアント数の上限指定も良く考慮した上で
    それぞれの値を設定する必要があるだろう。

  ●より進んだProFTPDの設定

  今回紹介した機能はProFTPDの持つほんの一部の機能であるといって良い。自
  分の管理するサイトに応じたより詳細な設定を行ないたい場合は、本誌1999年
  11月号〜2000年4月号の短期集中連載「ProFTPD入門講座」が非常に参考になる
  だろう。

■publicfile

publicfileは qmail の作者、D. J. Bernstein によるHTTP、FTPでのファイル公
開ツールである。作者の飛び抜けたセキュリティ意識を反映するように、
publicfileも群を抜いたセキュリティ性の高さを誇っている。
http://cr.yp.to/publicfile.html より、publicfileの特徴をまとめると以下の
ようになる。

	* コマンドリクエストを受け付ける前には公開ファイルエリアに
          chroot()し、root権限も剥ぎ落とす。
	* ユーザに「ログイン」をいっさいさせない。このため侵入者はユー
          ザ名とパスワードチェックのためにpublicfileを使うことができない。
	* ファイルの属性が、user, group, other いずれかに読み取り不能に
          設定されたものは、外部からの取得を拒否する。
	* 公開ファイルエリアの修正はいっさい試みない。HTTP, FTPどちらで
          もサーバエリアの修正のためのあらゆるコマンドを拒否する。
	* 外部プログラムの実行はいっさいしない。HTTP CGI(★い)や、FTP
          SITE EXECはサポートしない。
	* stdioのようなバグの入りやすいライブラリを使っていない。

---[★ い]-----------------------------------------------------------
shttpd(http://www.superscript.com/shttpd/intro.html) などを使うと
良いだろう。
---------------------------------------------------------------------

これらの点から分かるように、publicfileでは「ファイルを公開するだけ」に限
定した実装となっているため、ProFTPDに見られるような様々な便利機能は装備
していない。逆に、機能を絞っているからこそ得られる安全性は随一である。も
し、要求されるセキュリティ性が非常に高いサーバでファイルの一般公開をする
必要がある場合は publicfile の導入を検討する価値は高いだろう。

ここでは、「きわめて安全な anonymous ftp サーバの構築」を目標として、
publicfile を利用したftpサーバの設定方法を解説する。

■publicfile の導入

publicfileは単体で動作するのではなく、ucspi-tcp, daemontools と組み合わ
せて使うように設計されている。ucspi-tcp, daemontools をこれまで導入して
いない場合は、あらかじめこれらをインストールする必要がある。どちらも
D. J. Bernstein によるツールで、インストールも簡単なので両手順をここで解
説しておこう。最終目的のpublicfileの導入が完了するまでの手順は以下のよう
になる。
	1. ucspi-tcpのインストール
	2. daemontoolsのインストール
	3. daemontoolsの稼動開始のための設定
	4. publicfileのインストール
	5. publicfileの動作設定

すでにucspi-tcp, daemontoolsがインストールしてあるシステムでは、4番から
始めれば良い。1番から順を追って解説しよう。

  ●ucspi-tcpのインストール

  原稿執筆時の最新版は ucspi-tcp-0.88 で、http://cr.yp.to/ucspi-tcp.html
  から "How to install ucspi-tcp" のリンクをたどると入手できる。以下の手
  順でインストールは完了する。

	# gzip -dc ucspi-tcp-0.88.tar.gz | tar xvpf -
	# cd ucspi-tcp-0.88
	# make
	# make setup check

  デフォルトインストールでは、ucspi-tcpに含まれるファイル群が /usr/local 
  ディレクトリ以下にインストールされる(実際には実行ファイルしかないので
  それらが /usr/local/bin に入る。これを変更したい場合は、ソースディレク
  トリに含まれる、conf-home ファイルを変更する。ただし、インストールパス
  を変えた場合は、次項で説明するdaemontoolsの起動時に、ucspi-tcp の実行
  ファイル格納ディレクトリがコマンドサーチパス(環境変数PATH)に含まれるこ
  とを保証しなければならないことに注意する。

  ucspi-tcp は多くの場合、inetdと置き換える形でネットワークサービスデー
  モンの起動に利用するのだが、今回はpublicfileの configure プログラムが、
  ftpデーモンプログラムの起動スクリプトに tcpserver コマンド(ucspi-tcp
  コマンド群のひとつ)を自動的に埋め込んでくれるので、あまり ucspi-tcp の
  利用方法に詳しくなくても問題ないだろう。

--[COLUMN 1 tcpserver]-----------------------------------------------------

ucspi-tcp に含まれる tcpserver は外部からのTCP接続要求を受けて、対応する
ネットワークサービスデーモンを起動するプログラムである。その際に、接続ク
ライアントのアドレスによって接続の許可/不許可を制御したり、同時接続数を
制御したりすることができる。類似したものとしてinetdを想起するだろう。
inetdは、/etc/inetd.conf に登録してあるネットワークサービス全てのポート
を監視し、外部からの接続要求を受けて対応するデーモンプログラムを起動する
(下図)。

              外部からのソケット接続要求
                       ↓
  +-------------+--------------+----------------+-----------------+-----+
   inetdが監視  | Port21(ftp)  | Port23(telnet) | Port110(pop)    | ... |
                +--------------+----------------+-----------------+-----+
 対応するデーモン      ↓              ↓                ↓
 をinetdが起動        ftpd          telnetd            pop3d


これにたいし tcpserver は、一つのtcpserver が一つのサービスポートのみを
監視する形となっている。

    接続要求      接続要求       接続要求
       ↓             ↓           ↓
  +-----------+ +-----------+ +-----------+
  |  Port21   | |  Port23   | | Port 110  |
  |(tcpserver)| |(tcpserver)| |(tcpserver)|
  +-----------+ +-----------+ +-----------+
       ↓             ↓           ↓
      ftpd          telnetd       pop3d

それぞれのサービスごとに個別の接続制限を課す形で運用する。tcpserverは、

	tcpserver [オプション] ホスト ポート番号 デーモンプログラム

という書式で起動する。「ホスト」には接続を受けるIPアドレスを指定する。複
数のネットワークインタフェースを持つサーバで、一つのIPアドレスだけで接続
を受けたい場合にはそのIPアドレスを指定する。「ホスト」に0を指定すると、
サーバのもつ全てのローカルIPアドレスを指定したものとみなす。
「ポート番号」には接続を受ける、番号または /etc/service のサービス名を指
定する。「デーモンプログラム」は実際に起動するプログラムを指定する。指定
できるオプションには以下のものがある。より詳しい説明は
http://cr.yp.to/ucspi-tcp/tcpserver.html を参照して欲しい。

  一般的オプション
  =========================================================================
  -q		エラーメッセージなどを表示しない
  -Q		(デフォルト)エラーメッセージを表示する
  -v		おしゃべり(Verbose)モード。エラーメッセージと
		ステータスを表示する。
  接続制御オプション
  =========================================================================
  -c N		同一デーモンを同時に起動する上限をN個に
  -x cdb	tcprulesコマンドで作成したcdbファイルのルールに従う。
  -X		-x オプションで指定したcdbファイルが存在しない場合でも
		接続を受け付ける。
  -B "BANNER"	接続確立直後にクライアントに送られるバナー文字列
  -g GID	接続を受けた後に移行するグループID
  -u UID	接続を受けた後に移行するユーザID
  -U		-u $UID -g $GID と同じ
  -1		起動時に標準出力にローカルポート番号を出力する。
  -b 数値	TCP SYNのbacklogを約「数値」個に制限する。
  -o		IPオプションを残す。もしクライアントがソースルー
		ティングオプションをつけていたらそのまま送り返す(危険)。
  -O		(デフォルト)IPオプションを除去する
  -d		クライアントの応答が遅いときにデータ送出を遅れさせる。
  -D		-dの逆。

  データ収集オプション
  =========================================================================
  -h		(デフォルト)クライアントのホスト名をDNSに問い合わせ、結
		果を $TCPREMOTEHOST に入れる。
  -H		-hによるDNS検索を行なわない。
  -p		ホスト名検索のあと、その名前でIPアド
		レスを引いてみて、それがクライアントのIPアドレスと一致し
		ない場合は $TCPREMOTEHOST を削除する。
  -P		-pの逆。
  -l localname	ローカルホスト名のDNS検索をせず、"localname" を利用する。
		普通は 0 などを指定する。
  -r		(default)クライアントから $TCPREMOTEINFO を得ようとする
  -R		-rの逆。
  -t N		$TCPREMOTEINFOの取得のタイムアウトをN秒にする。
		26秒がデフォルト。
--[COLUMN 1 ここまで]-----------------------------------------------------

  ●daemontoolsのインストール

  原稿執筆時の最新版は daemontools-0.76 で、http://cr.yp.to/daemontools.html
  から "How to install daemontools" のリンクをたどると入手できる。以下の手
  順でインストールは完了する。

	# mkdir -p /package
	# chmod 1755 /package
	# cd /package

  このディレクトリにソースアーカイブ daemontools-0.76.tar.gz をコピーし、
  以下の作業を続ける。

	# gzip -dc daemontools-0.76.tar.gz | tar xvpf -
	# cd admin/daemontools-0.76
	# package/install

  以上の作業により daemontools のコマンド群が /usr/local/bin/ にインストー
  ルされる(★ろ)。

---[★ ろ]-----------------------------------------------------------
 実際には各コマンドは /usr/local/bin 内のシンボリックリンクとして作成される。
---------------------------------------------------------------------

  ●daemontoolsの稼動開始のための設定

  インストール作業で起動したinstallスクリプトでは、システムのスタートアッ
  プファイルにdaemontoolsの中核をなす svscan コマンドの起動処理が登録さ
  れるはずである。これが期待どおりになっているかを確認するため、一度リブー
  トして確認してみよう。リブート後、svscan プロセスが動いていればインス
  トールは完了、動いていなければソース展開ディレクトリにある 
  archive/boot.rclocal スクリプトに書いてあるコマンドライン(リスト【は】) 
  が実行されるようにシステムのスタートアップファイルに登録すればよい。

---[リスト は]-----------------------------------------------------------
csh -cf '/command/svscanboot &'
-------------------------------------------------------------------------


--[COLUMN 2 daemontools]-----------------------------------------------------

UNIXベースのシステムを運用する場合、色々なサービスデーモンプログラムの動
作を管理する必要がある。多くのデーモンプログラムは、/etc などのディレク
トリに設定ファイルを持ち、それにしたがって挙動を決定する。管理者が設定ファ
イルを書き変えた場合は動作しているプログラムに -HUP シグナルを送る、とい
うのが伝統的なプログラムの動作となっている。「動いているプロセスのPIDを
調べてこれにシグナルを送る」、というのは単純な作業ではあるが複数のシステ
ムを管理しているとOSによって方法が違うので混乱しがちである。BINDやApache 
に見られるように、最近では動作中のデーモンプログラムに設定ファイルの読み
直しや、再起動、終了などの指令を送るための外部コントロールユーティリティ
が付属しているものもある。全てのデーモンプログラムが、この種のコントロー
ルユーティリティを備えていればとても管理が楽になるのだろうが、残念ながら
それは期待できない。

daemontoolsは多種多様のデーモンプログラムの、起動、停止、落ちていないか
の監視と落ちた場合の再起動(自動)、各種シグナルの送信、ログの取得、ログロー
テート(自動)、などの作業を統一的に行なうためのツール集である。本文中で解
説した svscanboot は、daemontools の核となる svscan プログラムの起動スク
リプトである。svscanプログラムは(デフォルトで) /service ディレクトリを常
に監視し、同ディレクトリ内にさらにディレクトリがあった場合はそのディレク
トリを引数に supervise プログラムを起動する。

superviseプログラムは、与えられたディレクトリで定義されるサービスデーモ
ンプログラムの起動と監視を行なう。このディレクトリには "run" という名前
のスクリプトがあることを期待する。デーモンプログラムを開始するためにまず
./run をまず起動し、その後常にそのスクリプトから起動されたデーモンプロセ
スを監視して、もし途中で終了してしまうようなことがあったら、少しの間隔
(約1〜5秒)を置いて再起動する。

svscan, supervise両プログラムの連係により、目的とするサービスデーモンが
起動される(たとえば今回の場合はftpd)。これらのサービスデーモンに指令を送
るためのコントロールコマンドがsvcである。svcコマンドでは以下のオプション
が利用できる。

  -u  デーモンを上げる。
  -d  デーモンを落とす。再起動しない。
  -o  デーモンを上げる。ただしデーモンが止まっても再起動しない。
  -p  デーモンに STOP シグナルを送る(Pause)。
  -c  デーモンに CONT シグナルを送る。
  -h  デーモンに HUP シグナルを送る。
  -a  デーモンに ALRM シグナルを送る。
  -i  デーモンに INT シグナルを送る。
  -t  デーモンに TERM シグナルを送る。
  -k  デーモンに KILL シグナルを送る。
  -x  supervise がただちに終了するよう指示する。何かトラブルが起きたとき
      以外はこのオプションは利用しないはずである。

実際にサービスデーモンにシグナルを送りたいときは、

  # svc オプション サービスディレクトリ

のように指定する。「サービスディレクトリ」は /service/ ディレクトリ内に
張ったシンボリックリンクディレクトリを指定する(今回の場合は
/service/ftpd)。ただ、「サービスを止める」ために svc -d /service/ftpd
などとしても、supervise コマンドがすぐに再起動するので、本当にサービス自
体をしばらく止めたい場合は

  # touch /service/ftpd/down
  # svc -d /service/ftpd

とする。"down" という名前のファイルを作っておけば、superviseが再起動せず
に待機するようになる。サービスを再開したいときは

  # rm /service/ftpd/down
  # svc -u /service/ftpd

とすればよい。

--[COLUMN 2 ここまで]--------------------------------------------------------


  ●publicfileのインストール

  原稿執筆時の publicfile の最新版は publicfile-0.52.tar.gz である。これ
  は http://cr.yp.to/publicfile.html から "How to install publicfile" の
  リンクをたどると入手できる。ソースアーカイブを入手したら以下の手順を取
  ることでインストールが完了する。

	# gzip -dc publicfile-0.52.tar.gz
	# cd publicfile-0.52
	# make
	# make setup check

  デフォルトでは、/usr/local/publicfile 以下にpublicfileの関連ファイル群
  がインストールされる(★に)。

---[★ に]-----------------------------------------------------------
 コマンドしかないので実際には /usr/local/publicfile/bin だけに入ることに
 なる。
---------------------------------------------------------------------

  ●publicfileの動作設定

  今回の特集の主眼をふまえて、ここでは publiacfile を用いた anonymous
  ftp サーバの構築に絞って解説しよう。ただ、
  http://cr.yp.to/publicfile/install.html を見ても分かるように、httpdサー
  バの設定も同一の手順で完了しているので、興味があれば publicfile httpd
  の動作環境設定もしてみるとおもしろいだろう。

  ftpサーバ環境の構築は /usr/local/publicfile/bin ディレクトリにある 
  configure コマンドで簡単におこなえる。configure コマンドは以下の書式で
  利用する。

/usr/local/publicfile/bin/configure     

  各引数の意味は以下のようになっている。

			デーモンを走らせるアカウント(このアカウントの
			UID/GID でプロセスが走る)
		ログファイルの所有者となるアカウント(関連プロセ
			スmultilogがこのアカウントのUID/GIDで走る)
			ftpd, httpd で公開するファイルを含むトップディレ
			クトリ(configureコマンドが中味を適切に作ってくれ
			る)
			サーバとなるホスト名
			同IPアドレス

  例として

	アカウント		aftp
	ログアカウント		aftplog
	公開ディレクトリ	/opt/public
	ホスト名		ftp.uu.ymzk.org
	IPアドレス		10.0.0.21

  というパラメータで anonymous ftp サーバを建てるものとしよう。

  1. アカウントの作成

     まずデーモン走行用のアカウント aftp を作成する。ここでは、このアカ
     ウントの所属グループを aftp としてみた。

	(Solaris2, Linux, NetBSD, OpenBSDの場合)
	# groupadd aftp
	# useradd -s /bin/noshell -d /opt/public/ftpd -g aftp aftp
	(FreeBSDの場合)
	# pw useradd aftp -s /noshell -d /opt/public/ftpd

     続いてログ用アカウント aftplog を作成する

	(Solaris2, Linux, NetBSD, OpenBSDの場合)
	# groupadd aftplog
	# useradd -s /bin/noshell -d /opt/public/ftpd/log -g aftplog aftplog
	(FreeBSDの場合)
	# pw useradd aftplog -s /noshell -d /opt/public/ftpd/log

  2. 公開ディレクトリの準備

     今回の例では /opt/public をトップディレクトリとする。ただし、このディ
     レクトリの内容は publicfile 付属のconfigureコマンドが作成してくれる
     ので、管理者は /opt/public ディレクトリを用意する必要はない。という
     よりもむしろ、既に存在するとconfigureコマンドが上書きを回避するため
     になにもせずに終了するので、mkdirすらもしないでおく。

  3. configureコマンドの起動

     サービス用ディレクトリを作成する。

	# /usr/local/publicfile/bin/configure \
		aftp aftplog /opt/public ftp.uu.ymzk.org 10.0.0.21

     これにより、/opt/public ディレクトリが【画面 へ】のような内容で作成
     される。
【画面 へ】------------------------------------------------------------
ftp# ls -lF /opt/public
total 3
drwxr-sr-x  3 root  wheel  512 Jul 28 18:08 file/
drwx--S--T  3 root  wheel  512 Jul 28 18:08 ftpd/
drwx--S--T  3 root  wheel  512 Jul 28 18:08 httpd/

ftp# ls -lF /opt/public/file
total 1
drwxr-sr-x  2 root  wheel  512 Jul 28 18:08 0/
lrwxr-xr-x  1 root  wheel    1 Jul 28 18:08 10.0.0.21@ -> 0
lrwxr-xr-x  1 root  wheel    1 Jul 28 18:08 ftp.uu.ymzk.org@ -> 0

ftp# ls -lF /opt/public/ftpd
total 2
drwxr-sr-x  3 root  wheel  512 Jul 28 18:08 log/
-rwxr-xr-x  1 root  wheel  166 Jul 28 18:08 run*

ftp# ls -lF /opt/pf/httpd
total 2
drwxr-sr-x  3 root  wheel  512 Jul 28 18:08 log/
-rwxr-xr-x  1 root  wheel  142 Jul 28 18:08 run*
----------------------------------------------------------------------

  4. サービス起動

     /service ディレクトリにシンボリックリンクを張ることで自動的にftpdが
     起動される。

	# ln -s /opt/public/ftpd /service

     数秒待って、localhost にftp接続してみよう。

	# ftp localhost
	Connected to localhost.
	220 Features: a p .
	Name (localhost:yuuji): 

     publicfile ftpd はanonymous専用ftpデーモンなので、ログイン名のとこ
     ろは何を入れても anonymous login できる。

	Name (localhost:yuuji): hoge
				~~~~
	230 Hi. No need to log in; I'm an anonymous ftp server.
	Remote system type is UNIX.
	Using binary mode to transfer files.
	ftp> 

  ●publicfile ftpd 用のコンテンツ配置

  publicfile configure コマンドによって生成されたディレクトリのうち、
  file/ ディレクトリがコンテンツを置くためのディレクトリである。あらかじ
  めこのディレクトリには 0/ というディレクトリができている。publicfile
  ftpd はこのディレクトリを anonymous ftp login ユーザのログインディレク
  トリとする。ここにファイルを置いておけば、利用者にファイルを見せること
  ができる。また、ログインユーザと結びついたプロセスはこのディレクトリに
  chrootする。

  ちなみに、同ディレクトリににある IP アドレスと、ホスト名のディレクトリ
  は publicfile httpd で利用される。こちらはたとえば 
  http://host/index.html というリクエストがあった場合、
  file/host/index.html ファイルを返すようになっている。HTTP の
  virtualhost を利用したコンテンツ切り替えはディレクトリ名に対応させて行
  なうようになっている。デフォルトでは、file/10.0.0.21,
  file/ftp.uu.ymzk.org ともに file/0 へのシンボリックリンクとなっている
  ので、anonymous ftp サーバで公開する内容と同じディレクトリを指すように
  なっている。


yuuji@gentei.org
Fingerprint16 = FF F9 FF CC E0 FE 5C F7 19 97 28 24 EC 5D 39 BA
HIROSE Yuuji - ASTROLOGY / BIKE / EPO / GUEST BOOK / YaTeX [Tweet]