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 によって管理されるため、外部からは更新できないようにしています、これは SVK は apache を経由しないでリポジトリを操作するため、このファイルに指定された読み書きの制限は受けないことを利用して、あやまってチームのメンバーがミラー先を更新しないように読み取り専用しておきます。*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
11. Trac 環境の作成
Trac の環境作成も Subversion と同様に簡単なもので、コマンドラインから
PS temp> trac-admin D:\trac\project1 initenv
等と、作成したいフォルダを指定して initenv を実行すれば作成されます。続けて、
PS temp> trac-admin D:\trac\project1
と実行すると、
Trac [D:\trac\project1]>
12. apache に Trac をホストさせる
こちらについても改めて書くほどでもないので、ざっくりと書いていきます。
Trac は、CGI, FastCGI, mod_python, mod_wsgi といった手段で apache 上でホストできますが mod_python は推奨されない古い形式なので mod_wsgi を使用します。
mod_wsgi は、http://code.google.com/p/modwsgi/ からバイナリが手に入ります。Apache と Python のバージョンが合うものをダウンロードして 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 でアクセスできるようになります。