当前位置: 首页 > 图文教程 > 服务器 > Linux服务器 > Apache和Subversion搭建安全CVS
Linux服务器 中的 Apache和Subversion搭建安全CVS
作为新一代的开源版本控制工具,Subversion以其目录版本化、原子提交、版本化的元数据、更加有效的分支和标签等优良特性,正逐渐受到开源软件社区的重视,并有望取代CVS,成为开源软件开发中版本控制的首选系统。在服务器端,Subversion最大的独特之处,在于它可以通过一个扩展模块与Apache的HTTP服务器相结合,实现很多高级的管理功能和安全特性。与CVS相比,Subversion实现了更加先进和安全的用户认证功能。在Apache的支持下,用户可以通过HTTP协议访问版本库,管理员可以对用户访问HTTP的权限做出具体的设置,同时Subversion还可以获得SSL传输加密,用户数据加密,以及目录级的访问控制等特性。
本文将在服务器端配置工作的角度,结合作者在实际开发工作当中的配置实例,介绍Subversion服务器端的基本配置和管理,以及如何将Subversion与Apache结合,实现一些高级管理功能。
在开源软件的开发过程当中,由于开发方式自由和开发人员分散这些特性,版本控制问题一直是关系到项目成败的重要问题。没有版本控制系统的支持,开源软件的开发过程就是混乱和不可控制的。
长期以来,CVS作为一种普遍采用的开源版本控制工具,在很多的开源软件项目当中充当了重要的角色。在Eclipse当中,更是把CVS作为一个默认的插件,与Ant,JUnit等工具并列在一起,成为Eclipse软件开发的基本工具。近年来,随着开源社区的发展,一种功能更加强大的开源版本控制工具逐渐进入了人们的视野,那就是Subversion,凭借着更为优秀的特性,Subversion正在逐步取代CVS,成为新一代的开源版本控制工具。
相比CVS,Subversion中的目录、文件以及改名等元数据都是被版本化的,例如文件的改名、拷贝等等操作;而且,在Subversion中,提交操作是不可分割的,修订版本号是基于每次提交操作而非文件;另外,Subversion可以独立运行,有着轻量级的分支(Branching)与标签(Tagging)操作,版本库可以采用数据库(BerkeleyDB)或者是使用特定格式的文件进行存储,对二进制文件进行处理更为有效;最后,Subversion工具以及相关插件都有着很好的国际化支持,可以支持包括简体中文在内的多种语言版本,方便全球各地的开发人员。这些优秀的新特性,使得Subversion成为开源社区目前的最佳选择。
对于普通用户,即应用程序开发者而言,尤其是对Eclipse的用户而言,Subversion的使用十分的简单。通过官方提供的Eclipse插件Subclipse,用户可以在Eclipse里面很方便的使用Subversion客户端的各项基本功能。具体的客户端设置和使用方法,请参考Subversion官方网站和Subclipse官方网站。简单说来,在Eclipse中使用Subversion插件的基本功能,如更新、提交、同步、分支等等,基本上同使用Eclipse自带的CVS插件一模一样,这样,用户就可以从CVS方便的转移到Subversion。
目前,Subversion已经升级到1.3.2版本,相关下载、特性说明和详细使用手册可以在Subversion主页上找到。
有了简单易用的客户端,大部分的用户都可以轻松使用Subversion了,不过,作为服务器端的管理人员,还必须进一步了解服务器端的基本配置管理,才可以充分利用Subversion的各项优秀特性。
Subversion的版本库(repository),就是位于服务器端,统一管理和储存数据的地方。本文中,我们以Linux为例,介绍在服务器端配置和管理Subversion版本库的基本方法。
要创建一个版本库,首先要确定采用哪种数据存储方式。在Subversion中,版本库的数据存储有两种方式,一种是在BerkeleyDB数据库中存放数据;另一种是使用普通文件,采用自定义的格式来储存,称为FSFS。
两种存放方式各有优缺点,读者可以参考http://svnbook.org/上面的文档来了解两者详细的比较和区别,这里,我们仅引用上述文档当中的简单对照表,给出一个简明的比较。
确定了具体的数据存储类型,只要在命令行当中执行svnadmin命令就可以创建一个Subversion版本库,命令如下
如果一切正常,命令执行后不会有任何反馈信息而迅速返回,这样,一个新的版本库就被创建出来了。我们来查看一下生成的版本库结构:
其中,conf目录下存放了版本库的配置文件,包括用户访问控制和权限控制等内容,文件本身的注释说明十分详细,读者可以根据注释自行配置;dav目录是提供给Apache相关模块的目录,目前为空;db目录下存放着Subversion所要管理的所有受版本控制的数据,不同的存储方式(BerkeleyDB或者FSFS)下有着不同的目录结构,不过我们一般不用直接修改和查看这个目录下的内容,Subversion的命令可以安全的操作这个目录;另外,hooks目录存放着钩子脚本及其模版(一种版本库事件触发程序),locks目录存放着Subversion版本库锁定数据,format文件记录了版本库的布局版本号。
有了新建的版本库,就可以往里面添加项目了。不过,管理员必须考虑的问题是,应该将每一个项目分别放在不同的版本库里面,还是应该将它们放在统一的版本库里面。统一的版本库可以让管理员更加容易的升级和备份,不过,由于访问权限控制是针对整个版本库的,所以,统一的版本库也为不同项目配置不同的访问权限带来了麻烦。所以,管理员应该根据实际情况权衡考虑。
我们以统一的版本库为例,添加两个项目project_luni和project_test。要做到这个,最好的办法就是用svnimport命令导入已有的目录树。
首先,我们在一个临时目录下,根据Subversion版本控制的一般布局结构,创建出两个项目的主要目录树,如下:
然后,用svnimport命令来进行项目的导入:
作为版本库管理员,我们经常需要查看Subversion版本库的状况,这就需要一些“只读”的查看工具。
在上述项目导入完成以后,我们可以用svnlist确认导入的项目是否正确:
另外,如果要查看最新修订版本的信息,可以使用svnlookinfo命令:
命令输出了这个版本库的最新修订版本信息,包括作者、时间、日志字数和日志内容等。除开最新修订版以外,我们还可以在命令后面接上“--revision版本号”来指定某一个修订版的显示。
另外,我们还可以用如下命令来显示版本库的具体树形结构,后面的“--show-ids”选项指定显示每一个显示元素的修改版本ID。
这里有一个需要新手,尤其是习惯了Subversion客户端命令“svn”的用户注意的问题,那就是,“svnadmin”和“svnlook”都被认为是服务器端的管理工具,只被用于版本库所在的机器,用来检查和维护版本库,不能通过网络来执行任务。所以,试图将URL甚至本地file路径传递给这两个程序,都是错误的。
Subversion还有很多管理工具可供管理员应用,需要了解这项工具的使用方法,读者们可以用svnhelp,svnadminhelp,svnlookhelp等等命令查看帮助信息,另外,Subversion参考手册提供了更为全面和详细的使用介绍。
Subversion设计了一个抽象的网络层,版本库建立完毕之后,可以通过各种服务器向外公布。svnserve是Subversion自带的一个小型的服务器,它使用独立的协议与客户端。我们可以通过
作为inetd启动或者
作为守护进程启动一个服务。服务器启动后,客户端即可以通过绝对路径访问。如上例可以访问svn://服务器IP/etc/svn/repos。同时可以指定一些选项,常用的如-r,用来指定版本库的根路径,例如假设版本库位于/etc/svn/repos:
svnserve可以通过配置svnserve.conf来进行一些简单的访问权限控制。你可以在版本库的conf子文件夹下发现这个文件。文件的初始内容大致如下:
其中anon-access表示匿名用户的权限,auth-access表示认证用户的权限设置,password-db指向保存用户帐号密码的文件的位置,可以使用相对路径。svnserve只能对全局提供简单的访问控制,如果想要更加灵活的方式,可以使用ApacheHttpServer作为向外公布版本库的方式。
通过Http协议访问版本库是Subversion的亮点之一。使用Http协议意味着只需要打开浏览器,输入URL即可轻松的浏览整个版本库。灵活通常带来复杂性,Http方式相对于svnserve方式来说需要更多的配置。
由于Subversion需要版本化的控制,因此标准的Http协议不能满足需求。要让Apache与Subversion协同工作,需要使用WebDAV(Web分布式创作和版本控制)。WebDAV是HTTP1.1的扩展,关于WebDAV的规范和工作原理,可以参考IETFRFC2518。
为了使Subversion与dav模块通信,需要安装mod_dav_svn插件,可以在Subversion的安装目录中找到。将其拷贝到Apache安装目录的modules文件夹下。接下来就是配置Apache的httpd.conf文件,让Apache在启动的时候加载上述模块。
需要添加的内容如下:
首先需要启用dav_module,然后加载dav_svn_module。Location标签指出访问的URL以及在服务器上的实际位置。配置完毕后重新启动Apache,打开浏览器,输入http://服务器IP/repos将会看到如下画面:
这表示Apache的dav_svn模块已经可以正常工作了。用户可以使用任何一种Subversion的客户端通过Http协议访问你的版本库。
如果想要指定多个版本库,可以用多个Location标签,也可以使用SVNParentPath代替SVNPath,例如在/etc/svn下有多个版本库repos1,repos2等等,用如下方式指定:
"SVNParentPath/etc/svn"表示/etc/svn下的每个子目录都是一个版本库。可以通过http://服务器IP/repos/repos1,http://服务器IP/repos/repos2来访问。
现在你的版本库任何人都可以访问,并且有完全的写操作权限。也就是说任何人都可以匿名读取,修改,提交,以及删除版本库中的内容。显然大部分场合这是不符合需求的。那么如何进行权限设置呢,Apache提供了基本的权限设置:
首先需要创建一个用户文件。Apache提供了一个工具htpasswd,用于生成用户文件,可以在Apache的安装目录下找到。具体使用方法如下:
如果passwordfile不存在,可以加上-c选项让htpasswd新建一个。创建好的文件内容是用户名加上密码的MD5密文。
接下来修改httpd.conf,在Location标签中加入如下内容:
重新启动Apache,打开浏览器访问版本库。Apache会提示你输入用户名和密码来认证登陆了,现在只有passwordfile文件中设定的用户才可以访问版本库。也可以配置只有特定用户可以访问,替换上述"Requirevalid-user"为"Requireusertonyrobert"将只有tony和robert可以访问该版本库。
有的时候也许不需要这样严格的访问控制,例如大多数开源项目允许匿名的读取操作,而只有认证用户才允许写操作。为了实现更为细致的权限认证,可以使用Limit和LimitExcept标签。例如:
如上配置将使匿名用户有读取权限,而限制只有passwordfile中配置的用户可以使用写操作。如果这还不能满足你的要求,可以使用Apache的mod_authz_svn模块对每个目录进行认证操作。
首先需要让Apache将mod_authz_svn模块加载进来。在Subversion的安装目录中找到mod_auth_svn模块,将其拷贝到Apache安装目录的modules子目录下。修改httpd.conf文件,找到
在其后面加上
现在可以在Location标签中使用authz的功能了。一个基本的authz配置如下:
AuthzSVNAccessFile指向的是authz的策略文件,详细的权限控制可以在这个策略文件中指定,如:
使用SVNParentPath代替SVNPath来指定多个版本库的父目录时,其中所有的版本库都将按照这个策略文件配置。例如上例中tony将对所有版本库里的/tags目录具有读写权限。如果要对具体每个版本库配置,用如下的语法:
这样项目1的committer组只能对repos1版本库下的文件具有写权限而不能修改版本库repos2,同样项目2的commiter也不能修改repos1版本库的文件。
到目前为止我们的用户名密码文件还是以文本文件形式存放在文件系统中的,出于安全性的需要或者单点登陆等可扩展性的考虑,文本文件的管理方式都不能满足需求了。通过Apache的module_auth_mysql模块,我们可以用MySQL来保存用户信息。该模块的主页在http://modauthmysql.sourceforge.net/,你也可以在http://modules.apache.org/找到它的发行版本。安装方法同上述Apache的模块一样,拷贝至modules目录并在httpd.conf文件中添加如下语句:
相应的Location区域改写为:
然后在mysql中添加名为svn的数据库,并建立users数据表:
在users表中插入用户信息
重新启动Apache,在访问版本库的时候Apache就会用mysql数据表中的用户信息来验证了。
通过Apache的网络链接,版本库中的代码和数据可以在互联网上传输,为了避免数据的明文传输,实现安全的版本控制,需要对数据的传输进行加密。Apache提供了基于SSL的数据传输加密模块mod_ssl,有了它,用户就可以用https协议访问版本库,从而实现数据的加密传输了。SSL协议及其实现方式,是一个非常复杂的话题,本文只是介绍Apache提供的最基本的SSL配置方法,更加详细的介绍内容,请参考http://httpd.apache.org/docs-2.0/ssl/上的文档。
开始配置前,我们需要一个实现Apache中SSL模块的动态程序库,通常名为mod_ssl.so,及其配置文件,通常名为ssl.conf。这个实现是跟Apache的版本相关的,不匹配的版本是不能用的;而且,并不是每一个Apache的版本都自带了相关实现文件,很多情况下,我们需要自己去搜寻相关文件。另外,我们还需要OpenSSL软件及其配置文件,来生成加密密钥和数字证书。这里,我们可以使用一些免费网站,如http://hunter.campbus.com/上提供的集成版本的Apache。
有了相关的工具和文件,我们就可以开始生成SSL的证书和密钥了。首先,我们需要找到openssl程序及其配置文件openssl.cnf,运行如下命令来生成128位的RSA私有密钥文件
命令运行期间需要用户输入并确认自己的密码。
现在,我们需要SSL的认证证书,证书是由CA(certificateauthority)发放并且认证的。为此,我们可以用如下命令生成一个CSR(CertificateSigningRequest)文件发给CA,从而得到CA的认证:
当然,一般情况下,如果Subversion的用户不是太多,安全情况不是很复杂,我们也可以生成一个自签名的认证证书,从而省去了向CA申请认证的麻烦。如下命令:
以上两个命令都需要用户输入那个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模块加入其中:
然后,在配置文件的最后,加上如下SSL相关配置项:
这样,基本的设置工作就完成了。重新启动Apache服务器,现在可以用https协议代替http协议来访问版本库了。如果要限定版本库只能用https访问,我们可以在Apache配置文件当中Subversion部分加上“SSLRequireSSL”。如下:
Subversion以其优良的版本控制功能,灵活的网络访问模型,以及与Apache服务器联合配置所带来的更强大的管理控制功能,逐渐在开源软件开发的实践当中得到广泛的应用。本文重点介绍了Subversion服务器端的配置以及与Apache服务器联合配置的基本步骤和简单应用,实现了简单的实例应用。读者如果想要进一步了解相关信息,请参考文章后面列出的相关资料。
原文链接:http://www-128.ibm.com/developerworks/cn/java/j-lo-apache-subversion/index.html
评论 (0) All