mod_authz_svn を使おうとして挫折したりとか
最近プロジェクトの情報をなるべく(社内で)オープンにして、一部分のみセキュリティをかける方針に変更中です。
に書きましたが、SVN でも似たような設定をやろうと思いまして。だったら mod_authz_svn 使いたいよねと思ったんだけどうまくいかなかったので、そのあたりのお話。
ちなみにただの作業記録なので、同じ問題にハマってる方以外には役にたたないと思います。
前提
<Location /svn> DAV svn SVNParentPath /home/svn </Location> <Location /svn/proj1> # Limit write permission to list of valid users. AuthType Basic AuthName "Subversion Repository(proj1)" AuthUserFile /home/trac/proj1/trac.htpasswd <LimitExcept GET PROPFIND OPTIONS REPORT> Require valid-user </LimitExcept> </Location>
こんな感じで SVNParentPath を使ったマルチリポジトリ構成。
以前はユーザ認証自体かかってなかったんだけど、それだとログにユーザ名が残らなかったりして不便なので、最近やってるプロジェクトではプロジェクトごとに passwd ファイルを用意して、Apache 側でも個別にそれを指定している形。で、リポジトリに編集操作をする場合はユーザ認証が必要になる、と。
やりたいこと
認証ユーザのみ読み書きが行え、anonymous は読み込みもできないような /proj1/protected みたいなディレクトリを作成したい。
設定してみる→失敗
mod_authz_svn はすでに有効になっているようなので、
あたりを参考に設定してみる。
httpd.conf は
<Location /svn/proj1>
AuthzSVNAccessFile /home/svn/proj1/conf/authz
Satisfy Any
Require valid-user
AuthType Basic
AuthName "Subversion Repository(proj1)"
AuthUserFile /home/trac/proj1/trac.htpasswd
</Location>
こうやって。authz は、
[groups] developers = user1,user2,user3 [/] @developers = rw * = r [/protected] @developers = rw * =
こう。
で、http://trac-server/svn/proj1/doc/ や http://trac-server/svn/proj1/protected/ をブラウザから開いてみると・・・anonymous でも普通に見れちゃってる。あれ?
そして http://trac-server/svn/proj1/ にアクセスしてみると・・・403 Forbidden。なにがなにやら。
Apache のエラーログには、/proj1 を開いたタイミングで
[error] The URI does not contain the name of a repository. [403, #190001]
みたいなログが残っている模様。
原因調査
ここで調査にいろいろてこずったんだけど、
状態で確認を取るのが手っ取り早い感じ。
この状態でログを確認すると、/proj1 は前のままだけど、/proj1/doc や /proj1/protected も 403 Forbidden になって、
[error] Access denied: - GET doc:/
[error] Access denied: - GET protected:/
SVNPath を設定してみる→これも失敗
なんかわからないけど、SVNParentPath の設定が邪魔してるみたいなので、
<Location /svn/proj1>
SVNPath /home/svn/proj1
AuthzSVNAccessFile /home/svn/proj1/conf/authz
Satisfy Any
Require valid-user
AuthType Basic
AuthName "Subversion Repository(proj1)"
AuthUserFile /home/trac/proj1/trac.htpasswd
</Location>
みたいにサブディレクトリ側で SVNPath を設定する形に変えてみる。(親ディレクトリの SVNParentPath 設定は残したまま。)
すると、/proj1/protected を開いたタイミングで 403 Forbidden になって、エラーログにも
[error] Access denied: - GET proj1:/protected
と表示される。プロジェクトとパスは正しく認識されているらしい。
でも /proj1 や /proj1/doc を開くと、500 Internal Server Error になってしまって、画面には
<?xml version="1.0" encoding="utf-8"?> <D:error xmlns:D="DAV:" xmlns:m="http://apache.org/dav/xmlns" xmlns:C="svn:"> <C:error/> <m:human-readable errcode="2"> Could not open the requested SVN filesystem </m:human-readable> </D:error>
こんなエラーが出る。そのときのエラーログは、
[error] (20014)Error string not specified yet: Can't open file '/home/svn/svn/format': No such file or directory
[error] Could not fetch resource information. [500, #0]
[error] Could not open the requested SVN filesystem [500, #2]
[error] Could not open the requested SVN filesystem [500, #2]
とかなんとか。パスが /svn/svn みたいになっちゃってるところを見ると、まだ SVNParentPath の設定が悪さしてるのかな。
サブディレクトリでも DAV svn を指定してみる→これまた失敗
ためしに、
<Location /svn/proj1>
DAV svn
SVNPath /home/svn/proj1
AuthzSVNAccessFile /home/svn/proj1/conf/authz
Satisfy Any
Require valid-user
AuthType Basic
AuthName "Subversion Repository(proj1)"
AuthUserFile /home/trac/proj1/trac.htpasswd
</Location>
こう(DAV svn の行を追加)してみた。すると、
- /proj1、/proj1/doc は誰でも閲覧できる
- /proj1/protected は認証後のみ閲覧できる
という期待どおりの動作になった。
・・・と思いきや。svn コマンドでこのリポジトリを利用しようとすると、
svn: コミットに失敗しました (詳しい理由は以下のとおりです):
svn: MKACTIVITY (URL: '/svn/proj1/proj1/!svn/act/b57dd0a8-bf76-0410-9c89-cdc855475c64'): 403 Forbidden (http://trac-server)
とかなんとかエラーになってしまった。proj1/proj1 とかいうパスが出現しているところを見ると、やっぱり SVNParentPath の設定がどこかで生きてて、変な不整合を起こしているらしい。
- ためしに SVNParentPath の記述を消すとうまくいった
- SVNListParentPath On にすると /proj1 でなぜか / 相当の情報(本来のプロジェクト一覧)が見えたりした
という感じ。
その他試したこと
あたりを見ながら Apache の設定をいじってみたけど、すべて失敗。
たとえば「/proj1/proj1/!svn になってるなら、!svn を ../!svn に変えればうまいこといくんじゃね?」と
SVNSpecialURI ../!svn
なんてこともやってみたけど、
Syntax error on line 1106 of /usr/local/apache2/conf/httpd.conf:
SVNSpecialURI not allowed here
こんなエラーになったりとか。まあうまくいっても怪しすぎて困るんだけど。
あきらめた
で、オプション見てて気づいたけど、SVNPath と SVNParentPath は両方指定してはいけないことになってるみたい。すべてのリポジトリで共通の authz を使って、ユーザの制御なんかもそちらでやれって話みたいですね。そうでなければ /svn2 みたいな Location を別途用意して、/svn は SVNParentPath で、/svn は SVNPath で運用するとか。
まあ今回はそこまで手を入れる気はないし、mod_authz_svn を使わずに Apache 側だけで設定しちゃえってことで。最終的にこうなりました。
<Location /svn/proj1> # Limit write permission to list of valid users. AuthType Basic AuthName "Subversion Repository(proj1)" AuthUserFile /home/trac/proj1/trac.htpasswd <LimitExcept GET PROPFIND OPTIONS REPORT> Require valid-user </LimitExcept> </Location> <Location /svn/proj1/protected> Require valid-user </Location>
/proj1/protected 用に個別に設定を持つ形。今回は認証の有無だけで振り分ければいいのでこれでも問題なし。今後ルールが複雑になったら、passwd ファイルを増やしてパスごとに個別に設定する形になるのかな。
・・・とまあ今回は mod_authz_svn の使用はあきらめたんですが、SVNPatentPath 指定でもサブディレクトリ毎に authz を指定できるべきのような・・・。mod_dav_svn のバージョンは 1.3.2 とか結構古いので、もしかしたら最新版で直ってるかも。(一応 changelog は眺めたけど、それっぽいの無かった。)
結局調査に何時間もかけちゃったなぁ。これくらいの時間があれば、ソース読んで仕組みを把握できてたかも。