基于ssl和ldap的SVN工具安装指南
为了提升账户管理的便捷和安全性,公司在本人的建议下决定从NIS升级到LDAP。研究了2个星期,终于完成了LDAP服务器的搭建,并和SVN整合了起来。期间查找了很多资料,但多半无用,居然没有一个文档是可以完整搭建成功的。一时感慨,资料泛滥的年代,能找出几个像样的还真不容易。因此,贴出最近搭建的完整步骤,期望能给需要的人士一些帮助。有问题的地方,还请大家多多指教。
lneon-0.29.6.tar.tar
下载地址:http://www.webdav.org/neon/
lapr-1.4.6.tar.gz
下载地址:http://apr.apache.org/download.cgi
lapr-util-1.4.1.tar.gz
下载地址:http://apr.apache.org/download.cgi
lopenssl-1.0.0g.tar
下载地址:http://openssl.org.com
lserf-0.3.0.tar.bz2
下载地址:http://serf.googlecode.com/
lhttpd-2.2.22.tar
下载地址:http://httpd.apache.org/download.cgi
lsubversion-1.6.18.tar.gz、subversion-deps-1.6.18.tar.gz
下载地址:www.subversion.org.cn
Subversion英文版安装说明:http://svn.collab.net/repos/svn/trunk/INSTALL
l配置环境
操作系统版本:RHEL x86_64 AS 4.6(5.8也测试通过)
LDAP服务器版本:Red_Hat_Diretory_Server-8.0
l说明
neon、serf、apr、apr-util具体功能就不阐述了,全部是subversion需要的,其实subversion本身的源码包里面有,不过在某些情况下使用自己下载的会更好一些,这是我使用别的工具和SVN集成后发现的,使用自带的包无法编译,因此,建议使用上面的版本。换而言之,这些版本是经过测试能够完美整合的。
非常重要,如果不卸载,apache将无法编译安装。
# yum remove httpd apr apr-util
或者
# rpm -e --allmatches apr-{version}
# rpm -e apr-util-{version}
# rpm -e httpd
以下安装步骤都不做累述,源码包的安装是基本常识,查看安装包的INSTALL文件,按部就班即可。
# tar xzvf APR-1.4.6.tar.gz
# cd apr-1.4.6
# ./configure --prefix=/usr/local/apr
# make
# make install
# tar xzvf APR-util-1.4.1.tar.gz
# cd apr-util-1.4.1
#./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr
# make
# make install
# tar zxvfopenssl-1.0.0g.tar.gz
# cd openssl-1.0.0g
#./config --shared
# make
# make test
# make install
# echo /usr/local/ssl/lib >> /etc/ld.so.conf
# ldconfig
# tar xzvf httpd-2.2.22.tar.gz
# cd httpd-2.2.22
#./configure \
--prefix=/usr/local/apache2 \
--enable-so \
--enable-rewrite=share \
--enable-proxy=share \
--enable-proxy-ajp=share \
--enable-dav=share \
--enable-dav-fs \
--enable-mods-shared=all \
--enable-ssl=static \
--enable-ldap \
--enable-authnz-ldap \
--with-ldap \
--with-included-apr \
--with-apr=/usr/local/apr \
--with-apr-util=/usr/local/apr-util/ \
--with-ssl=/usr/local/ssl/
# make
# make install
# tar xzvf subversion-1.6.18.tar.gz
# tar xzvf subversion-deps-1.6.18.tar.gz
# tar xzvf neon-0.29.6.tar.gz
# tar xjvf serf-0.3.0.tar.bz2
# cd subversion-1.6.18
# rm -rf apr apr-util neon serf
# cp -ar ../neon-0.29.6 neon
# cp -ar ../serf-0.3.0 serf
# chown -R 1000:users neon serf
# ./configure \
--prefix=/usr/local/subversion \
--with-apxs=/usr/local/apache2/bin/apxs \
--with-ssl \
--with-apr=/usr/local/apr \
--with-apr-util=/usr/local/apr-util \
--with-zlib=/usr/lib64
# make && make install
装完之后执行/usr/local/subversion/bin/svn --version检查是否出现以下信息:
svn, version1.6.18 (r1303927)
compiled Aug 22 2012, 10:32:42
Copyright (C)2000-2009 CollabNet.
Subversion is opensource software, see http://subversion.apache.org/
This productincludes software developed by CollabNet (http://www.Collab.Net/).
The followingrepository access (RA) modules are available:
* ra_neon : Modulefor accessing a repository via WebDAV protocol using Neon.
- handles 'http'scheme 支持http
- handles 'https'scheme 支持https
* ra_svn : Modulefor accessing a repository using the svn network protocol.
- with Cyrus SASL authentication
- handles 'svn' scheme
* ra_local :Module for accessing a repository on local disk.
- handles 'file' scheme
# mkdir /usr/local/apache2/conf/crt; cd /usr/local/apache2/conf/crt
# openssl genrsa -out server-dsa.key 1024
# openssl req -new -x509 -days3650 -key server-dsa.key -out server-dsa.crt
//在httpd-ssl-conf中需指定这两个文件的存放位置
# vi /usr/local/apache2/conf/httpd.conf //取消如下内容的注释
Include conf/extra/httpd-ssl.conf
在配置文件末尾添加如下内容
<Location /svn>
DAV svn
SVNParentPath /home/subversion/project
AuthType Basic
AuthName "Subversion repository"
AuthUserFile /home/subversion/passwd
AuthzSVNAccessFile /home/subversion/auth
Require valid-user
</Location>
其中:
SVNParentPath后面跟的是 (此处配置你的版本库根目录).在这里,版本库根目录假设为/home/subversion/project
AuthName 后面跟的(是提示对话框标题)
AuthUserFile 跟的是(访问版本库用户的文件,须用apache 的 htpasswd命令生成)
AuthzSVNAccessFile后面跟的是(访问版本库权限的文件)
# vi /usr/local/apache2/conf/extra/httpd-ssl.conf
改三个地方
1、SSLCertificateFile"/usr/local/apache2/conf/crt/server-dsa.crt" //指定到生成的证书
2、SSLCertificateKeyFile"/usr/local/apache2/conf/crt/server-dsa.key" //指定到生成的证书
3、SSLCACertificatePath"/usr/local/apache2/conf/crt"
重启web服务
/usr/local/apache2/bin/apachectl restart
假设版本仓库的根目录为/home/subversion/projecrt
所以,先创建这个目录 mkdir -p /home/subversion/project
根目录创建完毕,下面我们创建一个叫data的仓库。 /usr/local/subversion/bin/svnadmincreate /home/subversion/project/data
注意命令的全路径。如果仅仅敲svnadmin将会用到系统自带的svn,会有报错信息。
查看data文件夹会发现多了一些像conf,dav等这类的文件,说明建库成功(注意:创建仓库的路径中,路径目录必须为所有人可读,否则采用svn客户端访问仓库时会失败。)
# mkdir -p /home/subversion/project/data/dav/activities.d
# chown -R o+w /home/subversion/project/data/
这时系统会提示你要求你输入密码,以及确认密码,输入即可,创建的用户就是Subversion的用户。但是,仅仅是创建了用户还是不行的,必须得给他授权才可以。
先在根目录创建授权文件。(注意:htpasswd -cm命令生成用户密码时会将passwd文件中原有的密码给覆盖掉,因此,如果创建多个用户,需要将-cm参数后边的文件指定到一个临时文件,然后将临时文件中的内容cp到passwd文件)
#vi /home/subversion/auth
输入如下内容:
[data:/] 指的是访问data仓库(可以具体到下面的子目录)
test1=rw test1有读和写权限
test2=r test2有只读的权限,只读权限的设置不能为ro。
还可以细化用户的详细目录路径:
[data:/trunk/FrontEnd/code]
test2=rw
结合上面对user1权限的设置,综合权限的结果是:test2对/data仓库有读取权限,没有写权限,但是对/data仓库下的/data/trunk/FrontEnd/code目录有读取和写的权限。
# su - test1
$ mkdir -p test/a/b/c
$ /usr/local/subversion/bin/svn import test https://192.168.1.198/svn/data/test -m "add test dir"
# vi /usr/local/apache2/conf/httpd.conf
将之前的配置注释掉。添加如下信息:
<Location /svn>
DAV svn
SVNParentPath /home/subversion/project
AuthzSVNAccessFile /home/subversion/auth
# Authentication
AuthType Basic
AuthName "SVN_repository"
AuthBasicProvider ldap
Require valid-user
AuthzLDAPAuthoritative off
AuthLDAPURL "ldap://192.168.1.226:389/DC=example,DC=com,DC=cn?uid?sub?(objectClass=*)"
</Location>
#/usr/local/apache2/bin/apachectl restart
在浏览器中输入https://localhost/svn/data
回车会出现svn登录的验证窗口,提示输入帐号和密码,帐号就是上面创建的subversion用户,输入帐号和密码之后,如果出现下面窗口,则说明subversion的安装成功了。
在服务器端可以使用终端:
svn checkout https://localhost/svn/data将data仓库checkout出来。
Svn客户端:
Svn客户端需要安装apr-1.2.12和apr-util-1.2.12,否则svn客户端不能checkout仓库。
CollabNetSubversion-client-1.5.6-1.i386.rpm
CollabNetSubversion-extras-1.5.6-1.i386.rpm
CollabNetSubversion-server-1.5.6-1.i386.rpm
ldap认证配置如下:
<Location/svn>
# 开启Subversion
DAV svn
# 包含所有版本库的路径
SVNParentPath /home/subversion/project
#Access file for Subversion Repository
AuthzSVNAccessFile /home/subersion/project/auth
# 使用基本的密码认证
AuthType Basic
# 弹出的对话框的库名
AuthName "Subversion repository"
# Authentication Provider is LDAP
AuthBasic Providerldap
# 绑定ldap认证用户(可以不要,则采用匿名用户,ldap默认是匿名查询)
AuthLDAPBindDN "CN=ldapadmin,OU=systemadmin,DC=example,DC=com,DC=cn"
# 绑定ldap认证用户的密码(上面用户如果没有设置,这一条则取消)
AuthLDAPBindPassword ins.key.ok00
# TheLDAP query URL
#Format: scheme://host:port/basedn?attribute?scope?filter
# TheURL below will search for all objects recursively below the basedn
# andvalidate against the sAMAccountName attribute
AuthLDAPURL "ldap://192.168.1.226:389/DC=example,DC=com,DC=cn?uid?sub?(objectClass=*)"
#Require authentication for this Location ,Requires that mod_authz_user beloaded and that # theAuthzLDAPAuthoritative off
Requirevalid-user
# LDAPAuthentication & Authorization is final; do not check other databases
#Prevent other authentication modules from authenticating the user if this onefails
AuthzLDAPAuthoritative off
</Location>
在认证的过程中,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 whensearching for entries. If not provided, mod_authnz_ldapwill use an anonymous bind.
原来,刚才说到认证的第一步是对LDAP目录进行搜索。其实AuthLDAPBindDN和AuthLDAPBindPassword所对应的就是搜索这个操作的bind。如果没有配置这两兄弟的话,httpd会使用匿名bind来搜索目录。为了不让LDAP的密码以明文的形式出现在配置文件中,考拉强烈建议在httpd.conf中不要使用这两个配置项。考拉的LDAP服务可是允许匿名绑定的哦~(当然匿名bind只有读取的权限,不过对于search操作而言,足够了呀)。
#ldap://是LDAP通讯的方式;ldapserver:389是LDAP的服务器名或IP地址,389为LDAP协议的端口;ou是组织单元(如果下面还有ou的话,应该在此后面再加上ou=xxx,用逗号隔开);dc=后面跟域名,有多少点就有多少dc=xxx,也要用逗号隔开,再举个例子LDAP服务器名为shanghai.domain.com.cn,那shanghai应该是主机的实际名字,domain.com.cn才是真正的域名,参数应该是这样"ldap://shanghai.domain.com.cn:389/ou=developer,dc=domain,dc=com,dc=cn?sAMAccountName?sub?(objectClass=*)";sAMAccountName?sub?(objectClass=*)参数是指明所有验证的是windows域中独特的帐户形式sam
当basedn不写OU,仅仅写后面的DC时,需要将389端口修改成3268。
TheAuthzLDAPAuthoritative offdirective will letauthentication fall through to the next module only if the user cannot bematched to a DN in the query. Currently even though the user is expired, itseems that their account will still be returned as a result when the LDAP queryis performed.
I don't knowenough about the ActiveDirectory LDAP schema to give a definite answer here,but if you could add a filter to your AuthLDAPURL directivethat filters out expired accounts it should result in the username not matchingany DN in the query. This should result in the authentication falling throughto the next module.
或许需要:
# AuthLDAPGroupAttributeIsDN on
# Require ldap-group CN=ldapadmin,OU=systemadmin,DC=example,DC=com,DC=cn
# AuthLDAPGroupAttribute memberUid
- Require ldap-groupcn=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比较和谐。