众所周知,SVN的repository可以使用自带的 svnserve或者apache httpd两种途径来访问。使用apache httpd管理对SVN的访问的好处是:可以利用httpd已有的模块控制对SVN的认证(authentication)和授权(authorization),其中就包括了本人梦寐以求的用LDAP目录服务的帐户来登录SVN。如此一来,所有和用户帐户和组相关的信息都可以集中保存在LDAP中啦!和管理到处存在的类似passwd和groups的文件相比,这样做岂不是激动人心?

    如何配置和往LDAP里添加用户帐户以及安装SVN这些内容考拉就不包括在这篇文章里了。考拉一直使用的是CentOS系统,这点一方面是因为它和RHEL的极高兼容性,另外也是受了鸟哥的影响拉:P

    在LDAP配置完成并正常运行之后,我们就要编辑httpd的配置文件了/etc/httpd/conf/httpd.conf。首先我们要保证需要的module在httpd启动的时候都能够成功加载,找到文件里LoadModule集中的那些行,然后确保mod_ldap, mod_authnz_ldap和mod_dav_svn都存在:

    LoadModule ldap_module modules/mod_ldap.so
    LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
    LoadModule dav_svn_module modules/mod_dav_svn.so
    我们可以认为:

- mod_ldap是httpd和LDAP进行交互所以需要的库。

- mod_authnz_ldap是控制LDAP认证和授权的模块,它依赖mod_ldap。它之所以叫authnz是因为这个模块同时实现了authentication和authorization。

- mod_dav_svn则是httpd用来操作svn repository的模块。

 

    然后我们在httpd.conf中添加如下内容,以实现对svn访问的认证和授权:

<Location /repos>
    DAV svn
    SVNParentPath /var/svn
    SVNListParentPath on
    SVNReposName "Xin Liu's Home SVN"
    # authentication
    AuthType Basic
    AuthName "xliu.home.svn"
    AuthBasicProvider ldap
    #AuthLDAPBindDN "CN=root,DC=xliu-home,DC=org"
    #AuthLDAPBindPassword MyLdapPasswdInPlainText
    AuthLDAPURL http://www.cnblogs.com/livepencil/admin/ldap://localhost:389/DC=xliu-home,DC=org?uid?sub?(objectClass=*)"
    # authorization
    AuthLDAPGroupAttributeIsDN on
    Require ldap-group cn=SVNUsers,ou=Group,dc=xliu-home,dc=org
    AuthLDAPGroupAttribute memberUid
</Location>

    让考拉先从authentication(认证)来说起。

    在认证的过程中,httpd首先在LDAP目录中搜索客户端提供的用户名(通过AuthLDAPURL配置如何搜索),假如未找到,则认证失败;如果搜索到,则尝试使用客户端提供的用户名和密码来bind LDAP,如果bind成功则认证通过。

    在我们的httpd.conf文件中,AuthLDAPBindDN和AuthLDAPBindPassword也是用来bind到LDAP服务的。考拉一开始对此迷惑了好久,不是说用httpd客户端提供的用户名和密码来bind LDAP的么,怎么这里又有个bind?httpd的官方文档对AuthLDAPBindDN是如此描述的:

    An optional DN used to bind to the server when searching for entries. If not provided, mod_authnz_ldap will use an anonymous bind.

    原来,刚才说到认证的第一步是对LDAP目录进行搜索。其实AuthLDAPBindDN和AuthLDAPBindPassword所对应的就是搜索这个操作的bind。如果没有配置这两兄弟的话,httpd会使用匿名bind来搜索目录。为了不让LDAP的密码以明文的形式出现在配置文件中,考拉强烈建议在httpd.conf中不要使用这两个配置项。考拉的LDAP服务可是允许匿名绑定的哦~(当然匿名bind只有读取的权限,不过对于search操作而言,足够了呀)。

 

    在authentication中获取了用户的DN之后,接下来httpd要做的就是authorization(授权)的步骤了。

    在这里不得不先点一下LDAP目录中的一个细节。在posixAccount中,每个用户帐户有一个gidNumber的属性,它表明了该用户的primary group ID number。所以每个用户只能有一个gidNumber:

# yyd, People, xliu-home.org
dn: uid=yyd,ou=People,dc=xliu-home,dc=org
uid: yyd
cn: YeYouDan
objectClass: account
objectClass: posixAccount
objectClass: top
loginShell: /bin/bash
homeDirectory: /home/yyd
gidNumber: 901
uidNumber: 902
    在这里901的gid对应了PowerUsers组:

# PowerUsers, Group, xliu-home.org
dn: cn=PowerUsers,ou=Group,dc=xliu-home,dc=org
objectClass: posixGroup
objectClass: top
cn: PowerUsers
gidNumber: 901
memberUid: 900 

    这样看起来很直观,但是等等,如果yyd这个用户不仅仅隶属于PowerUsers组,考拉还想让她属于SVNUsers组,那该怎么办?办法照样很简单很直观,在SVNUsers这个组上,添加一个memberUid属性就可以了,注意这个属性可以有多个值哦:

# SVNUsers, Group, xliu-home.org
dn: cn=SVNUsers,ou=Group,dc=xliu-home,dc=org
cn: SVNUsers
gidNumber: 903
objectClass: posixGroup
objectClass: top
memberUid: uid=xliu,ou=People,dc=xliu-home,dc=org
memberUid: uid=yyd,ou=People,dc=xliu-home,dc=org

    通常memberUid中保存的都是用户的DN,httpd默认也是这么设置的。当然你也可以把它设置为uid的值。这样一来,SVNUsers就成为了yyd用户的secondary group。

    好了,讲了这么多LDAP的内容,让我们再回过头来看看httpd.conf:

    - Require ldap-group cn=SVNUsers,ou=Group,dc=xliu-home,dc=org:这条配置告诉httpd,客户端提供的用户,必须隶属于SVNUsers这个组,注意这里一定要使用DN。

    - AuthLDAPGroupAttribute memberUid:它告诉httpd去读取LDAP中SVNUsers这个组记录的memberUid属性来和客户端提供的用户DN来比较。

    - AuthLDAPGroupAttributeIsDN on:它告诉httpd,memberUid这个属性里保存的是隶属于该组的用户的DN,httpd就会根据客户端提供的用户名和密码来寻找匹配的用户记录DN,再用这条DN来匹配SVNUsers组的memberUid属性的值。考拉在这个配置项上吃了点苦头,因为它默认值是on,所以简单注解掉该条配置项是没有用的,必须显式地把它设置为off。如果我们设置成off,那么就可以将LDAP中SVNUsers的memberUid设置成yyd了,不过考拉认为还是用memberUid来存储DN比较和谐。

    好了,现在保存httpd.conf并且启动apache服务器,在浏览器里输入网址http://%3cmyserver%3e/repos,看看svn是不是能像你希望的那样来访问了?

 

posted on 2010-06-15 18:46  考拉留  阅读(4624)  评论(0编辑  收藏  举报