Trac 0.12 導入時のメモ(設定前編)

Trac 0.11 から Trac 0.12 へ移行を考えている人や、Windows 認証を用いた Trac/Subversion の設定、SVK を利用したミラー サーバの構築といった参考になるかもしれないので、だらだらとメモっておく。

なお、内容については、1時間半ぐらいでザーッと一気に設定したものを思い出しながら書き起こしているため、内容に漏れや間違いがあった場合はコメント等で指摘してください。しかし、たった1時間半の作業を文章に起こすのに何時間かかってるんだ、これ…。

10. apache に Subversion をホストさせる

この方法については、わざわざ私が改めて書くこともないと思われるほど情報が多いのですが、認証周りの設定までを一通り書いておきます。

DAV を有効化

httpd.conf にて dav と dav_svn のモジュールを有効にし、公開する URL を決定します。

# DAV モジュール
LoadModule dav_module modules/mod_dav.so
LoadModule dav_svn_module modules/mod_dav_svn.so

# こちらは DAV とは関係ない承認モジュール(後述)
LoadModule authz_svn_module modules/mod_authz_svn.so

# /svn というパスの設定
<Location /svn>
    DAV                svn
    SVNParentPath      "D:/repos"
    SVNListParentPath  on
    #SVNIndexXSLT      "/svnindex.xsl"
    AuthzSVNAccessFile "D:/etc/svnaccess.conf"
</Location>

この例では、SVNParentPath を使用して D:\repos\{repository} にあるリポジトリをすべて http://localhost/svn/{repository} という URL で公開します。実は、Location を設定するとき /svn にするか /svn/ にするかは悩ましいところです。
Windows の共有フォルダやネットワークドライブの機能を用いて上記の URL に接続する場合、Windows は / がない URL にアクセスしてくるため、Location を /svn/ と設定していると共有フォルダやネットワークドライブとして開けなくなります。これだけ考えると Location は /svn にすることになります。しかし、

  • AuthzSVNAccessFile を使用してアクセス承認を行う
  • SVNParentPath を使用して複数のリポジトリをまとめて公開する
  • SVNListParentPath を on にしてリポジトリの一覧を表示できるようにする

という3つの条件がそろうと、Location を /svn としている状態でブラウザから /svn という URL にアクセスした場合に問題になります。この URL ではリポジトリが未指定なのでリポジトリ名が null になるようなのですが、後述の AuthzSVNAccessFile にて参照されるアクセス許可を確認する処理が、リポジトリ名が null だとエラーになるため /svn という URL でリポジトリ一覧を開こうとするとエラーになってしまいます。URL として /svn/ を指定すると、最後に / があるためかリポジトリ名が空文字列になるため [/] の設定を参照してリポジトリ一覧に対するアクセス承認がおりればリポジトリ一覧が表示されるという動きになります。
とりあえず、私は共有フォルダやネットワークドライブとしての利用をあきらめるようにして、

RedirectMatch permanent ^/svn$ /svn/
<Location /svn/>
    ....
</Location>

としています。

承認設定

リポジトリのアクセス承認の設定は AuthzSVNAccessFile で指定したファイルで行います。この例では D:\etc\svnaccess.conf に従うように指定していますので、このファイルを作成します。内容は、

# ユーザをグループ化して一括設定する場合、グループの設定を行う
[groups]
admins = user1, user2
group1 = user3, user4, user5
group2 = user3, user6, user7

# 全体のデフォルト設定
# SVNParentPath が on の場合、リポジトリ一覧の参照権限として使われるので誰でも読めるとする
[/]
* = r
? = r

# project1 リポジトリのデフォルト設定
#   admins, group1 のメンバーは読み書き可能
#   認証ユーザは読み取り可能
#   匿名ユーザは読み取り不可能
[project1:/]
@admins = rw
@group1 = rw
* = r
? = 

# SVK によるミラーリング用のディレクトリは外部から更新させない
[project1:/vendor]
* = r

こんなかんじの記述を行います。/vendor は SVK によって管理されるため、外部からは更新できないようにしています、これは SVKapache を経由しないでリポジトリを操作するため、このファイルに指定された読み書きの制限は受けないことを利用して、あやまってチームのメンバーがミラー先を更新しないように読み取り専用しておきます。*1

認証設定

承認設定ファイルだけでは誰がアクセスしても匿名ユーザとして扱われてしまうので、ユーザ認証の設定を行います。
apache のモジュールでは承認(authorize)に関するモジュールは authz、認証(authentication)に関するモジュールは authn という名前になっていますので、authn という名前のモジュールを有効にして設定します。一部の古いモジュールは auth という n も z もない名前になっていたり、authz と authn の両方の機能をもつものは authnz となっていたりします。
ここでは、例として mod_auth_sspi を用いて Windows のユーザとパスワードを使ってアクセスできるようにします。

LoadModule sspi_auth_module modules/mod_auth_sspi.so

と、事前に mod_auth_sspi を読み込ませておいて の間に、

    # 認証に使う Realm の名前
    # 後で trac でも認証を行うことを考えて、svn のような名前はやめましょう
    AuthName         "My Server"
    
    # この Location にて、mod_auth_sspi を有効化
    AuthType          SSPI
    SSPIAuth          on

    # NTLM 認証を有効にします (ログインしているユーザで自動的ログインを試みる)
    SSPIOfferSSPI     on

    # Basic 認証を有効にします (ユーザ/パスワードを尋ねるダイアログを表示する)
    SSPIOfferBasic    on

    # 上記2つがともに ON の場合、どちらを優先するか
    SSPIBasicPreferred  off
        # on の場合、Basic 認証が優先されるので、常にユーザ名とパスワードを聞かれます
        # off の場合、NTLM 認証が優先され、ログインできないときだけ聞かれます

    # mod_auth_sspi の認証失敗を apache の認証結果として採用する
    SSPIAuthoritative on

    # 使用するドメイン名またはコンピュータ名
    SSPIDomain        host1   
        # コンピュータ名を指定するとローカル ユーザで認証されます
        # ドメイン名を指定すると、指定されたドメイン ユーザで認証されます

    # 認証結果のドメイン名を捨てます
    SSPIOmitDomain    on      
       # domain1\user1 で認証したとき、apache や Subversion には user1 だけが渡ります。
       # off にした場合、少し前の例で AuthzSVNAccessFile で指定した svnaccess.conf にも
       # user1 ではなく domain1\user1 と書かなければなりません。

    # 認証結果を小文字に変換します
    SSPIUsernameCase  lower   
        # Windows では大文字小文字を区別していないので、認証時に user1 ではなく、
        # User1 や USER1 と入力しても認証が成功します。
        # apache や Subversion は大文字小文字を区別するので、user1 と User1 は別人だと
        # 認識します。AuthzSVNAccessFile で指定した svnaccess.conf に全パターンを登録する
        # のは現実的ではないので、全て小文字に変換するように指定して統一します。
    

というようなかんじで記述を行います。もし、Subversion Users のようなグループに参加しているユーザのみを対象にする場合は、

    require group "host1\Web Users"

としておくと、host1 のローカル グループである Web Users に参加している Windows ユーザのみが認証に成功します。ドメイン環境の場合は、host1 のかわりにドメイン名を指定してドメインのグループで制限できます。認証成功すれば誰でもアクセスできるようにするのであれば、

    require valid-user

とすれば OK です。また、匿名でのアクセスも許可する場合には、

    Satisfy Any

を追加することで、匿名ユーザで参照可能な範囲はユーザ認証の要求が発生しなくなります。実際のサーバでは、

  • 社員のユーザ認証は、会社の Active Directory で認証する
  • 外部作業員(外注)のユーザ認証は、サーバのローカル ユーザとして認証する
  • 匿名のアクセスも認める

という設定なので、

    AuthName         "My Server"

    AuthType          SSPI
    SSPIAuth          on
    SSPIOfferSSPI     on
    SSPIOfferBasic    on
    SSPIBasicPreferred  off

    # mod_auth_sspi の認証失敗を apache の認証結果として採用しない
    SSPIAuthoritative on
        # 採用しない=失敗したら次の authn モジュールへ認証を委任する

    # ローカル コンピュータで認証を試みる
    SSPIDomain        host1
    SSPIOmitDomain    on   
    SSPIUsernameCase  lower

    # ローカル グループ Web Users に所属していることを要求
    require group "host1\Web Users"

    # 平分パスワード認証を有効化
    AuthType          Basic

    # パスワードの保存先は LDAP
    AuthBasicProvider ldap

    # LDAP の接続設定とクエリ
    AuthLDAPBindDN       "..."
    AuthLDAPBindPassword "...."
    AuthLDAPURL          "ldap://..."

    # LDAP の属性に特定の値があることを要求
    require ldap-attribute ...

    # 認証に失敗してもアクセス元が社内なら匿名として認める
    Allow from ...
    Satisfy Any

*1:SVK の入門記事などでは、よくミラー先に誤ってコミットすると元リポジトリに直接コミットされてしまうので気をつけるような話がありますが、それを設定で不可能にしておこうというようなものです。

11. Trac 環境の作成

Trac の環境作成も Subversion と同様に簡単なもので、コマンドラインから

PS temp> trac-admin D:\trac\project1 initenv

等と、作成したいフォルダを指定して initenv を実行すれば作成されます。続けて、

PS temp> trac-admin D:\trac\project1

と実行すると、

Trac [D:\trac\project1]>

とプロンプトが変わって Trac の管理コンソールになりますが、Trac の設定については色々あるので後にまわします。

12. apache に Trac をホストさせる

こちらについても改めて書くほどでもないので、ざっくりと書いていきます。
Trac は、CGI, FastCGI, mod_python, mod_wsgi といった手段で apache 上でホストできますが mod_python は推奨されない古い形式なので mod_wsgi を使用します。
mod_wsgi は、http://code.google.com/p/modwsgi/ からバイナリが手に入ります。ApachePython のバージョンが合うものをダウンロードして modules フォルダに mod_wsgi.so という名前で保存すれば OK でしょう。
Trac の管理コンソールから

Trac [D:\trac\project1]> deploy C:\temp

と、deploy コマンドを実行すると、指定した場所に Trac の設定ファイル群がドサッと作成されます。ツリー構造は、

 cgi-bin/
    trac.cgi ... CGI でホストする場合の実行ファイル
    trac.fcgi ... FastCGI でホストする場合の実行ファイル
    trac.wsgi ... mod_wsgi でホストする場合の実行ファイル
 htdocs/
    common/ ... Trac の固定リソース ファイル群
    site/ ... このプロジェクトの固定リソース ファイル群

というようになっています。この中で今回使うのは、cgi-bin/trac.wsgi と htdocs/common/ です。まずは、htdocs/common を apache の DocumentRoot 下にコピーします。

PS temp> Move-Item "C:\temp\htdocs\common" `
>> "C:\Program Files (x86)\Apache Software Foundation\Apache2.2\htdocs\trac-common"

デフォルトの htdocs を移動していなければ、こんなかんじでファイルをコピーします。(これは移動していますが) htdocs の下に trac-common という名前で配置したので、trac.ini の htdocs_location に /trac-common と設定しておくことで、固定のリソースファイルの取り出しに Python のハンドラを経由しなくてよくなります。
cgi-bin/trac.wscgi についても同様に実行可能な場所にコピーします。デフォルトでは、そんな実行可能フォルダは存在しないので、どこかに場所を作って保管します。

PS temp> mkdir D:\trac\bin
PS temp> Copy-Item C:\temp\cgi-bin\trac.wsgi `
>> D:\trac\bin\project1.wsgi

とりあえず適当なフォルダに移動しています。また project1 に接続する設定なのでファイル名も変えています。apache の設定ファイルに、このフォルダと project1.wsgi を登録します。

# mod_wsgi の読み込み
LoadModule wsgi_module modules/mod_wsgi.so

# trac.wsgi を保存したディレクトリを実行可能にする
<Directory "D:/trac/bin">
    WSGIApplicationGroup %{GLOBAL}
    Order deny,allow
    Allow from all
</Directory>

# /project1 という URL で project1.wsgi を動かす
WSGIScriptAlias /project1 "D:/trac/bin/project1.wsgi"

これで、http://localhost/project1 という URL にアクセスすると Trac が無事に起動しているのが見えると思います。Subversion と同様に、trac も指定したフォルダの下をすべてプロジェクトとして使用することができます。たとえば、次のようなファイルを trac.wsgi として作成します。

import os

def application(environ, start_request):
    os.environ['TRAC_ENV_PARENT_DIR'] = 'D:\\trac'
    os.environ['PYTHON_EGG_CACHE'] = 'D:\\trac\\.eggs'
    from trac.web.main import dispatch_request
    return dispatch_request(environ, start_request)

このファイルを apache に登録します。

WSGIScriptAlias /projects "D:/trac/bin/trac.wsgi"

この例だと /projects という URL に登録しているので、project1 にアクセスするには http://localhost/projects/project1 という URL になります。D:\trac の下に proj2 という名前で新しい Trac の環境を作成した場合は、自動的に http://localhost/projects/proj2 という URL でアクセスできるようになります。