Node: The Password-Authenticating Server, Next: , Previous: Starting A Repository, Up: Repository Administration



The Password-Authenticating Server

パスワードサーバのセットアップに必要な手順を実行する前に、このような接 続がどのように動いているのか大雑把に見ておきましょう。リモートの CVS クライアントが :pserver: メソッドを使ってリポジトリに接続すると き、クライアントは実際にはサーバマシンの特定のポート番号、明確に言うと 2401 番(49の2乗と言ってもいいです、そういうのがお好きなら)に接続しに行き ます。2401番ポートは CVS pserver 用に指定されたデフォルトポートですが、 クライアントとサーバの共通了解さえあれば別のポートに設定することも可能 です。

CVS サーバはそのポートで接続をずっと待っているわけではなく、実際に接続 要求があるまで起動されません。かわりに Unix の inted (InterNET Daemon) プログラムがそのポートを listen しています。接続要求を受け取ったときに どうするかを教えておく必要がありますが、そうすると inetd が CVS サーバ を起動して、入って来たクライアントと接続してくれます。

これを実現するには inetd の設定ファイル、/etc/services/etc/inetd.conf を変更します。services ファイルは生のポート番号とサー ビス名を対応づけ、inetd.conf には inetd が各サービス名に対して何をすれ ばよいかを書いてあります。

まず /etc/services に次の1行を追加して下さい(この行がファイルにないこ とを確認してからですよ)

     cvspserver	2401/tcp
     

次に /etc/inetd.conf にこれを追加してください:

     cvspserver stream tcp nowait root /usr/local/bin/cvs cvs \
        --allow-root=/usr/local/newrepos pserver
     

(上記は実際のファイルではバックスラッシュなしの1つの長い行にしてくださ い) ただし、tcpwrapper が導入されたシステムにおいては次のようにしてく ださい:

     cvspserver stream tcp nowait root /usr/sbin/tcpd /usr/local/bin/cvs \
        --allow-root=/usr/local/newrepos pserver
     

inetd を再起動して、設定ファイルの変更を反映して下さい。(inetd の再起 動の仕方を知らない場合はマシンをリブートしてください、それで動くように なります)

接続を許可するためにはこれだけでいいのですが、ユーザの通常のログインパ スワードとは別に、CVS 用のパスワードを設定したいでしょう。そうすればシ ステム全体のセキュリティについて妥協することなくリポジトリにアクセスさ せることができるようになります。

リポジトリ内の CVSROOT/passwd が CVS のパスワードファイルです。このフ ァイルは cvs init を実行したときにデフォルトで生成されたりはしません。 CVS を pserver で提供するとは限らないからです。パスワードファイルが生 成されたとしても、CVS ではユーザ名とパスワードを生成できません。自分で 作る必要があります。CVSROOT/passwd ファイルのサンプルを示します:

     kfogel:rKa5jzULzmhOo
     anonymous:XR4EZcEs0szik
     melissa:tGX1fS8sun6rY:pubcvs
     

フォーマットはご覧の通りごく簡単です。各行次のようにしてください:

     <USERNAME>:<ENCRYPTED_PASSWORD>:<OPTIONAL_SYSTEM_USERNAME>
     

余分にコロンとオプショナルシステムユーザ名をつけると、CVS は USERNAME として認証した接続を SYSTEM_USERNAME というシステムアカウントの権限で 実行します。言い換えると そのセッションでは SYSTEM_USERNAME としてログ インしたときと同様のことがリポジトリ内で実行できる、ということです。

システムユーザ名が指定されていない場合、USERNAME はシステム上に実際に 存在するログインアカウントと一致しなければならず、セッションはそのユー ザの権限で実行されます。どちらの場合でも、ENCRYPTED_PASSWORD はシステ ムの実際のログインパスワードと一致しなくても構いません。それは CVS の pserver 接続にのみ用いられる、他と関係ないパスワードです。

パスワードは /etc/passwd にパスワードを保存するときに使われているのと 同じアルゴリズムで暗号化されます。ここで「どうやって暗号化したパスワー ドを持ってくればいいの?」という疑問が出てきます。Unix のシステムパスワー ドなら、passwd コマンドが /etc/passwd の暗号化を面倒見てくれます。しか し、それに対応するような cvs passwd コマンドはありません(これは何度か 提案されていますが、まだ誰も書いていないんですよ。あなたがやってくれま すか?)。

不便でしょうもない方法がひとつあります。他にどうしようもなければ、通常 のシステムパスワードを passwd コマンドで変えて、暗号化されたものを /etc/passwd から CVSROOT/passwd へカットアンドペーストし、元のパスワード に戻す、というのでなんとかなります(暗号化されたパスワードが /etc/shadows にあって、root 権限がないと読めない場合もあります)。

この方法はしかしかなり厄介です。暗号化されていないパスワードを引数で渡 せば暗号化されたものを出力してくれるような、コマンドラインユーティリテ ィを作るほうが簡単でしょう。Perl で書いたそういうツールをお見せしまし ょう:

     #!/usr/bin/perl
     
     srand (time());
     my $randletter = "(int (rand (26)) + (int (rand (1) + .5) % 2 ? 65 : 97))";
     my $salt = sprintf ("%c%c", eval $randletter, eval $randletter);
     my $plaintext = shift;
     my $crypttext = crypt ($plaintext, $salt);
     
     print "${crypttext}\n";
     

わたしはこのスクリプトを /usr/local/bin/cryptout.pl に置いてい ます。

     floss$ ls -l /usr/local/bin/cryptout.pl
     
     -rwxr-xr-x   1   root   root   265  Jun 14 20:41 /usr/local/bin/cryptout.pl
     floss$ cryptout.pl "some text"
     sB3A79YDX5L4s
     
     floss$
     

この例の出力を CVSROOT/passwd のエントリ作成に使ったとします:

     jrandom:sB3A79YDX5L4s:craig
     

で、誰かが次のコマンドを使ってリポジトリに接続するとすると:

     remote$ cvs -d :pserver:jrandom@floss.red-bean.com:/usr/local/newrepos login
     

ここでパスワードに some text とタイプすれば、以降は craig のアクセス権限で CVS コマンドを実行することができます。

CVSROOT/passwd にないユーザ名とパスワードでログインしようとした場合、 CVS は /etc/passwd のユーザ名とパスワードをチェックします。もし存在す れば(そして当然ですがパスワードが一致すれば)、CVS はアクセスを許可しま す。この振舞いは管理者の便宜のため、つまり通常のシステムユーザの分まで いちいち CVSROOT/passwd のエントリを設定しなくてもよいようにするための ものです。しかしこれはセキュリティホールにもなります。なぜなら、そのよ うなユーザが CVS に接続しようとすると、通常のログインパスワードが暗号 化されずにネットワーク上に流れてしまい、パスワード盗み屋に見られてしま うかもしれないからです。このあとでこの「fallback」な振舞いを無効にする 方法を述べます。有効にするにしろ無効にするにしろ、ログインアカウントも 持っている CVS ユーザに対しては、それぞれを違うパスワードにするように、 おそらく強制すべきです。

passwd ファイルでの認証はリポジトリ全体に対して有効なのですが、少し工 夫すればプロジェクトごとのアクセス許可を設定するために使用することもで きます。一方法を示します:

次のように仮定します。リモートの開発者にプロジェクト foo へのア クセスを許可し、また別のリモートの開発者にプロジェクト bar への アクセスを許可するが、一方のプロジェクトの開発者には、もう一方のプロジ ェクトにコミットさせたくない。この場合、プロジェクト別のユーザアカウン トとグループをシステム上に作成し、CVSROOT/passwd ファイルで対応させる ことによって実現できます。

/etc/passwd から関連部分の抜粋:

     cvs-foo:*:600:600:Public CVS Account for Project Foo:/usr/local/cvs:/bin/false
     cvs-bar:*:601:601:Public CVS Account for Project Bar:/usr/local/cvs:/bin/false
     

/etc/group からの抜粋:

     cvs-foo:*:600:cvs-foo
     cvs-bar:*:601:cvs-bar
     

最後に CVSROOT/passwd からの抜粋です:

     kcunderh:rKa5jzULzmhOo:cvs-foo
     jmankoff:tGX1fS8sun6rY:cvs-foo
     brebard:cAXVPNZN6uFH2:cvs-foo
     xwang:qp5lsf7nzRzfs:cvs-foo
     dstone:JDNNF6HeX/yLw:cvs-bar
     twp:glUHEM8KhcbO6:cvs-bar
     ffranklin:cG6/6yXbS9BHI:cvs-bar
     yyang:YoEqcCeCUq1vQ:cvs-bar
     

CVS ユーザ名のうちいくつかはシステムユーザアカウント cvs-foo と 対応しており、いくつかは cvs-bar に対応しています。CVS はシステ ムアカウントのユーザIDの権限で動作しますので、リポジトリのうち関連する 部分には適切なユーザとグループの書込み権限を与えておいて下さい。ユーザ アカウントをきちんとロックしておけば(ログインパスワードを無効にし、シ ェルには /bin/false を設定)、このシステムは十分セキュアです(こ の章で後ほど述べる CVSROOT のパーミッションについて読んでおいて下さい ね!)。また、CVS ではレコードやログメッセージの変更をシステムユーザ名で はなく CVS ユーザ名で行うので、ある変更が誰の責任なのかというのもわか ります。