Linux SVNServer搭建,并支持https访问

liuxueping 2015-02-14

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.rpm28-Mar-200918:57267K

sqlite-3.5.9-2.x86_64.rpm28-Mar-200918:51547K

subversion-1.6.12-1.rhel5.x86_64.rpm19-Jun-201019:583.6M

mod_dav_svn-1.6.12-1.rhel5.x86_64.rpm19-Jun-201019:58261K

前两个是依赖包,第三个是主安装包,第四个是用于支持http访问的包(参考文章中还安装了dev包,本人实践中未安装,不影响使用)

安装过程如下:

首先检查SVN版本并卸载旧的版本

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

[root@testbed1svn]#rpm-qa|grepsubversion

[root@testbed1bin]#rpm-esubversion-1.4.2-4.el5

error:"subversion-1.4.2-4.el5"specifiesmultiplepackages

[root@testbed1bin]#rpm-e--allmatchessubversion-1.4.2-4.el5

[root@testbed1svn]#rpm-ivhsubversion-1.6.12-1.rhel5.x86_64.rpm

error:Faileddependencies:

libneon.so.27()(64bit)isneededbysubversion-1.6.12-1.x86_64

neon>=0.26.1isneededbysubversion-1.6.12-1.x86_64

sqlite>=3.4isneededbysubversion-1.6.12-1.x86_64

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

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

[root@testbed1svn]#rpm-Uvhsqlite-3.5.9-2.x86_64.rpm

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

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

[root@testbed1svn]#rpm-Uvhneon-0.28.4-1.x86_64.rpm

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

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

[root@testbed1svn]#rpm-ivhsubversion-1.6.12-1.rhel5.x86_64.rpm

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

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

[root@testbed1svn]#rpm-Uvhmod_dav_svn-1.6.12-1.rhel5.x86_64.rpm

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

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

最后安装验证

[root@testbed1~]#svnserve--version

svnserve,version1.6.12(r955767)

compiledJun192010,10:46:32

Copyright(C)2000-2009CollabNet.

Subversionisopensourcesoftware,seehttp://subversion.tigris.org/

ThisproductincludessoftwaredevelopedbyCollabNet(http://www.Collab.Net/).

Thefollowingrepositoryback-end(FS)modulesareavailable:

*fs_base:ModuleforworkingwithaBerkeleyDBrepository.

*fs_fs:Moduleforworkingwithaplainfile(FSFS)repository.

CyrusSASLauthenticationisavailable.

2.建立版本库,并实现svn://方式访问

本段参考:http://www.linuxde.net/2011/06/138.html

#mkdir/svndata创建svn数据目录(目录可自行制定)

#svnadmincreate/svndata/kumingkuming就是版本库的名字,可以改变!

配置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服务器

#killallsvnserve

#psaux|grepsvnserve查看服务,端口: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模块。

需要添加的内容如下:

LoadModuledav_modulemodules/mod_dav.so

LoadModuledav_svn_modulemodules/mod_dav_svn.so

<Location/kuming>

DAVsvn

SVNPath/svndata/kuming

</Location>

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

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

<Location/svn>

DAVsvn

SVNParentPath/svndata

</Location>

"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

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

<Location/svn>

DAVsvn

SVNParentPath/svndata

#Authentication:Digest

AuthName"Subversionrepository"

AuthTypeDigest

AuthDigestProviderfile

AuthUserFile/etc/svn-auth.htdigest

#Authorization:Authenticatedusersonly

Requirevalid-user

</Location>

Thepasswordfilecanbecreatedasfollows:(以下命令中"Subversionrepository"就是上面的AuthName)

$###Firsttime:use-ctocreatethefile

$htdigest-c/etc/svn-auth.htdigest"Subversionrepository"harry

AddingpasswordforharryinrealmSubversionrepository.

Newpassword:*****

Re-typenewpassword:*****

$htdigest/etc/svn-auth.htdigest"Subversionrepository"sally

AddingusersallyinrealmSubversionrepository

Newpassword:*******

Re-typenewpassword:*******

$

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

4.配置路径访问策略

可以使用Apache的mod_authz_svn模块对每个目录进行认证操作。修改httpd.conf文件,添加

LoadModuleauthz_svn_modulemodules/mod_authz_svn.so

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

<Location/svn>

DAVsvn

SVNParentPath/svndata

#Authentication:Digest

AuthName"Subversionrepository"

AuthTypeDigest

AuthDigestProviderfile

AuthUserFile/etc/svn-auth.htdigest

AuthzSVNAccessFile/svndata/conf/authz

#Authorization:Authenticatedusersonly

Requirevalid-user

</Location>

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命令)

opensslgenrsa-des3-outmy-server.key1024

Loading'screen'intorandomstate-done

GeneratingRSAprivatekey,1024bitlongmodulus

.....++++++

........++++++

eis65537(0x10001)

Enterpassphraseforserver.key:********

Verifying-Enterpassphraseforserver.key:********

命令运行期间需要用户输入并确认自己的密码。

现在,我们需要SSL的认证证书,证书是由CA(certificateauthority)发放并且认证的。一般情况下,如果Subversion的用户不是太多,安全情况不是很复杂,我们也可以生成一个自签名的认证证书,从而省去了向CA申请认证的麻烦。如下命令:

(以下openssl可使用绝对路径/usr/bin/openssl,openssl.cnf文件也可使用绝对路径/etc/ssl/openssl.cnf或/usr/lib/ssl/openssl.cnf,根据实际情况选择)

opensslreq-new-keymy-server.key-x509-outmy-server.crt-configopenssl.cnf

CountryName(2lettercode)[GB]:

StateorProvinceName(fullname)[Berkshire]:

LocalityName(eg,city)[Newbury]:

OrganizationName(eg,company)[MyCompanyLtd]:

OrganizationalUnitName(eg,section)[]:

CommonName(eg,yournameoryourserver'shostname)[]:此处输入主机名

EmailAddress[]:

以上两个命令都需要用户输入那个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模块加入其中:

LoadModulessl_modulemodules/mod_ssl.so

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

SSLMutexdefault

SSLRandomSeedstartupbuiltin

SSLSessionCachenone

ErrorLoglogs/SSL.log

LogLevelinfo

<VirtualHostip地址:443>

SSLEngineOn

SSLCertificateFileconf/ssl/my-server.crt

SSLCertificateKeyFileconf/ssl/my-server.key

</VirtualHost>

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

<Location/svn>

DAVsvn

SVNParentPath/svndata

#Authentication:Digest

AuthName"Subversionrepository"

AuthTypeDigest

AuthDigestProviderfile

AuthUserFile/etc/svn-auth.htdigest

AuthzSVNAccessFile/svndata/conf/authz

SSLRequireSSL

#Authorization:Authenticatedusersonly

Requirevalid-user

</Location>

此时目录授权可以实现如下要求,当策略文件中有以下策略时

[/branches/dev/subfolder]

user0=rw

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

6.系统权限问题

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

Can'topenfile'/xx/xxx/db/txn-current-lock':Permissiondenied

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

7.证书与主机名不匹配问题

如果查看/var/log/httpd/ssl_error_log文件,发现如下错误日志

RSAservercertificateCommonName(CN)`localhost.localdomain'doesNOTmatchservername!?

可能是因为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/opensslrsa-in/path/to/originalkeywithpass.key-out/path/to/newkeywithnopass.key

使用新的key文件就无需输入密码启动了。

参考:https://wiki.apache.org/httpd/RemoveSSLCertPassPhrase

参考文章中还有另一种解决方式,基本原理是在服务启动要求密码时以脚本方式自动响应一个密码,从而实现无需手动输入密码的目的。

相关推荐