httpd, Apache HTTP サーバ

Apache HTTP Server は 「非常にいろいろなことをしてくれる」 ネットワークサーバ でSubversionの機能も上げることができます。カスタムモジュールを使って httpdはSubversion リポジトリをWebDAV/DeltaVプロトコル 経由でクライアントから利用可能にします。WebDAV/deltaVプロトコルは HTTP 1.1 の拡張です(http://www.webdav.org/ により詳しい情報が あります)。このプロトコルはワールドワイドウェブの核心である、 広く利用可能なHTTP プロトコルに対して、書き込み—特にバージョン化された 書き込み—機能を付け加えます。結果は標準化された、堅牢なシステム を構成することができ、それは Apache 2.0 の一部としてパッケージ化されて います。また Apache 2.0 はさまざまなオペレーティングシステムとサード パーティー性製品によってサポートされており、それを利用すればネットワーク 管理者は新たなカスタムポートを開く必要がありません。 [25] Apache-Subversion サーバはsvnserveよりも多くの 機能を持っていますが、セットアップは少し難しくなります。柔軟性には しばしば複雑さがともなうものです。

以下の議論の多くはApacheの設定ディレクティブへの参照を含んでいます。 いくつかの例はそのようなディレクティブの利用方法になっていますが、 その完全な説明はこの章の範囲外です。Apache チームは非常にすばらしい ドキュメントを管理していてhttp://httpd.apache.org から自由に参照可能です。たとえば設定ディレクティブの一般的な リファレンスはhttp://httpd.apache.org/docs-2.0/mod/directives.html にあります。

また、Apache の設定を変更する場合、しばしば間違いが起こります。 Apache のログシステムにまだなじみがないのであれば、それに注意すると 良いでしょう。httpd.confファイルにはApache に よって生成されるアクセスログとエラーログのディスク上での場所を指定する ディレクティブがあります。(それぞれCustomLogErrorLogという名前です)。Subversion の mod_dav_svn も Apache のエラーログインターフェースを利用しています。これらのファイルは 情報取得のために常に閲覧することができ、ほかの方法でははっきりしない 問題の原因を明らかにするかも知れません。

必須要件

HTTP 越しにリポジトリにアクセスする場合、基本的には二つのパッケージで利用 可能な四つの部品が必要になります。Apache httpd 2.0、 それに付属しているmod_dav DAVモジュール、Subversion、 そしてそれに付属しているmod_dav_svnファイルシステム 提供モジュールです。すべての部品を手に入れてしまえばリポジトリのネットワーク 対応は以下のように簡単です:

  • httpd 2.0 を起動し、mod_dav モジュール付きで実行する。

  • mod_dav_svn プラグインを mod_dav にインストールする。mod_dav_svn はリポジトリにアクセスするために Subversion のライブラリを利用 します。そして、

  • httpd.confファイルを設定してリポジトリを 公開する。

最初の二つについてはhttpdとSubversion を ソースコードからコンパイルするか、自分のシステム用の既にコンパイル 済みのバイナリパッケージをインストールすることによって取得できます。 どのようにして Apache HTTP サーバと共に Subversion をコンパイルするか、 そしてこの目的のために Apache 自身をどのように設定すれば良いかに ついての最新情報は Subversion ソースコードツリーの最上位にある INSTALLファイルを参照してください。

基本的な Apache の設定

システム上に必要なすべての部品をインストールしたあとは、httpd.conf によって Apache の設定をすることだけが残っています。 LoadModule ディレクティブを使って mod_dav_svn モジュールを Apache にロードしてください。この ディレクティブはほかの Subversion 関連の設定項目に先立って指定しなくてはなりません。 Apache がデフォルトレイアウトを使ってインストールされているなら、mod_dav_svn モジュールは Apache インストールディレクトリのmodulesサブディレクトリ 中になければなりません(たいていの場合、/usr/local/apache2の ようなディレクトリになります)。LoadModuleディレクティブは単純な 構文を持ち、名前の付いたモジュールをディスク上の共有ライブラリの場所に対応付けます:

LoadModule dav_svn_module     modules/mod_dav_svn.so

mod_davが ( httpdプログラムに直接静的にリンクされるのではなく) 共有オブジェクトとしてコンパイルされた場合、それに対しても同様の LoadModule行が必要になります。 mod_dav_svn 行の前に設定することに注意してください:

LoadModule dav_module         modules/mod_dav.so
LoadModule dav_svn_module     modules/mod_dav_svn.so

次に、設定ファイルの後の場所のどこかで Subversion リポジトリをどこに 置くかを Apache に伝える必要があります。Location ディレクティブは XML風の記述で、開始タグで始まり、終了タグで終わる間 にさまざまなほかの設定ディレクティブを書きます。 Locationディレクティブの目的は Apache に、指定した URL かそのサブディレクトリである特定の処理をするように指示するためにあります。 Subversion の場合、DAV層で管理するバージョン化された資源のある URL で 処理を単に引き渡すように Apache に指示するだけです。Apache に対して /repos/で始まる部分(つまり、URL のサーバ名と 場合によって付随するポート番号文字列の後に続く部分)を持ったすべての URL について、/absolute/path/to/repositoryにある リポジトリを管理する DAV 提供モジュールに引き渡すように指示することが できます。それには以下のようなhttpd.conf構文を使い ます:

<Location /repos>
  DAV svn
  SVNPath /absolute/path/to/repository
</Location>

ローカルディスク上の同じ親ディレクトリにある複数の Subversion リポジトリ を提供する計画がある場合は、別のディレクティブ、 SVNParentPath を使って共通の親ディレクトリを示すこともできます。たとえばhttp://my.server.com/svn/repos1とか、 http://my.server.com/svn/repos2のような URL を経由してアクセスされる/usr/local/svnディレクトリ 中に複数の Subversion リポジトリを作る場合であれば、以下の例の中にある httpd.confの設定構文を使うことができます:

<Location /svn>
  DAV svn

  # any "/svn/foo" URL will map to a repository /usr/local/svn/foo
  SVNParentPath /usr/local/svn
</Location>

この構文を使うと Apache は/svn/で始まるパス部分 を持つすべての URL を Subversion DAV モジュールに渡しますが、すると このモジュールはSVNParentPathによって指定される ディレクトリ中のすべてのアイテムは実際のSubversion リポジトリであると 仮定します。これはSVNPathディレクティブを利用 するのとは違って新しいネットワーク公開用リポジトリを作るたびに Apache を再起動する必要がないのでとても便利です。

新しいLocationを定義する場合は、他の公開された Location と重ならないように注意してください。たとえばメインの DocumentRoot/wwwに 設定されている場合、Subversion リポジトリを<Location /www/repos>の中で公開しないでください。 URI /www/repos/foo.cが要求されても Apache は DocumentRoot中にあるrepos/foo.c を探せば良いのか、Subversion リポジトリから foo.c を返すためにmod_dav_svnに取り次げば良いのか 判断できなくなります。

この時点で、パーミッションがどうなるかというについて十分考慮する ことが必要になります。Apache をある程度の期間にわたって通常利用する Webサーバとしてきた場合、おそらく既にいろいろなコンテンツがある ことでしょう—ウェブページ、スクリプト、などなど。これらの アイテムは既に Apache と協調動作するようなパーミッションの組が設定 されている、あるいはもっと正確には、Apache にそのようなファイルを 扱うことを許可する設定になっています。Subversion サーバとして Apache が利用される場合も、Subversion リポジトリに対して正しい 読み書きのパーミッションを設定する必要があります。(詳しくは サーバとパーミッション: 留意点を見てください)。

既に存在しているウェブページやスクリプトの設定に問題を起こさない ように Subversion の要求を満足させるためのパーミッションを決定しなくて なりません。これは Subversion リポジトリを、Apache が既に あなたに対して提供しているほかのサービスと協調するようなパーミッション に変更するか、あるいはhttpd.confの中で UserGroupディレクティブを 使ってSubversion リポジトリを所有しているユーザ・グループで Apache が実行されるべき状態に変更することを意味します。 このための唯一の正しい解法といったものはありませんし、個々の 管理者は正しいやり方をするための異なる理由を持っているはずです。 パーミッションに関連した問題はおそらく Apache を利用した Subversion リポジトリの設定時に一番よく見落とされることであるのに注意してください。

認証オプション

この時点で httpd.confを以下のような 感じで設定している場合

<Location /svn>
  DAV svn
  SVNParentPath /usr/local/svn
</Location>

あなたのリポジトリは「匿名で」 世界中からアクセス可能となります。何らかの 認証と認可の仕組みを設定するまで、あなたの作ったSubversion リポジトリは Locationディレクティブによって一般的に誰からも アクセスすることができてしまいます。言い換えると、

  • 誰でもリポジトリ URL(とその任意のサブディレクトリ) の作業コピーをチェックアウト するために Subversion クライアントを利用することができます,

  • 誰でもリポジトリ URL をブラウザで指定することによってリポジトリの最新 リビジョンを閲覧することができます。そして

  • 誰でもそのリポジトリにコミットすることができます。

基本 HTTP 認証

クライアントを認証する一番簡単な方法は HTTP の基本認証の仕組みを使うことで、 それは単純にユーザ名とパスワードを使って、ある人間が自分がその当人である と言っているのを確認します。Apache はhtpasswdユーティリティー を用意して、受け入れることのできるユーザ名とパスワードの一覧を管理 しますが、その人たちにだけあなたの Subversion リポジトリにアクセスする権利を 与えることができます。 Sarry と Harry にだけコミット権限を与えてみましょう。 まず彼らをパスワードファイルに追加する必要があります。

$ ### First time: use -c to create the file
$ ### Use -m to use MD5 encryption of the password, which is more secure
$ htpasswd -cm /etc/svn-auth-file harry
New password: ***** 
Re-type new password: *****
Adding password for user harry
$ htpasswd -m /etc/svn-auth-file sally
New password: *******
Re-type new password: *******
Adding password for user sally
$

次に新しいパスワードファイルを何に利用するかというのを Apache に伝える ため、 Locationブロック内部で追加の httpd.conf ディレクティブが必要になります。 AuthTypeディレクティブは 利用する認証システムのタイプを指定します。今回はBasic 認証システムを指定したいと思います。AuthNameは 任意の名前で認証ドメインを与えるためのものです。ほとんどのブラウザは ユーザに名前とパスワードを問い合わせるときにこの名前をポップアップダイアログ ボックス中に表示します。最後にAuthUserFileディレクティブは htpasswdで作ったパスワードファイルの場所を指定します。

三つのディレクティブを追加した後では、あなたの <Location> ブロックは以下のような感じになっていることでしょう:

<Location /svn>
  DAV svn
  SVNParentPath /usr/local/svn
  AuthType Basic
  AuthName "Subversion repository"
  AuthUserFile /etc/svn-auth-file
</Location>

この <Location> ブロックはまだ完成しておらず 役に立つことは何もしません。単に Apache に対して、認証が要求されるとき には常にSubversion クライアントからユーザ名とパスワードを取得するように 言うだけです。しかしここで欠けているのは Apache に対してどのような 種類のクライアント要求が認証で必要とされるのかを言うための ディレクティブです。これをやるのに最も簡単な方法はすべてのリクエストを保護 するこです。Require valid-user の追加は Apache に対して すべてのリクエストは認証されたユーザであることを伝えます:

<Location /svn>
  DAV svn
  SVNParentPath /usr/local/svn
  AuthType Basic
  AuthName "Subversion repository"
  AuthUserFile /etc/svn-auth-file
  Require valid-user
</Location>

認可のポリシーを設定する Requireディレクティブと、その他の方法についての 詳細については次の節(認可のオプション項) を読んでください。

一点注意があります: HTTP の基本認証パスワードはほとんど平文のままネットワーク を流れるため、セキュリティー上は非常に弱いものです。もしパスワードの 盗聴が心配なら、SSL 暗号化のような仕組みを使うのが最良でしょう。これで クライアント認証はhttp://のかわりに https://を使って認証することになります; 最低限度の 処置として Apache に自己サイン付きサーバ証明書を設定することができます。 [26] どうすれば良いかについては Apache のドキュメント(と、OpenSSL の ドキュメント)を見てください。

SSL 証明書の管理

リポジトリを自社ファイアウォールの外にさらす必要のあるビジネス は認可されていない他人が自分たちのネットワークデータを「盗聴」 しているかも知れないということを意識すべきです。 SSL はこの手の望ましくない意図が重要なデータの流出に帰結する可能性を 小さなものにします。

Subversion クライアントが OpenSSL を使ってコンパイルされた場合、https:// URL を使って Apache サーバと通信する能力を得ます。Subversion クライアントで 利用される Neon ライブラリはサーバ証明書を検証することができるだけ ではなく、確認要求を受けた場合には自分の証明書を提示する能力も持って います。クライアントとサーバが SSL 証明書を交換しお互いの認証に成功 すれば、その後のすべての通信はセッションキーによって暗号化されます。

どのようにしてクライアントとサーバ証明書を生成するか、またその証明書を 利用するようにどうやって Apache を設定するかについてはこの本の範囲外です。 Apache 自身のドキュメントを含め、さまざまな本でこの方法を説明しています。 ここでは通常の Subversion クライアントでのサーバとクライアント証明書を どのように管理するかについて説明します。

https://経由で Apache と通信する場合、Subversion クライアントは二つの異なるタイプの情報を受け取ることができます:

  • サーバ証明書

  • クライアント証明書の提示要求

クライアントがサーバ証明書を受け取った場合、それが信頼できるものであるか どうかの検証が必要になります: サーバは本当に名乗っているそのサーバなの でしょうか? OpenSSL ライブラリはサーバ証明書にサインした者、あるいは 認証期間 (CA)を調べることでこれを確認します。もし OpenSSL が自動的に CA を信用することができないか、他の問題が起きた 場合(たとえば、証明書の有効期間が過ぎていたり、ホスト名が一致していない 場合など)、Subversion コマンドラインクライアントはそのサーバ証明書を とにかく信用するかどうかをユーザに聞いてきます:

$ svn list https://host.example.com/repos/project

Error validating server certificate for 'https://host.example.com:443':
 - The certificate is not issued by a trusted authority. Use the
   fingerprint to validate the certificate manually!
Certificate information:
 - Hostname: host.example.com
 - Valid: from Jan 30 19:23:56 2004 GMT until Jan 30 19:23:56 2006 GMT
 - Issuer: CA, example.com, Sometown, California, US
 - Fingerprint: 7d:e1:a9:34:33:39:ba:6a:e9:a5:c4:22:98:7b:76:5c:92:a0:9c:7b

(R)eject, accept (t)emporarily or accept (p)ermanently?

このダイアログはなじみ深いものだと思います; 本質的にはウェブブラウザで 見ることのできるのと同じ質問になっています(ブラウザは Subversion と 同じような HTTP クライアントの一種なんです!)。もし (p)ermanent、常に信用 する、というオプションを選ぶと、サーバはあなたのユーザ名とパスワードを キャッシュしたのとちょうど同じ方法であなたの実行時auth/ 領域にそのサーバ証明書をキャッシュします。(クライアント証明のキャッシュ項 を参照してください)。キャッシュされてしまえば、Subversion はそれ以降の やり取りについては自動的にこの証明書を信用します。

実行時serversファイルもSubversion クライアントが自動的に 特定の CA を信頼するように設定することができます。すべてのものについて そうすることもできますし、ホストごとにすることもできます。 単にssl-authority-filesを、 PEM で暗号化された CA 証明書をセミコロンで区切ったリストに設定してください:

[global]
ssl-authority-files = /path/to/CAcert1.pem;/path/to/CAcert2.pem

多くの OpenSSL の設定ではほとんど無制限に信頼する 「default」 CA が、あらかじめ設定されています。Subversion クライアントにそのような 標準的な認証機関を信用させるためにはssl-trust-default-ca 変数をtrueに設定してください。

Apache と通信する際、Subversion クライアントはクライアント証明書の 確認要求を受けるかも知れません。Apache はクライアントに対して自分自身を 証明するようにたずねます: あんたは本当にあんたなのか? もしすべてが正し ければ Subversion クライアントはApache が信用している CA によってサイン されたプライベート証明書を送り返します。クライアント証明書は通常 暗号化された形式でディスク中に保管され、ローカルパスワードによって 保護されています。Subversion がこの確認要求を受けた場合、あなたは 証明書のパスと、それを保護しているパスワードについて聞かれます:

$ svn list https://host.example.com/repos/project

Authentication realm: https://host.example.com:443
Client certificate filename: /path/to/my/cert.p12
Passphrase for '/path/to/my/cert.p12':  ********
…

クライアント証明書は 「p12」形式のファイル であることに注意してください。クライアント証明書を Subversion で利用する場合、それは標準的な PKCS#12 フォーマットでなければなりません。 ほとんどのウェブブラウザは既にその形式の証明書をインポートしたり エクスポートしたりすることができます。他の方法としては既存の証明書 をOpenSSLのコマンドラインツールによってPKCS#12形式に変換するという ものです:

ここでも実行時serversファイルはホスト単位で この確認要求を自動化することを認めています。そのような情報は 実行時変数で指定できます:

[groups]
examplehost = host.example.com

[examplehost]
ssl-client-cert-file = /path/to/my/cert.p12
ssl-client-cert-password = somepassword

いったんssl-client-cert-filessl-client-cert-password変数を 設定すれば、Subversion クライアントはユーザに問い合わせることなしに 自動的にクライアント証明書の確認要求に応答することができるようになります。 [27]

認可のオプション

ここまでのところで、すでに認証についての設定は完了しました が認可はまだです。Apache はクライアントを試し、本当のクライアン トであることを確認することができますが、これらの認証済みクライアントそれ ぞれにどのようなアクセスを許し、また制限するかについてはまだ説明 していません。この節ではリポジトリに対してアクセス制御するための 二つの方法について説明します。

全面的なアクセス制御

アクセス制御の一番簡単な方法は特定のユーザをリポジトリに対して読み出し 専用、あるいは読み書き可能として認可することです。

<Location>ブロックにRequire valid-user ディレクティブを追加することによってすべてのリポジトリ操作にアクセス制限を 設けることができます。前の例を使うと、これはharrysally、あるいはユーザごとの正しいパスワードを入力した 人だけに、Subversion リポジトリに対する任意の操作を許すというものです:

<Location /svn>
  DAV svn
  SVNParentPath /usr/local/svn

  # how to authenticate a user
  AuthType Basic
  AuthName "Subversion repository"
  AuthUserFile /path/to/users/file
  
  # only authenticated users may access the repository
  Require valid-user
</Location>

しばしばそのような厳しい設定は不要です。たとえば Subversion 自身の ソースコードリポジトリはhttp://svn.collab.net/repos/svn にありますが、世界中の誰でも読み出しアクセスすることが可能です( それはチェックアウトしたり、ウェブブラウザでリポジトリを閲覧する ような操作です)が、書き込み操作は認証されたユーザにのみ許されています。 この手の制限を付与するには LimitLimitExcept設定ディレクティブを使うことができます。 Locationディレクティブのように、この二つの ブロックは開始タグと終了タグがあり、 <Location> ブロック中でネストすることができます。

LimitLimitExceptディレクティブ に現れるパラメータは HTTP 要求タイプで、そのブロック全体に影響を 与えます。たとえば、現在サポートされている読み出しのみの操作を 除くすべてのリポジトリアクセスを禁止したい場合、LimitExcept ディレクティブが、GETPROPFINDOPTIONS、そしてREPORT要求タイプ パラメータを渡す形で利用できます。そして既に触れたRequire valid-user ディレクティブを、単に<Location>ブロックの中に 置くかわりに、<LimitExcept>ブロックの中に置く形に なります。

<Location /svn>
  DAV svn
  SVNParentPath /usr/local/svn

  # how to authenticate a user
  AuthType Basic
  AuthName "Subversion repository"
  AuthUserFile /path/to/users/file

  # For any operations other than these, require an authenticated user.
  <LimitExcept GET PROPFIND OPTIONS REPORT>
    Require valid-user
  </LimitExcept>
</Location>

このようなことは単純な例にすぎません。Apache のアクセス制御と Requireディレクティブについてのさらに詳しい情報 はhttp://httpd.apache.org/docs-2.0/misc/tutorials.html にある Apache ドキュメントチュートリアルのSecurity セクションを見てください。

ディレクトリごとのアクセス制御

第二の Apache httpd モジュールである mod_authz_svn を使うと、より詳細なパーミッションの設定が可能です。このモジュールは クライアントからサーバに送信されるさまざまな裸の URL を取得し、 mod_dav_svnにそれを解析するように要求し、設定ファイル で定義されたアクセス方式に基づき必要に応じてアクセスを拒否します。

Subversion をソースコードから構築した場合はmod_authz_svn は自動的にmod_dav_svnのそばにインストールされます。 多くのバイナリ配布でもやはり自動的にインストールします。正しくインストール されているかどうかを確認するにはhttpd.conf にある、mod_dav_svnLoadModule ディレクティブのすぐ後に来ていることを確認してください:

LoadModule dav_module         modules/mod_dav.so
LoadModule dav_svn_module     modules/mod_dav_svn.so
LoadModule authz_svn_module   modules/mod_authz_svn.so

このモジュールを有効にするには AuthzSVNAccessFile ディレクティブを使うためにLocationブロックを 設定する必要があります。このディレクティブはリポジトリにある パスのパーミッションが書かれたファイルを指定します。(すぐあとで このファイルの形式について議論します。)

Apache は柔軟なので三つの一般的なパターンのどれかにブロックを 設定することができます。まず基本的な設定パターンの一つを選びます。 (以下の例は非常に単純です; Apache の認証と認可の設定の詳細に ついては Apache 自身のドキュメントを参照してください。)

最も単純なブロックはすべての人に対して自由にアクセスすることを 許すものです。このやり方では Apache は認証要求を送信することは ないのですべてのユーザは「匿名」として扱われます。

例 6.1. 匿名アクセスの設定例。

<Location /repos>
  DAV svn
  SVNParentPath /usr/local/svn

  # our access control policy
  AuthzSVNAccessFile /path/to/access/file
</Location>
          

この対極にある設定方法として、すべての人にたいして認証要求するための ブロックを設定することもできます。すべてのクライアントは自身を特定 するための証明を送る必要があります。ブロックはRequire valid-user ディレクティブによって無条件に認証を要求し、またその方法を定義します。

例 6.2. 認証つきアクセスの設定例。

<Location /repos>
  DAV svn
  SVNParentPath /usr/local/svn

  # our access control policy
  AuthzSVNAccessFile /path/to/access/file

  # only authenticated users may access the repository
  Require valid-user

  # how to authenticate a user
  AuthType Basic
  AuthName "Subversion repository"
  AuthUserFile /path/to/users/file
</Location>
          

三番目の非常に一般的な方法は認証つきアクセスと匿名アクセスの組合せ によるものです。たとえば多くの管理者はあるリポジトリのディレクトリを 誰でも読めるようにしたいが、もっと重要な場所については認証された ユーザのみが読めるように(あるいは書き込めるように)したいと考えます。 このような設定ではすべてのユーザはまずは匿名でリポジトリにアクセスし ます。ある時点で本当のユーザ名を要求しなくてはならないアクセスが 発生すると、Apache はクライアントから認証を要求します。このためには Satisfy Anyディレクティブと Require valid-userディレクティブの両方を使います。

例 6.3. 認証つき/匿名の両方でアクセスする場合の設定例。

<Location /repos>
  DAV svn
  SVNParentPath /usr/local/svn

  # our access control policy
  AuthzSVNAccessFile /path/to/access/file

  # try anonymous access first, resort to real
  # authentication if necessary.
  Satisfy Any
  Require valid-user

  # how to authenticate a user
  AuthType Basic
  AuthName "Subversion repository"
  AuthUserFile /path/to/users/file
</Location>
          

いったん基本的な Locationブロックが設定されて しまえばその中にアクセスファイルを作り、認証の規則を定義すること ができます。 アクセスファイルの形式はsvnserve.confや 実行時設定ファイルで利用されるのと同じです。 ハッシュ文字(#)で始まる行は無視されます。 一番単純な形では、それぞれのセクションはリポジトリ とのその中にあるパスの名前を決め、認証用のユーザ名はセクションごと の中にくるオプション名になります。それぞれのオプションの値は リポジトリパスにアクセスするユーザレベルを記述します; r (読み込み専用)か、 rw(読み書き可能)のどちらか になります。ユーザがまったく含まれていなければ、アクセスは全面的 に禁止されます。

もっと具体的に言うと; セクション名は[repos-name:path] か、[path]の形になります。SVNParentPath ディレクティブを使っている場合はセクション中でリポジトリ名を指定するのが 重要です。それを省略すると[/some/dir]のようなセクション は すべてのリポジトリのパス /some/dir にマッチしてしまいます。しかしSVNPathディレクティブ を使っている場合はセクションで唯一のパスを定義するのが良い方法です— 結局そこには唯一のリポジトリしか無いのですから。

[calc:/branches/calc/bug-142]
harry = rw
sally = r

この最初の例ではユーザ harrycalcリポジトリ中の /branches/calc/bug-142 ディレクトリに対して完全な読み書きアクセスが可能ですが、 sally は読み出し アクセスのみです。それ以外のユーザにはこのディレクトリのアクセスは 禁止されます。

もちろんパーミッションは親ディレクトリから子ディレクトリに継承 されます。これは Sally のために、サブディレクトリ中では異なる アクセス方式を指定することができるという意味です:

[calc:/branches/calc/bug-142]
harry = rw
sally = r

# give sally write access only to the 'testing' subdir
[calc:/branches/calc/bug-142/testing]
sally = rw

これで Sally はブランチのtestingサブディレクトリ では書き込みができますが、ディレクトリのほかの部分では依然として読み出し のみが可能です。一方 Harry はブランチ全体に対して依然として 完全な読み書きアクセスが可能です。

ユーザ名変数を設定しなければ、他の人を継承の規則に従って許可する のを明示的に拒否することもできます:

[calc:/branches/calc/bug-142]
harry = rw
sally = r

[calc:/branches/calc/bug-142/secret]
harry =

この例では Harry はbug-142のツリーに 対して完全な読み書きアクセスが可能ですが、その中のサブディレクトリ secretにはまったくアクセスできません。

留意しておくことは、一番詳しく指定したパスが常に最初にマッ チするということです。mod_authz_svnモジュー ルはまず最初にパス自身にマッチするかどうかを調べ、次にその親 ディレクトリ、さらにその親ディレクトリ、と調べていきます。結 果はアクセスファイル中の具体的なパスが有効になると、親ディレ クトリから引き継いでいるパーミッション情報は常に上書きされて しまいます。

デフォルトでは、誰であれリポジトリに対するすべてのアクセスは禁止 されます。これは、もし空のファイルで始めた場合、リポジトリのルート ですべてのユーザに対して少なくとも読み出しパーミッションを与えたい だろうということを意味します。これはアスタリスク変数(*) を使って、「すべてのユーザ」をあらわすことで可能です。 :

[/]
* = r

これはよくある設定です; セクション名の中にリポジトリ名が存在しないことに 注意してください。これはSVNPathを使っていようが SVNParentPathを使っていようが、すべてのリポジトリが すべてのユーザによってどこからでも読み込めるようにします。 すべてのユーザがリポジトリに読み込みアクセスできるようになってしまえば 特定のリポジトリの特定のサブディレクトリに特定のユーザが読み書き可能と するため、明示的に rwの許可を与えることができます。

アスタリスク変数 (*) も特に注意しておく価値があります: それは匿名ユーザにマッチするような 唯一のパターン です。Locationブロックで匿名と認証されたアクセスの 組合せを許すように設定した場合、すべてのユーザは Apache に対して匿名で アクセスするところから話が始まります。 mod_authz_svn はアクセスするパスのために 定義された * の値を探します; みつからなければ Apache はクライアントに対して実際に認証要求を出します。

アクセスファイルでもユーザのグループ全体を定義することが てきます。これは Unix の/etc/groupファイルと 良く似た形式です:

[groups]
calc-developers = harry, sally, joe
paint-developers = frank, sally, jane
everyone = harry, sally, joe, frank, sally, jane

グループを使ってユーザと同じようにアクセス制御することができ、この場合 グループであることを示す「アットマーク」(@)を先頭に付けます:

[calc:/projects/calc]
@calc-developers = rw

[calc:/projects/paint]
@paint-developers = rw
jane = r 

グループは他のグループを含むように定義することもできます:

[groups]
calc-developers = harry, sally, joe
paint-developers = frank, sally, jane
everyone = @calc-developers, @paint-developers

...これでほとんどすべてです。

パス名にもとづいたチェックの禁止

mod_dav_svnモジュールには、「読み込み禁止」 のしるし がついたデータが間違って外部に漏れないようにいろいろな工夫がしてありま す。これは、 svn checkoutsvn update のようなコマンドからの戻り値となるすべてのパス名とファイルの内容を綿密に チェックする必要があることを意味します。このようなコマンドが認可のポリシーに よって読み込むべきではないファイルパス名に出会うと、通常は完全にそれを 無視します。履歴や名称変更を追うようなコマンドの場合— 例えばずっと 昔に名称変更されたファイルに対して svn cat -r OLD foo.c のようなコマンドを実行するような場合など— 名称変更の履歴は、その ようなファイルの以前の名前に読み込み制約がある場合には、単に異常終了して しまいます。

このようなすべてのパス名に対するチェックは場合によっては非常に効率の悪 いものになり、特にsvn logコマンドではそうです。リビ ジョンの一覧を取得する場合、サーバはすべてのリビジョンのすべての変更さ れたパスを見てそれらが読み込み許可されているかどうかを調べます。許可さ れていないパスが見つかるとリビジョンの変更のあったパスの一覧からは除外 され(これは通常--verboseオプションで見ることのできる ものです)、ログメッセージ全体が表示されなくなります。言うまでもありま せんが、たくさんのファイルのあるリビジョンでは多くの時間を消費します。 しかしこれはセキュリティーを保つための代償です: mod_authz_svnのようなモジュールをまったく設定してい ない場合でも、やはり mod_dav_svnモジュールがApache の httpd に対してすべてのパスについての認可チェック をするように要求します。mod_dav_svnモジュールは具体 的にどんな認可モジュールがインストールされているかは知らないので、単に Apache に対して、もしそのようなものがあるなら実行するようにと依頼する だけです。

一方、これに関する逃げ道もやはりあって、セキュリティーよりも効率を重視 するようにも設定できます。ディレクトリごとの認可の仕組みをまったく利用 しないのなら(たとえば mod_authz_svn やそれに類似 のモジュールを使わないのなら)、このパス名に対するチェックを完全に無効に することもできます。httpd.confファイルで、 SVNPathAuthzディレクティブを使ってください:

例 6.4. Disabling path checks altogether

<Location /repos>
  DAV svn
  SVNParentPath /usr/local/svn
            
  SVNPathAuthz off
</Location>            
          

SVNPathAuthz ディレクティブはデフォルトでは 「on」 です。 「off」 に設定するとすべてのパス名にもとづいた認可のチェックが禁止されます; mod_dav_svnはすべてのパスについて認可のチェックをしなく なります。

おまけ

ここまで Apache と mod_dav_svn のための認証と認可のオプショ ンの大部分を説明してきました。しかし Apache が用意している、さらに いくつかのすばらしい機能があります。

リポジトリ閲覧

Subversion リポジトリでApache/WebDAVの設定による一番の恩恵は バージョン化されたファイルやディレクトリの最新リビジョンがウェブブラウザ から直接参照可能だということです。Subversion は URL をバージョン化された 資源を特定するために利用するので、そのような HTTPベースのリポジトリアクセス に利用される URL はウェブブラウザから直接入力することが可能です。ブラウザは その URLに対してGET要求を発行し、その URL がバージョン化 されたディレクトリであるかファイルであるかに応じてmod_dav_svnはディレクトリ の一覧またはファイルの内容を表示します。

URL は見たいと思うリソースのバージョンについての情報は含まれていない ので mod_dav_svn は常に最新のバージョンで答えます。この機能は Subversion URL をドキュメントの参照先として渡すことができ、その URL は常にドキュメントの最新を指すことになる、というすばらしい効果も あります。もちろん他のウェブサイトからのハイパーリンクとして URL を 利用することもできます。

一般的には、(ディレクトリへのURLに比べて) バージョン化されたファイルへ のURLのほうをよく使うことになるでしょう—結局のところ、関心のある内容 がありそうな場所は、そこなのですから。 しかし、Subversion のディレクトリ一覧を参照する機会はあるかも知れず、 その場合すぐに一覧表示で生成される HTML は非常に基本的なもので、美の追求 (や、何か面白いことをやらかそうということ)を目的としているわけではないの に気づくでしょう。このディレクトリ一覧をカスタマイズするために、 Subversion は XML インデックス機能を用意しています。 httpd.conf中で、リポジトリのLocation ブロック中で単一のSVNIndexXSLTディレクティブを使うと mod_dav_svn に対して、ディレクトリ一覧表示時に XML 出力を生成し、 好きな XSLT スタイルシートを参照するように設定することができます:

<Location /svn>
  DAV svn
  SVNParentPath /usr/local/svn
  SVNIndexXSLT "/svnindex.xsl"
  …
</Location>

SVNIndexXSLTディレクティブとクールな XSLT スタイル シートを使ってディレクトリ一覧をウェブサイトのほかの部分で利用されている 色スキーマや画像に一致させることができます。あるいは、もし望むなら Subversion ソース配布中のtools/xslt/ディレクトリ にあるサンプルスタイルシートを使うこともできます。 SVNIndexXSLT ディレクトリで指定されるパスは実際の URL パスであることに注意してください — ブラウザはそれを利用するためにはスタイルシートが読める場所に なければなりません!

その他の機能

堅牢なウェブサーバとして Apache で既に提供されている機能のいくつかは Subversion においても機能とセキュリティーの向上につながります。 Subversion は Neon というSSL(安全なソケット層。既に述べました)や 圧縮(gzipPKZIPと同じような アルゴリズムを使ってファイルより小さなデータの塊に「縮める」 こと)のような仕組みをサポートした一般的なHTTP/WebDAV ライブラリを使って Apache と通信します。やらなくてはならないことは 単にSubversionとApacheで必要な機能をコンパイルし、そのような機能を使える ように正しくプログラムを設定することだけです。

圧縮の仕組みは、実際のサイズを減らすためのネットワーク転送データの圧縮と 解凍処理でクライアントとサーバに少し負荷をかけます。ネットワークの帯域 が細い場合この圧縮はサーバとクライアント間の転送スピードを非常に大きく することができます。極端な場合このデータ転送量の現象は、操作がタイムアウト してしまうか、完了するかの違いになることさえあります。

それほどは面白くありませんが、やはり有用なことは Apache と Subversion に関係したその他の機能で、たとえば特定のポートを指定する機能( デフォルト HTTP ポートである 80 のかわりに)や、Subversion リポジトリが アクセスする仮想ドメイン名の機能や、プロキシ経由でリポジトリにアクセス する能力などがあります。これらはすべて Neon でサポートされているので、 Subversion は自由にその機能を利用することができます。

最後にmod_dav_svnは、ほぼ完全なWebDAV/DeltaV の方言を利用することができるのでサードパーティー製の DAV クライアント を経由してリポジトリにアクセスすることもできます。ほとんどのモダンな オペレーティングシステム(Win32, OS X そして Linux)では標準ネットワーク を「共有」することによって DAV サーバをマウントする組み込みの機能があります。 これは複雑な話題です; 詳細は付録 B. WebDAV と、自動バージョン化を読んでください。



[25] 彼らはそういう作業を本当に嫌います。

[26] 自己サイン付きサーバ証明書は、「中間偽装」攻撃に対しては やはり脆弱ですが、そのような攻撃は、暗号化されていないパスワードを 盗聴するタイプのものに比べてはるかに困難です。

[27] セキュリティーにもっと神経質な人はクライアント証明書用パスワード を実行時serversファイルに格納するのを嫌がる でしょう。