Apache的HTTP服务器是一个Subversion可以利用的“重型”网络服务器,通过一个自定义模块,httpd可以让Subversion版本库通过WebDAV/DeltaV协议在客户端前可见,WebDAV/DeltaV协议是HTTP 1.1的扩展(见 下面的讨论包括了对Apache配置指示的引用,给了一些使用这些指示的例子,详细地描述不在本章的范围之内,Apache小组维护了完美的文档,公开存放在他们的站点 同样,当你修改你的Apache设置,很有可能会出现一些错误,如果你还不熟悉Apache的日志子系统,你一定需要认识到这一点。在你的文件 为了让你的版本库使用HTTP网络,你基本上需要两个包里的四个部分。你需要Apache httpd 2.0和包括的mod_dav DAV模块,Subversion和与之一同分发的mod_dav_svn文件系统提供者模块,如果你有了这些组件,网络化你的版本库将非常简单,如:
你可以通过从源代码编译httpd和Subversion来完成前两个项目,也可以通过你的系统上的已经编译好的二进制包来安装。最新的使用Apache HTTP的Subversion的编译方法和Apache的配置方式可以看Subversion源代码树根目录的 一旦你安装了必须的组件,剩下的工作就是在 LoadModule dav_svn_module modules/mod_dav_svn.so 注意,如果mod_dav是作为共享对象编译(而不是静态链接到httpd程序),你需要为它使用使用 LoadModule dav_module modules/mod_dav.so LoadModule dav_svn_module modules/mod_dav_svn.so 在你的配置文件后面的位置,你需要告诉Apache你在什么地方保存Subversion版本库(也许是多个), <Location /repos> DAV svn SVNPath /absolute/path/to/repository </Location> 如果你计划支持多个具备相同父目录的Subversion版本库,你有另外的选择, <Location /svn> DAV svn # any "/svn/foo" URL will map to a repository /usr/local/svn/foo SVNParentPath /usr/local/svn </Location> 使用上面的语法,Apache会代理所有URL路径部分为 请确定当你定义新的 在本阶段,你一定要考虑访问权限问题,如果你已经作为普通的web服务器运行过Apache,你一定有了一些内容—网页、脚本和其他。这些项目已经配置了许多在Apache下可以工作的访问许可,或者更准确一点,允许Apache与这些文件一起工作。Apache当作为Subversion服务器运行时,同样需要正确的访问许可来读写你的Subversion版本库。(见服务器和访问许可:一个警告。) 你会需要检验权限系统的设置满足Subversion的需求,同时不会把以前的页面和脚本搞乱。这或许意味着修改Subversion的访问许可来配合Apache服务器已经使用的工具,或者可能意味着需要使用 此时,如果你配置的 <Location /svn> DAV svn SVNParentPath /usr/local/svn </Location> 这样你的版本库对全世界是可以“匿名”访问的,直到你配置了一些认证授权政策,你通过
最简单的客户端认证方式是通过HTTP基本认证机制,简单的使用用户名和密码来验证一个用户所自称的身份,Apache提供了一个htpasswd工具来管理可接受的用户名和密码,这些就是你希望赋予Subversion特别权限的用户,让我们给Sally和Harry赋予提交权限,首先,我们需要添加他们到密码文件。 $ ### First time: use -c to create the file $ ### Use -m to use MD5 encryption of the password, which is more secure $ htpasswd -cm /etc/svn-auth-file harry New password: ***** Re-type new password: ***** Adding password for user harry $ htpasswd -m /etc/svn-auth-file sally New password: ******* Re-type new password: ******* Adding password for user sally $ 下一步,你需要在 添加完这三个指示,你的 <Location /svn> DAV svn SVNParentPath /usr/local/svn AuthType Basic AuthName "Subversion repository" AuthUserFile /etc/svn-auth-file </Location> 这个 <Location /svn> DAV svn SVNParentPath /usr/local/svn AuthType Basic AuthName "Subversion repository" AuthUserFile /etc/svn-auth-file Require valid-user </Location> 一定要阅读后面的部分(“授权选项”一节)来得到 需要警惕:HTTP基本认证的密码是用明文传输,因此非常不可靠的,如果你担心密码偷窥,最好是使用某种SSL加密,所以客户端认证使用 商业应用需要越过公司防火墙的版本库访问,防火墙需要小心的考虑非认证用户“吸取”他们的网络流量的情况,SSL让那种形式的关注更不容易导致敏感数据泄露。 如果Subversion使用OpenSSL编译,它就会具备与Subversion服务器使用 怎样产生客户端和服务器端证书以及怎样使用它们已经超出了本书的范围,许多书籍,包括Apache自己的文档,描述这个任务,现在我们可以覆盖的是普通的客户端怎样来管理服务器与客户端证书。 当通过
如果客户端接收了一个服务器证书,它需要去验证它是可以相信的:这个服务器是它自称的那一个吗?OpenSSL库会去检验服务器证书的签名人或者是核证机构(CA)。如果OpenSSL不可以自动信任这个CA,或者是一些其他的问题(如证书过期或者是主机名不匹配),Subversion命令行客户端会询问你是否愿意仍然信任这个证书: $ svn list https://host./repos/project Error validating server certificate for ‘https://host.:443‘: - The certificate is not issued by a trusted authority. Use the fingerprint to validate the certificate manually! Certificate information: - Hostname: host. - Valid: from Jan 30 19:23:56 2004 GMT until Jan 30 19:23:56 2006 GMT - Issuer: CA, , Sometown, California, US - Fingerprint: 7d:e1:a9:34:33:39:ba:6a:e9:a5:c4:22:98:7b:76:5c:92:a0:9c:7b (R)eject, accept (t)emporarily or accept (p)ermanently? 这个对话看起来很熟悉,这是你会在web浏览器(另一种HTTP客户端,就像Subversion)经常看到的问题,如果你选择(p)ermanent选项,服务器证书会存放在你存放那个用户名和密码缓存(见“客户端凭证缓存”一节。)的私有运行区 你的运行中 [global] ssl-authority-files = /path/to/CAcert1.pem;/path/to/CAcert2.pem 许多OpenSSL安装包括一些预先定义好的可以普遍信任的“缺省的”CA,为了让Subversion客户端自动信任这些标准权威,设置 当与Apache通话时,Subversion客户端也会收到一个证书的要求,Apache是询问客户端来证明自己的身份:这个客户端是否是他所说的那一个?如果一切正常,Subversion客户端会发送回一个通过Apache信任的CA签名的私有证书,一个客户端证书通常会以加密方式存放在磁盘,使用本地密码保护,当Subversion收到这个要求,它会询问你证书的路径和保护用的密码: $ svn list https://host./repos/project Authentication realm: https://host.:443 Client certificate filename: /path/to/my/cert.p12 Passphrase for ‘/path/to/my/cert.p12‘: ******** … 注意这个客户端证书是一个“p12”文件,为了让Subversion使用客户端证书,它必须是运输标准的PKCS#12格式,大多数浏览器可以导入和导出这种格式的证书,另一个选择是用OpenSSL命令行工具来转化存在的证书为PKCS#12格式。 再次,运行中 [groups] examplehost = host. [examplehost] ssl-client-cert-file = /path/to/my/cert.p12 ssl-client-cert-password = somepassword 一旦你设置了 此刻,你已经配置了认证,但是没有配置授权,Apache可以要求用户认证并且确定身份,但是并没有说明这个身份的怎样允许和限制,这个部分描述了两种控制访问版本库的策略。 最简单的访问控制形式是授权特定用户为只读版本库访问或者是读/写访问版本库。 你可以通过在 <Location /svn> DAV svn SVNParentPath /usr/local/svn # how to authenticate a user AuthType Basic AuthName "Subversion repository" AuthUserFile /path/to/users/file # only authenticated users may access the repository Require valid-user </Location> 有时候,你不需要这样严密,举个例子,Subversion自己在 在 <Location /svn> DAV svn SVNParentPath /usr/local/svn # how to authenticate a user AuthType Basic AuthName "Subversion repository" AuthUserFile /path/to/users/file # For any operations other than these, require an authenticated user. <LimitExcept GET PROPFIND OPTIONS REPORT> Require valid-user </LimitExcept> </Location> 这里只是一些简单的例子,想看关于Apache访问控制 也可以使用Apache的httpd模块mod_authz_svn更加细致的设置访问权限,这个模块收集客户端传递过来的不同的晦涩的URL信息,询问mod_dav_svn来解码,然后根据在配置文件定义的访问政策来裁决请求。 如果你从源代码创建Subversion,mod_authz_svn会自动附加到mod_dav_svn,许多二进制分发版本也会自动安装,为了验证它是安装正确,确定它是在 LoadModule dav_module modules/mod_dav.so LoadModule dav_svn_module modules/mod_dav_svn.so LoadModule authz_svn_module modules/mod_authz_svn.so 为了激活这个模块,你需要配置你的 Apache非常的灵活,你可以从三种模式里选择一种来配置你的区块,作为开始,你选择一种基本的配置模式。(下面的例子非常简单;见Apache自己的文档中的认证和授权选项来查看更多的细节。) 最简单的区块是允许任何人可以访问,在这个场景里,Apache决不会发送认证请求,所有的用户作为“匿名”对待。 在另一个极端,你可以配置为拒绝所有人的认证,所有客户端必须提供证明自己身份的证书,你通过 第三种流行的模式是允许认证和匿名用户的组合,举个例子,许多管理员希望允许匿名用户读取特定的版本库路径,但希望只有认证用户可以读(或者写)更多敏感的区域,在这个设置里,所有的用户开始时用匿名用户访问版本库,如果你的访问控制策略在任何时候要求一个真实的用户名,Apache将会要求认证客户端,为此,你可以同时使用 一旦你的基本 访问文件的语法与svnserve.conf和运行中配置文件非常相似,以( 具体一点:这个小节的名称是 [calc:/branches/calc/bug-142] harry = rw sally = r 在第一个例子里,用户 当然,访问控制是父目录传递给子目录的,这意味着我们可以为Sally指定一个子目录的不同访问策略: [calc:/branches/calc/bug-142] harry = rw sally = r # give sally write access only to the ‘testing‘ subdir [calc:/branches/calc/bug-142/testing] sally = rw 现在Sally可以读取分支的 也可以通过继承规则明确的的拒绝某人的访问,只需要设置用户名参数为空: [calc:/branches/calc/bug-142] harry = rw sally = r [calc:/branches/calc/bug-142/secret] harry = 在这个例子里,Harry对 有一件事需要记住的是需要找到最匹配的目录,mod_authz_svn模块首先找到匹配自己的目录,然后父目录,然后父目录的父目录,就这样继续下去,更具体的路径控制会覆盖所有继承下来的访问控制。 缺省情况下,没有人对版本库有任何访问,这意味着如果你已经从一个空文件开始,你会希望给所有用户对版本库根目录具备读权限,你可以使用 [/] * = r 这是一个普通的设置;注意在小节名中没有提到版本库名称,这让所有版本库对所有的用户可读,不管你是使用 星号( 访问文件也允许你定义一组的用户,很像Unix的 [groups] calc-developers = harry, sally, joe paint-developers = frank, sally, jane everyone = harry, sally, joe, frank, sally, jane 组可以被赋予通用户一样的访问权限,使用“at”( [calc:/projects/calc] @calc-developers = rw [paint:/projects/paint] @paint-developers = rw jane = r ...并且非常接近。 mod_dav_svn模块做了许多工作来确定你标记为“不可读”的数据不会因意外而泄露,这意味着需要紧密监控通过svn checkout或是svn update返回的路径和文件内容,如果这些命令遇到一些根据认证策略不是可读的路径,这个路径通常会被一起忽略,在历史或者重命名操作时—例如运行一个类似svn cat -r OLD foo.c的命令来操作一个很久以前改过名字的文件 — 如果一个对象的以前的名字检测到是只读的,重命令追踪就会终止。 所有的路径检查在有时会非常昂贵,特别是svn log的情况。当检索一列修订版本时,服务器会查看所有修订版本修改的路径,并且检查可读性,如果发现了一个不可读路径,它会从修订版本的修改路径中忽略(可以查看 在另一方面,也有一个安全舱门允许你用安全特性来交换速度,如果你不是坚持要求有每目录授权(如不使用 mod_authz_svn和类似的模块),你就可以关闭所有的路径检查,在你的 例 6.4. 关闭所有的路经检查 <Location /repos> DAV svn SVNParentPath /usr/local/svn SVNPathAuthz off </Location>
我们已经覆盖了关于认证和授权的Apache和mod_dav_svn的大多数选项,但是Apache还提供了许多很好的特性。 一个非常有用的好处是使用Apache/WebDAV配置Subversion版本库时可以用普通的浏览器察看最新的版本库文件,因为Subversion使用URL来鉴别版本库版本化的资源,版本库使用的HTTP为基础的URL也可以直接输入到Web浏览器中,你的浏览器会发送一个 因为URL不能确定你所希望看到的资源的版本,mod_dav_svn会一直返回最新的版本,这样会有一些美妙的副作用,你可以直接把Subversion的URL传递给文档作为引用,这些URL会一直指向文档最新的材料,当然,你也可以在别的网站作为超链使用这些URL。 你通常会在版本化的文件的URL之外得到更多地用处—毕竟那里是有趣的内容存在的地方,但是你会偶尔浏览一个Subversion的目录列表,你会很快发现展示列表生成的HTML非常基本,并且一定没有在外观上(或者是有趣上)下功夫,为了自定义这些目录显示,Subversion提供了一个XML目录特性,一个单独的 <Location /svn> DAV svn SVNParentPath /usr/local/svn SVNIndexXSLT "/svnindex.xsl" … </Location> 使用 Apache作为一个健壮的Web服务器的许多特性也可以用来增加Subversion的功能性和安全性,Subversion使用Neon与Apache通讯,这是一种一般的HTTP/WebDAV库,可以支持SSL和Deflate压缩(是gzip和PKZIP程序用来“压缩”文件为数据块的一样的算法)之类的机制。你只需要编译你希望Subversion和Apache需要的特性,并且正确的配置程序来使用这些特性。 Deflate压缩给服务器和客户端带来了更多地负担,压缩和解压缩减少了网络传输的实际文件的大小,如果网络带宽比较紧缺,这种方法会大大提高服务器和客户端之间发送数据的速度,在极端情况下,这种最小化的传输会造成超时和成功的区别。 不怎么有趣,但同样重要,是Apache和Subversion关系的一些特性,像可以指定自定义的端口(而不是缺省的HTTP的80)或者是一个Subversion可以被访问的虚拟主机名,或者是通过代理服务器访问的能力,这些特性都是Neon所支持的,所以Subversion轻易得到这些支持。 最后,因为mod_dav_svn是使用一个半完成的WebDAV/DeltaV方言,所以通过第三方的DAV客户端访问也是可能的,几乎所有的现代操作系统(Win32、OS X和Linux)都有把DAV服务器影射为普通的网络“共享”的内置能力,这是一个复杂的主题;察看附录 C, WebDAV和自动版本化来得到更多细节。 |
|