上次介绍了如何建立一个简单的SVN服务器, 但是这样的SVN服务器没有权限限制,只要是可以访问的人都能对版本库进行修改。 可以说这是绝对不安全,不利于管理的。 这节介绍一下利用Apache提供的基本HTTP认证机制来强化我们的SVN服务管理

svn subversion logo

依旧假定 http服务的根目录在 /srv/http/ , svn的目录在 /srv/http/svn/ ;
为了方便测试权限配置,请禁用SVN凭证缓存,编辑 $HOME/.subversion/config

[auth]
store-auth-creds = no

[这里主要提供示例,详细信息请查看svn手册]

制定目标

为了方便讲解,设定两种不同的管理目标:

  1. 版本库 svntest1 :
    只有具有账户的用户才能访问,其中 harry 具有读写(rw)权限,而 sally 只能干看的份(r);
    (本地目录 /srv/http/svn/svntest1/)
  2. 版本库 svntest2 :
    凡是匿名用户都有查看的权限,而注册用户(sally)皆有读写的权限(rw);
    (本地目录 /srv/http/svn/svntest2/)

设定apache配置档

为了比较细致的设定访问权限,我们在apache的配置文件(httpd.conf)中引入SVN的用户认证模块: mod_authz_svn.so ,那么现在模块的顺序是:

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

    因为上面两种不同的要求,所以我们希望apache首先把任何用户当做匿名用户,当遇到目录权限时,才要求用户提供用户名和密码; 引入权限配置文件, Location 段改为:

<Location /svn/>
DAV svn
SVNParentPath /srv/http/svn

# our access control policy
AuthzSVNAccessFile /etc/httpd/svn/authz

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

# how to authenticate a user
AuthType Basic
AuthName “LD’s Subversion Server”
AuthUserFile /etc/httpd/svn/passwd
# 把配置文件都放 /etc/httpd/ 下,方便管理
</Location>

设定目录(版本库)权限

根据前一步的设定,目录权限配置文件是 /etc/httpd/svn/authz ,密码文件是 /etc/httpd/svn/passwd ; 关于authz文件,在每个版本库目录下的 conf 目录下有简单的示例。

先设置密码

user@~$ sudo htpasswd -c /etc/httpd/svn/passwd harry
user@~$ sudo htpasswd /etc/httpd/svn/passwd sally
# 注意: 第一行 htpasswd 加了参数 -c 表示创建文件,而第二行不加,否则只有sally的密码

修改目录权限配置文件是 /etc/httpd/svn/authz ; 注释: [/]表示你所有代码库的根目录,而[repository:/]表示其中一个名叫“repository”的代码库的根目录。

让我们先来实现管理目标1: 在文件 authz 中这么写

[groups]
# 建立一个group,成员有 harry 和 sally
svntest1 = harry,sally

# 版本库 svntest1 的根目录
[svntest1:/]

# 对整个群组开放可读
@svntest1 = r

# 授予 harry 可读写权限
harry = rw

# 其他人没有权限,空着
* =

好了,看看测试结果:

  1. harry 正常访问,可以修改
    (测试 mkdir、import、delete 执行成功)
  2. sally 能访问,但不能修改
    (list 执行成功; 测试 list、delete 执行失败)
  3. anonymous 不能访问
  4. 浏览器不能访问

看了第一个目标,是不是觉得svn权限配置很简单,继续目标2: 修改文件 authz

[groups]
svntest1 = harry,sally
# 建立群组 svntest2 ,只有一个组员 sally
svntest2 = sally

# 版本库 svntest2 的根目录
[svntest2:/]

# 给自己群组读写权限
@svntest2 = rw
# 当然也可以只把写权限给 sally
# sally = rw

# 其他人只有读权限
* = r

目标2的测试结果:

  1. sally 正常访问,可以修改
    (测试 mkdir、commit、delete 执行成功)
  2. anonymous 和 harry 能访问,但不能修改
    (list执行成功; 测试 delete、commit 执行失败)
  3. 浏览器可以访问

结束语

OK,两个示例over了。 再进行深入目录的权限设置,举一反三即可。 其实 subversion 权限设置还是比较简单的,比vsftpd还单薄许多。 SVN手册上不太建议使用基于路径的访问控制,公司的话,还是这样配置比较简洁; 而且一般还算熟悉Linux的,对这个权限理解应该没有问题。

补遗: 只要在 “Location” 中加入 “SVNListParentPath on” ,就能让浏览器支持版本库列表; 如果考虑安全问题,建议保持默认关闭。