Linux SVNServer搭建,并支持https访问

1.Subversion安装过程
参考http://blog.csdn.net/zhaiqi618/article/details/5741060
安装包下载地址,SVN版本1.6.12 :

http://the.earth.li/pub/subversion/summersoft.fay.ar.us/pub/subversion/latest/1.6.12/rhel5/x86_64/

neon-0.28.4-1.x86_64.rpm 28-Mar-2009 18:57 267K
sqlite-3.5.9-2.x86_64.rpm 28-Mar-2009 18:51 547K

subversion-1.6.12-1.rhel5.x86_64.rpm 19-Jun-2010 19:58 3.6M

mod_dav_svn-1.6.12-1.rhel5.x86_64.rpm 19-Jun-2010 19:58 261K
前两个是依赖包,第三个是主安装包,第四个是用于支持http访问的包(参考文章中还安装了dev包,本人实践中未安装,不影响使用)
安装过程如下:
首先检查SVN版本并卸载旧的版本

以root用户上传svn安装包到服务器并尝试安装。

# rpm -qa | grep subversion

# rpm -e subversion-1.4.2-4.el5

error: "subversion-1.4.2-4.el5" specifies multiple packages



# rpm -e --allmatches subversion-1.4.2-4.el5

# rpm -ivh subversion-1.6.12-1.rhel5.x86_64.rpm

error: Failed dependencies:

libneon.so.27()(64bit) is needed by subversion-1.6.12-1.x86_64

neon >= 0.26.1 is needed by subversion-1.6.12-1.x86_64

sqlite >= 3.4 is needed by subversion-1.6.12-1.x86_64


此时直接安装subversion提示包依赖未满足,于是要升级neon及sqlite

先升级sqlite,请注意,rpm管理本身对sqlite有依赖,所以不能卸载sqlite,如果卸载,会出现rpm命令不可用的问题,最好直接升级至最新版本的sqlite。

# rpm -Uvh sqlite-3.5.9-2.x86_64.rpm

Preparing... ########################################### [100%]

1:sqlite ########################################### [100%]

# rpm -Uvh neon-0.28.4-1.x86_64.rpm

Preparing... ########################################### [100%]

1:neon ########################################### [100%]

# rpm -ivh subversion-1.6.12-1.rhel5.x86_64.rpm

Preparing... ########################################### [100%]

1:subversion ########################################### [100%]

# rpm -Uvh mod_dav_svn-1.6.12-1.rhel5.x86_64.rpm

Preparing... ########################################### [100%]

1:mod_dav_svn ########################################### [100%]


最后安装验证

# svnserve --version

svnserve, version 1.6.12 (r955767)

compiled Jun 19 2010, 10:46:32



Copyright (C) 2000-2009 CollabNet.

Subversion is open source software, see http://subversion.tigris.org/

This product includes software developed by CollabNet (http://www.Collab.Net/).



The following repository back-end (FS) modules are available:



* fs_base : Module for working with a Berkeley DB repository.

* fs_fs : Module for working with a plain file (FSFS) repository.



Cyrus SASL authentication is available.


2. 建立版本库,并实现svn://方式访问
本段参考:http://www.linuxde.net/2011/06/138.html
# mkdir /svndata 创建svn数据目录(目录可自行制定)
# svnadmin create /svndata/kuming kuming就是版本库的名字,可以改变!

配置svn配置文件(为了方便管理,这里多个库调用相同的配置文件。)

#每个版本库创建之后都会生成svnserve.conf主配文件
# vim /svndata/kuming/conf/svnserve.conf

[general]
anon-access = none
auth-access = write
password-db = /svndata/conf/passwd
authz-db = /svndata/conf/authz
realm = kuming

# mkdir /svndata/conf
# vim /svndata/conf/passwd //svn用户配置文件

[users]
user1 = password1
user2 = password2
user3 = password3
user4 = password4

# vim /svndata/conf/authz //svn权限控制配置文件

[groups]    #设置组
group1 = user1,user2  #多用户用逗号隔开

[/]       #根目录权限设置(就是“kuming”这个文件夹)
user3 = rw   #用户1权限是:可读写
user4 = r    #用户2权限是:可读,不可写
user =      #什么都没写代表没有任何权限

@group1 = rw  #设置组权限

[kuming:/123]  #设置根目录下“123”文件夹的权限
#说明“123”这个文件件怎么创建?这是在SVN服务器配置好之后,创建一个权限很高的用户在客户端登录SVN
#然后创建一个文件夹“123”。

启动服务器

# svnserve -d -r /svndata
-d表示以daemon方式(后台运行)运行
-r /svndata指定根目录是/svndata
关闭SVN 服务器
# killall svnserve

# ps aux | grep svnserve 查看服务,端口:3690

客户端使用的软件是TortoiseSVN,浏览方法:打开版本库浏览器输入:svn://ip-addr/kuming/文件夹名


至此已经基本实现一个SVNServer,但此时只能使用svn://协议访问,且对版本库中路径的访问授权策略很简单,很难满足实际需求。如想要给某用户只访问子目录/aaa/bbb/ccc的权限,必须给其访问父目录的权限,即必须至少给其根目录的读权限,但实际中我们不希望这样,因为我们不想让该用户访问其它目录,虽然可以通过复杂的策略达到目的,但不利于维护。比如随着时间发展,当增加新目录时,必须针对新目录写相应的授权策略。

好消息是,如果使用http协议访问SVN,则不会出现上面的情况。即给某用户访问某子目录的权限时不需要给其父目录的访问权限。下面介绍如何实现http访问SVN。

3.配置httpd,实现http访问
参考http://svnbook.red-bean.com/nightly/en/svn.serverconfig.httpd.html#svn.serverconfig.httpd.authn.digest
http://www.ibm.com/developerworks/cn/java/j-lo-apache-subversion/
接下来就是配置 Apache 的 httpd.conf 文件,让 Apache 在启动的时候加载dav模块。

需要添加的内容如下:

LoadModule dav_module modules/mod_dav.so
LoadModule dav_svn_module modules/mod_dav_svn.so

DAV svn
SVNPath /svndata/kuming


首先需要启用 dav_module,然后加载 dav_svn_module。Location 标签指出访问的 URL 以及在服务器上的实际位置。配置完毕后重新启动 Apache(service httpd restart),打开浏览器,输入 http://服务器IP/kuming 即可访问SVN服务器。

如果想要指定多个版本库,可以用多个 Location 标签,也可以使用 SVNParentPath 代替 SVNPath,例如在 /svndata 下有多个版本库 repos1,repos2 等等,用如下方式指定:


DAV svn
SVNParentPath /svndata


"SVNParentPath /svndata" 表示 /etc/svn 下的每个子目录都是一个版本库。可以通过 http://服务器IP/svn/repos1,http://服务器IP/svn/repos2 来访问。


此时任何人都可以访问版本库(http://方式不使用svn://方式的用户认证机制,且不需要启动svnserve),并且有完全的写操作权限。也就是说任何人都可以匿名读取,修改,提交,以及删除版本库中的内容。下面介绍如何进行认证,参考:http://svnbook.red-bean.com/nightly/en/svn.serverconfig.httpd.html#svn.serverconfig.httpd.authn.digest

上面的官网中提到两种认证方式,Basic authentication和Digest authentication。此处直接介绍第二种方式,


DAV svn
SVNParentPath /svndata

# Authentication: Digest
AuthName "Subversion repository"
AuthType Digest
AuthDigestProvider file
AuthUserFile /etc/svn-auth.htdigest

# Authorization: Authenticated users only
Require valid-user


The password file can be created as follows:(以下命令中"Subversion repository"就是上面的AuthName)

$ ### First time: use -c to create the file
$ htdigest -c /etc/svn-auth.htdigest "Subversion repository" harry
Adding password for harry in realm Subversion repository.
New password: *****
Re-type new password: *****
$ htdigest /etc/svn-auth.htdigest "Subversion repository" sally
Adding user sally in realm Subversion repository
New password: *******
Re-type new password: *******
$

重启apache服务即可实现以http方式访问SVN时进行认证。此时仅实现了对用户的认证,还未实现对目录的授权。

4. 配置路径访问策略
可以使用 Apache 的 mod_authz_svn 模块对每个目录进行认证操作。修改 httpd.conf 文件,添加
LoadModule authz_svn_module modules/mod_authz_svn.so

现在可以在 Location 标签中使用 authz 的功能了。一个基本的 authz 配置如下:

DAV svn
SVNParentPath /svndata

# Authentication: Digest
AuthName "Subversion repository"
AuthType Digest
AuthDigestProvider file
AuthUserFile /etc/svn-auth.htdigest

AuthzSVNAccessFile /svndata/conf/authz

# Authorization: Authenticated users only
Require valid-user

AuthzSVNAccessFile 指向的是 authz 的策略文件,详细的权限控制可以在这个策略文件中指定。

此时已经实现认证及授权功能,当策略文件中有以下策略时
[/branches/dev/subfolder]
user0 = rw

用户user0只能访问subfolder目录及其子目录,这样基本满足开发需要,但还不完美,且还未实现如文章标题所写的https方式访问。

5.用 SSL 实现安全的网络传输
参考:http://www.ibm.com/developerworks/cn/java/j-lo-apache-subversion/
SSL 的证书和密钥
首先,我们需要找到 openssl 程序及其配置文件 openssl.cnf,运行如下命令来生成 128 位的 RSA 私有密钥文件
my-server.key:(以下openssl命令建议使用绝对路径/usr/bin/openssl,因为有此软件包也包含openssl命令)
openssl genrsa -des3 -out my-server.key 1024
Loading 'screen' into random state - done
Generating RSA private key, 1024 bit long modulus
.....++++++
........++++++
e is 65537 (0x10001)
Enter pass phrase for server.key:********
Verifying - Enter pass phrase for server.key:********
命令运行期间需要用户输入并确认自己的密码。
现在,我们需要 SSL 的认证证书,证书是由 CA(certificate authority) 发放并且认证的。一般情况下,如果 Subversion 的用户不是太多,安全情况不是很复杂,我们也可以生成一个自签名的认证证书,从而省去了向 CA 申请认证的麻烦。如下命令:
(以下openssl可使用绝对路径/usr/bin/openssl, openssl.cnf文件也可使用绝对路径/etc/ssl/openssl.cnf或/usr/lib/ssl/openssl.cnf,根据实际情况选择)

openssl req -new -key my-server.key -x509 -out my-server.crt -config openssl.cnf

Country Name (2 letter code) [GB]:
State or Province Name (full name) [Berkshire]:
Locality Name (eg, city) [Newbury]:
Organization Name (eg, company) [My Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:此处输入主机名
Email Address []:

以上两个命令都需要用户输入那个 key 文件的密码,以及一些网络设置信息,如域名,邮箱等等,这里输入的服务器域名应该与 Apache 配置文件当中的一致。现在,我们可以在 Apache 的 conf 目录下新建一个 ssl 目录,将 my-server.key 和 my-server.crt 文件都移动到 ssl 目录里面。然后修改 ssl.conf 文件,将 SSLCertificateKeyFile 和 SSLCertificateFile 项指向这两个文件。(原文如此,实际中不需要)

如果 Apache 的 module 目录里面没有 mod_ssl.so 文件,可以将事先准备好的文件拷贝过去。然后,我们可以设置 Apache 的配置文件 httpd.conf,将 ssl 模块加入其中:

LoadModule ssl_module modules/mod_ssl.so

然后,在配置文件 httpd.conf的最后,加上如下 SSL 相关配置项:

SSLMutex default
SSLRandomSeed startup builtin
SSLSessionCache none
ErrorLog logs/SSL.log
LogLevel info

SSLEngine On
SSLCertificateFile conf/ssl/my-server.crt
SSLCertificateKeyFile conf/ssl/my-server.key


这样,基本的设置工作就完成了。重新启动 Apache 服务器,现在可以用 https 协议代替 http 协议来访问版本库了。如果要限定版本库只能用 https 访问,我们可以在 Apache 配置文件当中 Subversion 部分加上 “SSLRequireSSL”。如下:


DAV svn
SVNParentPath /svndata

# Authentication: Digest
AuthName "Subversion repository"
AuthType Digest
AuthDigestProvider file
AuthUserFile /etc/svn-auth.htdigest

AuthzSVNAccessFile /svndata/conf/authz

SSLRequireSSL

# Authorization: Authenticated users only
Require valid-user


此时目录授权可以实现如下要求,当策略文件中有以下策略时
[/branches/dev/subfolder]
user0 = rw

用户user0只能访问subfolder目录及其子目录,不能访问父目录且看不到父目录其它子目录。

6. 系统权限问题
目前为止还没完,因为linux文件系统权限问题,在提交代码时有可能遇到类似如下错误:

Can't open file '/xx/xxx/db/txn-current-lock':Permission denied

这可能是因为SVN库文件是使用root用户创建的,apache应用无写权限请尝试执行 chmod -R o+w /xx/xxx命令(其中/xx/xxx是SVN仓库文件地址),立即生效。如果问题还未解决,请google其它解决方案。

7.证书与主机名不匹配问题
如果查看/var/log/httpd/ssl_error_log文件,发现如下错误日志
RSA server certificate CommonName (CN) `localhost.localdomain' does NOT match server name!?

可能是因为mod_ssl模块默认加载了/etc/pki/tls/certs/localhost.crt证书,解决方法是修改conf.d/ssl.conf配置文件,将其中virtualhost 部分配置删除,重启httpd服务即可。
参考:http://stackoverflow.com/questions/19153353/see-server-name-according-to-ssl-certificates

8. 启动时免输密码
当配置使用ssl方式启动httpd服务后,每次启动都需要输入密码,这样就不能使服务开机自启动。
一种解决方法是生成免密码的key文件,方法如下:

/path/to/openssl rsa -in /path/to/originalkeywithpass.key -out /path/to/newkeywithnopass.key

使用新的key文件就无需输入密码启动了。
参考:https://wiki.apache.org/httpd/RemoveSSLCertPassPhrase
参考文章中还有另一种解决方式,基本原理是在服务启动要求密码时以脚本方式自动响应一个密码,从而实现无需手动输入密码的目的。

你可能感兴趣的:(SVN)