HTTPdによる認証

この章ではホームページにアクセスできる人を限定する方法を概説します。 CGIでもこれらのことを実現するように設計することはできますが、 HTTPdにはもとから簡単にこれらのことを実現できるようにするための 機能がついてます。
ここでの話はNCSAのhttpdもしくはapache向けの話です。 .htaccess ファイルにいろいろ記述してアクセスを制限します。 .htaccessファイルがあるディレクトリ以下すべてのファイルが その制限の対象となります。

■ 特定のホストからのアクセスを許す。

例えば.htaccessファイルに下記のように記述します。
<LIMIT GET>
order deny,allow
deny from all
allow from .phys.s.u-tokyo.ac.jp
</LIMIT>
こうすると、ホスト名の後側が ".phys.s.u-tokyo.ac.jp" である ホストからのアクセスのみが許され、それ以外のホストからの アクセスはすべて禁じられます。

ホストの指定方法には次の8種があります。

すべてのホストを対象にする。

allow from all

特定の一つのホストのホスト名を指定する。

allow from host.phys.s.u-tokyo.ac.jp

ある一つのドメイン名に属する全てのホストを指定する。

allow from .phys.s.u-tokyo.ac.jp

特定の一つのホストのIPを指定する。

allow from 133.11.1.1

IPアドレスの上位バイトが共通するサブネットの全てのホストを指定する。

allow from 133.11.1.

IPアドレスの上位ビットが共通するサブネットの全てのホストを指定する。

allow from 133.11.1.0/26
この例ではクライアントのIPの上位26ビットが 指定のIP 133.11.1.0 に等しいホストが対象になる。つまり 133.11.1.1 -- 133.11.1.63が対象になる。

IPアドレスのネットマスク部分が共通する全てのホストを指定する。

allow from 133.11.1.0/255.255.255.192
この例では255, 192は2進表記でそれぞれ 11111111, 11000000 なので これとクライアントのIPとの論理和をとると、 クライアントのIPの上位3バイトはそのまま残り、下位1バイトは その上位2ビットの値のみが残る。その残った値が 133.11.1.0 に等しいホストが対象になる。つまり 133.11.1.1 -- 133.11.1.63が対象になる。

複数の種類のホストを指定する。

allow from hostA.phys.s.u-tokyo.ac.jp hostB.phys.s.u-tokyo.ac.jp
IPによる指定やドメイン、サブネット、ネットマスクの指定も同様。

■ 特定のホストからのアクセスを禁ずる。

例えば.htaccessファイルに下記のように記述します。
<LIMIT GET>
order allow,deny
allow from all
deny from .ecc.u-tokyo.ac.jp
</LIMIT>
こうすると、ホスト名の後側が ".ecc.u-tokyo.ac.jp" である ホストからのアクセスが禁じられ、それ以外のホストからの アクセスはすべて許されます。

IPによる指定やドメイン、サブネット、ネットマスクの指定も allowの場合と同じです。

■ 特定の個人のアクセスを許す。

まず、アクセスを許可する人々のハンドル名(ユーザー名)と パスワードを決めて紙に書き留めて下さい。

パスワードを暗号化します。暗号化にはcrypt()関数を用います。

puts( crypt( password, salt ) );
ここで password は生のパスワードの文字列、saltは暗号化の度合を 定めるちょっとしたおまじないの文字列で、アルファベットや数字を ランダムに選んだ8文字の文字列を与えます。crypt()関数は暗号化された 文字列が格納されている配列のアドレスを返しますので、それを 適当に表示します。このプログラムについては後でもう少し詳しく 解説します。

ハンドル名と暗号化パスワードのリストを保存するファイルを用意します。 ファイルの置き場所としてはpublic_html/ディレクトリとは異なる webからアクセスできない所が好ましいです。 ファイル名は例えば .htpasswdとしましょう。 それにハンドル名と暗号化パスワードを対にして書き込みます。

naoki:$1$RVaJ$Vet0CrteDb9f/R1vX8b0l0
このファイル中の行頭が#の行はコメント扱いになります。 このファイルのpermissionをotherに対して読み込み可能に して下さい。groupに対してはアクセス禁止にしましょう。 暗号化されたパスワードは他人に見られても ある程度は大丈夫です。もちろん見られずに済むならそれに 越したことは無いのですが。

.htaccessファイルに次のように記述します。

AuthType Basic
AuthName Secret Pages
AuthUserFile /home/naoki/.htpasswd
<LIMIT GET>
require valid-user
</LIMIT>
AuthType の項目にはこのようにBasicと書いて下さい。
AuthName の項目にはこのアクセス制限をすることを表す適当な文字列を 書いて下さい。
AuthUserFile には先に作成したパスワードファイルのpathを ファイルシステムの絶対ディレクトリで記述して下さい。 webからアクセスできるpublic_html/以下にパスワードファイルを 置いておくと、世界中から丸見えですので別の所に置きましょう。
そしてこのように require valid-user と書いて下さい。

そして、アクセスを許可する人々にパスワードを教えます。 盗聴されないように紙に書いて手渡しするのが安全です。

こうすると、このディレクトリ以下のファイルへアクセスしようとすると、 HTTPdはブラウザに対してパスワードを打ち込むように要求します。 閲覧者がハンドル名とパスワードを入力して、再びファイルへアクセス すると、HTTPdは照合を行って、正しいならファイルを送り返します。
以後、このディレクトリ以下のファイルへのアクセスの際には ブラウザが自動的にパスワードをHTTPdに送るので、再度パスワードを 打ち込む必要はありません。

AuthTypeをBasicとしたこの方法では、閲覧者が打ち込んだパスワードは 特に暗号化されずにネットワーク上を流れるので、あまり安全では ありません。商業機密や軍事機密を扱う場合には、この方法を用いては なりません。もっと安全な方法もありますが筆者はそれに詳しくありません。

入力されたハンドル名はCGIで環境変数 REMOTE_USER で参照できます。

■ パスワードを暗号化するプログラム

apache付属のhtpasswdというプログラムがapacheのsrcディレクトリの 隣のsupportディレクトリにありますので、それを使ってパスワードを 暗号化することができますが、パスワードの暗号化は単にcrypt()関数を 使うだけなので、そのプログラムは自分でも簡単に作ることができます。

encrypt.cc

UNIXの種類によっては crypt()関数のprototypeが unistd.h で宣言されて いないかもしれません。その場合にはこのプログラム冒頭で次のように 宣言して下さい。

extern "C" char* crypt( const char*, const char* );
コンパイルの際には -lcrypt オプションをつけて下さい。

ちなみに、パスワードを照合するには次のようにします。

if( !strcmp( encrypt, crypt( passwd, encrypt ) ) ){
  // あたり
}
ここで passwd は打ち込まれたパスワードで encryptは暗号化されたパスワードです。


目次

Copyright(C) by Naoki Watanabe. Oct 21st, 1995.
渡辺尚貴 naoki@cms.phys.s.u-tokyo.ac.jp