Apache ベースのサーバ

はじめに

Subversion 用にセットアップできるサーバのうち、もっとも柔軟なのは Apache ベースの物です。セットアップするには少し複雑ですが、他のサーバが提供できない特徴があります。

WebDAV

Apache ベースの Subversion サーバは、多数の他のプログラムがサポートする WebDAV プロトコルを使用します。例えば、リポジトリを Windows エクスプローラで言う Web フォルダ としてマウントでき、ファイルシステムのその他のフォルダのようにアクセスできます。

リポジトリの閲覧

ブラウザにリポジトリの URL を入力することで、Subversion クライアントをインストールしていなくても内容を閲覧できます。これにより、より大きなユーザの輪がそのデータにアクセスできるようになります。

認証

Apache がサポートする (SSPI や LDAPを含む) 認証メカニズムを使用できます。

セキュリティ

Apache はとても安定・安全ですかから、リポジトリにも自動的に同じセキュリティが確保できます。これには SSL の暗号化も含まれます。

Apache のインストール

Apache をインストールするためには、コンピュータが Windows 2000 か Windows XP+SP1, Windows 2003, Vista, Server 2008 である必要があります。

警告

サービスパック 1 を適用していない Windows XP ではインチキなネットワークデータを流してしまい、リポジトリを破壊する可能性があります!

  1. Apache ウェブサーバの最新版を http://httpd.apache.org/download.cgi からダウンロードしてください。バージョン 2.2.x をダウンロードしてください。1.3.xx では動作しません!

    Apache 用の msi インストーラは other files をクリックして、binaries/win32 へと進むと見つかります。apache-2.2.x-win32-x86-openssl-0.9.x.msi (openssl を含むもの) を選択することになるかと思います。

  2. いったん Apache2 インストーラを手に入れれば、それをダブルクリックし、インストール中にそのプロセスの案内をしてもらえます。(サーバ用の DNS 名がなく、IP アドレス入力するだけなら) サーバ URL を必ず正しく入力してください。すべてのユーザ向けに、ポート 80 でサービスとして apache をインストールするのをおすすめします。注) すでに IIS や 80 番ポートを他のプログラムを実行しているなら、インストールに失敗するでしょう。その場合、プログラムディレクトリ \Apache Group\Apache2\conf に移動し、 httpd.conf をそこに置いてください。そのファイルを編集し、Listen 80 を別の空いているポート (例えば Listen 81) に変更してください。その後インストールを再起動してください。今度は問題なく終了するはずです。

  3. Apache ウェブサーバの動作確認のため、ウェブブラウザで http://localhost/ にアクセスすると、あらかじめ設定されているウェブサイトが表示されます。

注意

Apache をサービスとしてインストールすると決めた場合、デフォルトではローカルシステムアカウントで実行してしまうという警告があります。より安全な方法として、Apache を実行するにあたって独立したアカウントを作成できます。

リポジトリのあるディレクトリのアクセスコントロールリスト (ディレクトリを右クリック | 属性 | セキュリティ) で、Apache を実行するサーバ上のアカウントをフルコントロールに明示していなければなりません。そうでなければ、ユーザが行った変更をコミットすることができません。

Apache がローカルシステムとして実行しても、まだそのようなエントリー(この場合 SYSTEM アカウントになる) が必要です。

このパーミッション設定を Apache にしない場合、ユーザは Access denied エラーメッセージを受け取ることになります。このエラーは Apache のエラーログに 500 エラーとして記録されています。

Subversion のインストール

  1. Apache 用 Subversion Win32 バイナリの最新版をダウンロードしてください。必ず、使用する Apache のバージョンと組み合わさる、正しいバージョンを使用してください。そうしないと、再起動しようとした際に、不明瞭なエラーメッセージを得ることになります。Apache 2.2.x を使用する場合、http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=8100 へ進んでください。

  2. Subversion インストーラを実行し、説明に従ってください。Subversion インストーラがインストール済みの Apache を認識した場合、それでほとんど終了です。Apache サーバが見つからない場合、いくつか追加の手順があります。

  3. Windows エクスプローラで、Subversion のインストールディレクトリ (通常 c:\program files\Subversion) に移動し、/httpd/mod_dav_svn.somod_authz_svn.so を確認してください。そのファイルを Apache モジュールディレクトリ (通常 c:\program files\apache group\apache2\modules ) にコピーしてください。

  4. Subversion インストールディレクトリにある /bin/libdb*.dll/bin/intl3_svn.dll を、Apache bin ディレクトリにコピーしてください。

  5. Apache の設定ファイル (通常 C:\Program Files\Apache Group\Apache2\conf\httpd.conf)を、メモ帳のようなテキストエディタで以下のように編集してください。

    以下の行のコメントをはずし ('#' マークを消し) てください。

    #LoadModule dav_fs_module modules/mod_dav_fs.so
    #LoadModule dav_module modules/mod_dav.so
    

    また、以下の 2 行を LoadModule セクションの最後に追加してください。

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

設定

以上で Apache と Subversion をセットアップしました。しかし Apache は、どのように TortoiseSVN のような Subversion クライアントを扱うかをまだ知りません。Subversion リポジトリが使用する URL を Apache に教えるために、Apache 設定ファイル (通常、c:\program files\apache group\apache2\conf\httpd.conf) をお好みのテキストエディタ (例: メモ帳) で以下のように編集してください。

  1. 以下の行を設定ファイルの最後に追加してください。

    <Location /svn>
      DAV svn
      SVNListParentPath on
      SVNParentPath D:\SVN
      #SVNIndexXSLT "/svnindex.xsl"
      AuthType Basic
      AuthName "Subversion repositories"
      AuthUserFile passwd
      #AuthzSVNAccessFile svnaccessfile
      Require valid-user
    </Location>
    

    これで Apache に、すべての Subversion リポジトリの物理的な位置が D:\SVN 以下にあるように設定できます。リポジトリは外部に URL: http://MyServer/svn/ で提供することになります。アクセス制限は passwd ファイルに記述した users/password の組で行います。

  2. passwd ファイルの作成をするには、コマンドプロンプト (DOS ボックス) を再度開き、apache2 フォルダ (通常 c:\program files\apache group\apache2) に移動してください。その後、以下を入力してファイルを作成してください。

    bin\htpasswd -c passwd <username>
    

    これで認証に使用するファイルを passwd という名前で作成します。ユーザを追加する場合は、さらに以下のようにしてください。

    bin\htpasswd passwd <username>
    
  3. 再度 Apache サービスを再起動してください。

  4. ブラウザで http://MyServer/svn/MyNewRepository (MyNewRepository には、あらかじめ作成しておいた Subversion リポジトリの名前に置き換えてください) すべてうまくいったのなら、ユーザ名とパスワードを入力でき、リポジトリの内容を見ることができます。

以下は入力する部分の短い説明です。

表3.1 Apache httpd.conf の設定

設定説明
<Location /svn>Subversion リポジトリは URL http://MyServer/svn/ から有効になることを意味します。
DAV svnApache にその URL にはどのモジュールがレスポンスを返せばいいか指示します。この場合は Subversion モジュール。
SVNListParentPath onSubversion バージョン 1.3 以降では、SVNParentPath に列挙した有効なリポジトリに対してこのディレクティブが有効になります。
SVNParentPath D:\SVNSubversion に以下のリポジトリを探すように指示します。
SVNIndexXSLT "/svnindex.xsl"ウェブブラウザでの閲覧を、もっと魅力的にするのに使用します。
AuthType Basicユーザ名・パスワードといった BASIC 認証を有効にします。
AuthName "Subversion repositories"ポップアップする認証ダイアログでどの認証用かユーザに伝えるのにこの情報を使用します。
AuthUserFile passwd認証に使用するパスワードファイルを指定します。
AuthzSVNAccessFileSubversion リポジトリ内のアクセスファイルの場所。
Require valid-userURL にアクセスしたときに正しいユーザ名・パスワードを入力したユーザのみ許可するよう指定します。


これは例でしかありません。Apache ウェブサーバにはもっとずっとたくさん設定項目があります。

  • リポジトリを、指定したユーザは書込アクセスができ、それ以外のユーザは読込アクセスしかできないようにしたい場合、以下の行を変更してください。

    Require valid-user
    

    これを以下のようにします。

    <LimitExcept GET PROPFIND OPTIONS REPORT>
    Require valid-user
    </LimitExcept>
    
  • passwd ファイルを使用して、全リポジトリを単位にアクセス制限・許可を行います。リポジトリ内部のフォルダごとにアクセスを設定するような制御が必要なら、以下の行のコメントアウトを解除し、Subversion アクセスファイルを作成してくださいてください。

    #AuthzSVNAccessFile svnaccessfile
    

    Apache は確実に、有効なユーザのみが /svn にアクセスできるようにします。また、Subversion の AuthzSVNAccessFile モジュールにユーザ名を渡し、Subversion アクセスファイルに列挙したルールに基づく、よりきめの細かいアクセス制御を行うことができます。パスが repos:path か、単に path として指定されるのに注意してください。特定のリポジトリを指定しない場合、アクセスルールは SVNParentPath の下のすべてのリポジトリに適用されます。mod_authz_svn で使用する認証ポリシーファイルの書式は、「パスベース認証」 で説明しています。

  • ウェブブラウザでのリポジトリの閲覧を、もっと「魅力的」にするには、以下の行のコメントを外してください。

    #SVNIndexXSLT "/svnindex.xsl"
    

    また、svnindex.xsl, svnindex.css, menucheckout.ico をドキュメントルートディレクトリ (通常 C:/Program Files/Apache Group/Apache2/htdocs) に置いてください。このディレクトリは、Apache 設定ファイルの DocumentRoot ディレクティブで設定します。

    その 3 ファイルは http://tortoisesvn.tigris.org/svn/tortoisesvn/trunk/contrib/svnindex にあるソースリポジトリから直接取得できます (TortoiseSVN のソースリポジトリへのアクセスのしかたは、「TortoiseSVN は自由!」 で説明します)。

    TortoiseSVN リポジトリにある XSL ファイルには、以下のような気の利いた仕掛けがしてあります。ウェブブラウザでのリポジトリ閲覧の際、リポジトリにあるフォルダごとに、右側にアイコンを表示します。このアイコンをクリックすると、この URL 用の TortoiseSVN のチェックアウトダイアログを開きます。

複数のリポジトリ

SVNParentPath ディレクティブを使用する場合、新しいリポジトリを作成する際に Apache 設定ファイルを変更する必要はありません。単にはじめのリポジトリと同じ場所に、新しいリポジトリを作成してください。これで終わりです! 筆者の会社では、SMB (通常の Windows ファイルアクセス) で指定のフォルダに直接アクセスできています。ここに新しいフォルダを作成し、TortoiseSVN コマンド TortoiseSVNここにリポジトリを作成... を実行すると新しいプロジェクトのホームができます...

Subversion 1.3 以降を使用している場合、ブラウザで個々のリポジトリを指定するのではなく上位パスを指定して、有効なプロジェクトの一覧を Apache が表示できるよう、SVNListParentPath on ディレクティブを使用できます。

パスベース認証

mod_authz_svn モジュールは、ユーザ名とリポジトリパスを元にしたアクセス制限のきめ細かい制御を行えます。これは Apache サーバで利用でき、また Subversion 1.3 では svnserve でも同様に利用できます。

サンプルファイルは以下のようになります。

[groups]
admin = john, kate
devteam1 = john, rachel, sally
devteam2 = kate, peter, mark
docs = bob, jane, mike
training = zak
# Default access rule for ALL repositories
# Everyone can read, admins can write, Dan German is excluded.
[/]
* = r
@admin = rw
dangerman =
# Allow developers complete access to their project repos
[proj1:/]
@devteam1 = rw
[proj2:/]
@devteam2 = rw
[bigproj:/]
@devteam1 = rw
@devteam2 = rw
trevor = rw
# Give the doc people write access to all the docs folders
[/trunk/doc]
@docs = rw
# Give trainees write access in the training repository only
[TrainingRepos:/]
@training = rw

すべてのパスをチェックするのは、(特にリビジョンログに関して) 時間がかかる操作だということに注意してください。サーバは、リビジョンごとにすべてのパスを変更があるかチェックし、そこが読み込めるかどうかをチェックします。リビジョンにあるファイルが多くなれば、時間をどんどん消費してしまいます。

認証 (authentication) と許可 (authorization) は独立したプロセスです。ユーザがリポジトリパスへアクセスしたい場合、通常の認証条件とファイルへのアクセス許可条件を両方満たさなくてはなりません。

Windows ドメインでの認証

お気づきのように passwd ファイルに、ユーザごと別々に ユーザ名/パスワードのエントリを作成しなければなりません。 そして、(安全上の理由で) ユーザに定期的にパスワードを変えて欲しいなら、手動で変更しなければなりません。

しかし少なくとも、Windows のドメインコントローラを利用するLANの内部からリポジトリにアクセスするなら、この問題の解決法があります。mod_auth_sspi です!

オリジナルの SSPI モジュールはソースコード込みで Syneapps から提供されていましたが、現在開発が止まっています。しかし、がっかりすることはありません。コミュニティが拾い上げ、改良を行っています。新しいホームは SourceForge にあります。

  • apache のバージョンに一致するモジュールをダウンロードし、mod_auth_sspi.so を Apache モジュールフォルダにコピーしてください。

  • Apache 設定ファイル を編集し、以下を LoadModule セクションに追加してください。

    LoadModule sspi_auth_module modules/mod_auth_sspi.so
    

    以上の行を

    LoadModule auth_module modules/mod_auth.so
    

    の行の前に挿入してください。

  • Subversion ロケーションがこのタイプの認証を使用するように、

    AuthType Basic
    

    AuthType SSPI
    

    に変更しなければなりません。また、

    SSPIAuth On
    SSPIAuthoritative On
    SSPIDomain <domaincontroller>
    SSPIOmitDomain on
    SSPIUsernameCase lower
    SSPIPerRequestAuth on
    SSPIOfferBasic On
    

    <Location /svn> ブロックに追加する必要があります。ドメインコントローラを使用しなければ、<domaincontroller> としたドメインコントローラの名前を取り除いてください。

SSPI を使用して認証を行う場合、パスワードファイルを定義するのに AuthUserFile の行はもう必要ありません。Apache はユーザ名とパスワードを Windows ドメインで認証します。DOMAIN\username を参照するよう svnaccessfile のユーザ一覧を更新する必要があります。

重要

SSPI 認証は、SSL の安全な接続 (https) でのみ有効です。サーバに通常の http 接続しか使えない場合は、動作しません。

SSL を有効にするには、「SSL を使用したサーバの保護」 の章をご覧ください。

ヒント

Subversion の AuthzSVNAccessFile ファイルではユーザ名の大文字小文字は区別します。("JUser" と "juser" は異なります)

Microsoft の世界では、Windows ドメインとユーザ名は大文字小文字を区別しません。ですからネットワーク管理者の中には、ユーザアカウントをキャメルケース (例: JUser) で作成するのを好む人がいます。

Windows ドメインとユーザ名をユーザが入力したとおりに Subversionに渡して SSPI 認証を行う場合、この違いは悪影響を与えます。インターネットエクスプローラは Apache にアカウント作成時の形に自動で整形して渡します。

結論としては、AuthzSVNAccessFile にユーザごとに少なくとも 2 エントリ (小文字のエントリと、インターネットエクスプローラが Apache に渡すのと同じ形式のエントリ) が必要です。また、TortoiseSVN でリポジトリにアクセスする際に、小文字で入力するようユーザに指導する必要があるでしょう。

Apache のエラーログとアクセスログは、こういった問題を読み解き Subversion の AuthzSVNAccessFile モジュールに渡すユーザ名の文字列を決めるのを助ける相棒といえます。すべてが動作するには、svnaccessfile 内のユーザ文字列の正しいフォーマット (例: DOMAIN\user vs. DOMAIN//user) をテストする必要があります。

マルチ認証ソース

また、Subversion リポジトリに複数の認証ソースを持つこともできます。それには、いずれの認証タイプも権威を持たないようにします。すると Apache は、ユーザ名とパスワードの検証に、複数のソースをチェックするようになります。

Windows ドメイン認証と passwd ファイル両方を使用するというのが、よくあるシナリオです。これにより、Windows ドメインログインできないユーザも、SVN アクセスができるようになります。

  • Windows ドメイン認証と passwd ファイル認証の両方を有効にするには、Apache 設定ファイルの <Location> ブロックに以下のエントリを追加してください。

    AuthBasicAuthoritative Off
    SSPIAuthoritative Off
    

以下は、Windows ドメインと passwd ファイル認証を組み合わせた Apache の全設定のサンプルです。

<Location /svn>
  DAV svn
  SVNListParentPath on
  SVNParentPath D:\SVN

  AuthName "Subversion repositories"
  AuthzSVNAccessFile svnaccessfile.txt

# NT Domain Logins.
  AuthType SSPI
  SSPIAuth On
  SSPIAuthoritative Off
  SSPIDomain <domaincontroller>
  SSPIOfferBasic On

# Htpasswd Logins.
  AuthType Basic
  AuthBasicAuthoritative Off
  AuthUserFile passwd

  Require valid-user
</Location>

SSL を使用したサーバの保護

Apache 2.2.x では OpenSSL をサポートしていますが、デフォルトでは有効になっていません。手動で有効にする必要があります。

  1. apache の設定ファイルで、以下のコメントアウトを外してください。

    #LoadModule ssl_module modules/mod_ssl.so
    

    さらにその下の次の部分です。

    #Include conf/extra/httpd-ssl.conf
    

    その後、

    SSLMutex "file:C:/Program Files/Apache Software Foundation/\
    Apache2.2/logs/ssl_mutex"
    

    の行を

    SSLMutex default
    

    に変更してください。

  2. 次に、SSL 証明書を作成する必要があります。コマンドプロンプト (DOS ボックス) を開き、Apache フォルダ (例: C:\program files\apache group\apache2) に移動して、以下を入力してください。

    bin\openssl req -config conf\openssl.cnf -new -out my-server.csr
    

    パスフレーズが訊かれます。簡単な単語ではなく、文全体 (詩の一部など) を入力してください。より長い文の方がいいでしょう。サーバの URL も入力する必要があります。質問はすべて任意ですが、すべて答えるのをお勧めします。

    通常 privkey.pem ファイルは自動的に作成されますが、作成されなければ以下のコマンドで生成する必要があります。

    bin\openssl genrsa -out conf\privkey.pem 2048
    

    次に以下のコマンドを入力してください。

    bin\openssl rsa -in conf\privkey.pem -out conf\server.key
    

    および (1 行で)

    bin\openssl req -new -key conf\server.key -out conf\server.csr \
    -config conf\openssl.cnf
    

    その後 (1 行で)

    bin\openssl x509 -in conf\server.csr -out conf\server.crt
                     -req -signkey conf\server.key -days 4000
    

    これで 4000 日経過すると失効する証明書ができます。最後に以下を (1 行で) 入力してください。

    bin\openssl x509 -in conf\server.cert -out conf\server.der.crt
                     -outform DER
    

    ここまでのコマンドは、Apache の conf フォルダにファイルをいくつか (server.der.crt, server.csr, server.key, .rnd, privkey.pem, server.cert) 作成します。

  3. Apache サービスを再起動してください。

  4. ブラウザで https://servername/svn/project を表示してください…

SSL とインターネットエクスプローラ

SSL を使用してサーバを安全にしようとしたり、Windows ドメインの認証を使用する場合、インターネットエクスプローラでリポジトリを閲覧するのはうまくいきません。が、心配しないでください。インターネットエクスプローラが認証できないだけです。他のブラウザにはこの問題はありませんし、TortoiseSVN やその他の Subversion クライアントは認証できます。

まだ IE でリポジトリの閲覧を行いたいのなら、以下も行ってください。

  • Apache 設定ファイルの <Location /path> ディレクティブで区切り SSPIBasicPreferred On と定義してください。IE でも認証できるようになります。しかし、他のブラウザや Subversion はこの location で認証ができなくなります。

  • 暗号化していない (SSL を使わない) 認証も提供してください。おかしなことに、SSL で安全にしていない接続では IE は認証の問題が発生しません。

  • SSL の「標準」セットアップでは、Apache の仮想 SSL ホストに以下の項目があります。

    SetEnvIf User-Agent ".*MSIE.*" \
                 nokeepalive ssl-unclean-shutdown \
                 downgrade-1.0 force-response-1.0
    

    この設定にはきちんとした理由があります (ありました(?))。http://www.modssl.org/docs/2.8/ssl_faq.html#ToC49 をご覧ください。また、NTLM 認証を行いたい場合、keepaliveを使わなければなりません。SetEnvIf 全体をアンコメントすると mod_auth_sspi を組み込んだ Win32 上の Apache で、SSL を使ったWindows 認証を IE で行えるようになります。

SSL アクセスの強制

リポジトリが安全になるよう SSL をセットアップするにあたり、通常の非 SSL (http) アクセスを無効にして、https のみを許可したいかもしれません。このため、Subversion の <Location> ブロックに別のディレクティブ SSLRequireSSL を追加しなければなりません。

<Location> ブロックの例は以下のようになります。

<Location /svn>
  DAV svn
  SVNParentPath D:\SVN
  SSLRequireSSL
  AuthType Basic
  AuthName "Subversion repositories"
  AuthUserFile passwd
  #AuthzSVNAccessFile svnaccessfile
  Require valid-user
</Location>

仮想 SSL ホストでのクライアント証明書の使用方法

Nigel Green さんが TortoiseSVN のメーリングリストに投稿した内容です。ありがとうございます!

サーバの構成によっては、2 つ仮想 SSL ホストをひとつのサーバにセットアップする必要があるかも知れません。ひとつはクライアント証明書のいらず、web アクセスが公開されています。二つ目はクライアント証明書が必要な安全なサーバで、Subversion サーバを動作させています。

SSLVerifyClient Optional ディレクティブを、Apache 設定ファイルの サーバごとの セクション (つまり VirtualHost ブロックと Directory ブロックの外側) に追加すると、最初の SSL ハンドシェイクでクライアント証明書を要求するように、強制できます。mod_ssl のバグにより、SSL 接続を再ネゴシエーションする場合、動作していないときと同じように、この時点で証明書が必要になるのは避けられません。

解決策は、Subversion でロックしたい仮想ホストのディレクトリに、以下のディレクティブを追加することです。

SSLRequire %{SSL_CLIENT_VERIFY} eq "SUCCESS"

クライアント証明書を受け取り、検証に成功した場合だけ、このディレクティブは、そのディレクトリへのアクセスを許可します。

まとめると、Apache 設定ファイルの関係する行は、以下のようになります。

SSLVerifyClient Optional

### Virtual host configuration for the PUBLIC host 
### (not requiring a certificate)

<VirtualHost 127.0.0.1:443>
  <Directory "pathtopublicfileroot">
  </Directory>
</VirtualHost>

### Virtual host configuration for SUBVERSION 
### (requiring a client certificate)
<VirtualHost 127.0.0.1:443>
  <Directory "subversion host root path">
    SSLRequire %{SSL_CLIENT_VERIFY} eq "SUCCESS"
  </Directory>

  <Location /svn>
    DAV svn
    SVNParentPath /pathtorepository
  </Location>
</VirtualHost>