5.httpd,Apache的HTTP服务器

Posted on Posted in 7.服务配置

httpd,Apache的HTTP服务器

Apache的HTTP服务器是一个Subversion可以利用的“重型”网络服务器,通过一个自定义模块,httpd可以让Subversion版本库通过WebDAV/DeltaV协议在客户端前可见,WebDAV/DeltaV协议是HTTP 1.1的扩展(见http://www.webdav.org/来查看详细信息)。这个协议利用了无处不在的HTTP协议是广域网的核心这一点,添加了写能力—更明确一点,版本化的写—能力。结果就是这样一个标准化的健壮的系统,作为Apache
 2.0软件的一部分打包,被许多操作系统和第三方产品支持,网络管理员也不需要打开另一个自定义端口。 [40]这样一个Apache-Subversion服务器具备了许多svnserve没有的特性,但是也有一点难于配置,灵活通常会带来复杂性。

下面的讨论包括了对Apache配置指示的引用,给了一些使用这些指示的例子,详细地描述不在本章的范围之内,Apache小组维护了完美的文档,公开存放在他们的站点http://httpd.apache.org。例如,一个一般的配置参考位于 http://httpd.apache.org/docs-2.0/mod/directives.html

同样,当你修改你的Apache设置,很有可能会出现一些错误,如果你还不熟悉Apache的日志子系统,你一定需要认识到这一点。在你的文件httpd.conf里会指定Apache生成的访问和错误日志(CustomLogErrorLog指示)的磁盘位置。Subversion的mod_dav_svn使用Apache的错误日志接口,你可以浏览这个文件的内容查看信息来查找难于发现的问题根源。

为什么是 Apache 2?

如果你系统管理员,很有可能是你已经运行了Apache服务器,并且有一些高级经验。写本文的时候,Apache

 1.3是Apache最流行的版本,这个世界因为许多原因而放缓升级到2.X系列:如人们害怕改变,特别是像web服务器这种重要的变化,有些人需要一些在Apache
 1.3 API下工作的插件模块,在等待2.X的版本。无论什么原因,许多人会在首次发现Subversion的Apache模块只是为Apache
2  API写的后开始担心。

对此问题的适当反应是:不需要担心,同时运行Apache 1.3和Apache 2非常简单,只需要安装到不同的位置,用Apache 2作为Subversion的专用服务器,并且不使用80端口,客户端可以访问版本库时在URL里指定端口:

$ svn checkout http://host.example.com:7382/repos/project …

                   

先决条件

为了让你的版本库使用HTTP网络,你基本上需要两个包里的四个部分。你需要Apache httpd2.0和包括的mod_dav DAV模块,Subversion和与之一同分发的mod_dav_svn文件系统提供者模块,如果你有了这些组件,网络化你的版本库将非常简单,如:

  • 配置好httpd 2.0,并且使用mod_dav启动,

  • 为mod_dav安装mod_dav_svn插件,它会使用Subversion的库访问版本库,并且

  • 配置你的httpd.conf来输出(或者说暴露)版本库。

你可以通过从源代码编译httpd和Subversion来完成前两个项目,也可以通过你的系统上的已经编译好的二进制包来安装。最新的使用Apache HTTP的Subversion的编译方法和Apache的配置方式可以看Subversion源代码树根目录的INSTALL文件。

基本的 Apache 配置

一旦你安装了必须的组件,剩下的工作就是在httpd.conf里配置Apache,使用LoadModule来加载mod_dav_svn模块,这个指示必须先与其它Subversion相关的其它配置出现,如果你的Apache使用缺省布局安装,你的mod_dav_svn模块一定在Apache安装目录(通常是在/usr/local/apache2)的modules子目录,LoadModule指示的语法很简单,影射一个名字到它的共享库的物理位置:

LoadModule dav_svn_module     modules/mod_dav_svn.so

       

注意,如果mod_dav是作为共享对象编译(而不是静态链接到httpd程序),你需要为它使用LoadModule语句,一定确定它在mod_dav_svn之前:

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

       

在你的配置文件后面的位置,你需要告诉Apache你在什么地方保存Subversion版本库(也许是多个),位置指示有一个很像XML的符号,开始于一个开始标签,以一个结束标签结束,配合中间许多的其它配置。Location指示的目的是告诉Apache在特定的URL以及子URL下需要特殊的处理,如果是为Subversion准备的,你希望可以通过告诉Apache特定URL是指向版本化的资源,从而把支持转交给DAV层,你可以告诉Apache将所有路径部分(URL中服务器名称和端口之后的部分)以/repos/开头的URL交由DAV服务提供者处理。一个DAV服务提供者的版本库位于/absolute/path/to/repository,可以使用如下的httpd.conf语法:

<Location /repos>   DAV svn   SVNPath /absolute/path/to/repository </Location>

       

如果你计划支持多个具备相同父目录的Subversion版本库,你有另外的选择,SVNParentPath指示,来表示共同的父目录。举个例子,如果你知道会在/usr/local/svn下创建多个Subversion版本库,并且通过类似http://my.server.com/svn/repos1http://my.server.com/svn/repos2的URL访问,你可以用后面例子中的httpd.conf配置语法:

<Location /svn>   DAV svn   # any "/svn/foo" URL will map to a repository /usr/local/svn/foo   SVNParentPath /usr/local/svn </Location>

       

使用上面的语法,Apache会代理所有URL路径部分为/svn/的请求到Subversion的DAV提供者,Subversion会认为SVNParentPath指定的目录下的所有项目是真实的Subversion版本库,这通常是一个便利的语法,不像是用SVNPath指示,我们在此不必为创建新的版本库而重启Apache。

请确定当你定义新的Location,不会与其它输出的位置重叠。例如你的主要DocumentRoot/www,不要把Subversion版本库输出到<Location /www/repos>,如果一个请求的URI是/www/repos/foo.c,Apache不知道是直接到repos/foo.c访问这个文件还是让mod_dav_svn代理从Subversion版本库返回foo.c。服务器返回的结果通常是301 Moved Permanently

服务器名称和复制请求

Subversion利用COPY请求类型来执行服务器端的文件和目录拷贝,作为一个健全的Apache模块的一部分,拷贝源和拷贝的目标通常坐落在同一个机器上,为了满足这个需求,你或许需要告诉mod_dav服务器主机的名称,通常你可以使用httpd.confServerName指示来完成此目的。

ServerName svn.example.com

         

如果你通过NameVirtualHost指示使用Apache的虚拟主机,你或许需要ServerAlias指示来指定额外的名称,再说一次,可以查看Apache文档的来得到更多细节。

在本阶段,你一定要考虑访问权限问题,如果你已经作为普通的web服务器运行过Apache,你一定有了一些内容—网页、脚本和其他。这些项目已经配置了许多在Apache下可以工作的访问许可,或者更准确一点,允许Apache与这些文件一起工作。Apache当作为Subversion服务器运行时,同样需要正确的访问许可来读写你的Subversion版本库。

你会需要检验权限系统的设置满足Subversion的需求,同时不会把以前的页面和脚本搞乱。这或许意味着修改Subversion的访问许可来配合Apache服务器已经使用的工具,或者可能意味着需要使用httpd.confUserGroup指示来指定Apache作为运行的用户和Subversion版本库的组。并不是只有一条正确的方式来设置许可,每个管理员都有不同的原因来以特定的方式操作,只需要意识到许可关联的问题经常在为Apache配置Subversion版本库的过程中被疏忽。

认证选项

此时,如果你配置的httpd.conf保存如下的内容

<Location /svn>   DAV svn   SVNParentPath /usr/local/svn </Location>

       

…这样你的版本库对全世界是可以“匿名”访问的,直到你配置了一些认证授权政策,你通过Location指示来使Subversion版本库可以被任何人访问,换句话说,

  • 任何人可以使用Subversion客户端来从版本库URL取出一个工作拷贝(或者是它的子目录),

  • 任何人可以在浏览器输入版本库URL交互浏览的方式来查看版本库的最新修订版本,并且

  • 任何人可以提交到版本库。

当然,你也许已经设置了pre-commit钩子来防止提交(见“实现版本库钩子”一节),但是就像你读到的,也可以使用Apache内置的方法来限制访问。

基本HTTP认证

最简单的客户端认证方式是通过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 $

         

下一步,你需要在httpd.confLocation区里添加一些指示来告诉Apache如何来使用这些密码文件,AuthType指示指定系统使用的认证类型,这种情况下,我们需要指定Basic认证系统,AuthName是你提供给认证域一个任意名称,大多数浏览器会在向用户询问名称和密码的弹出窗口里显示这个名称,最终,使用AuthUserFile指示来指定使用htpasswd创建的密码文件的位置。

添加完这三个指示,你的<Location>区块一定像这个样子:

<Location /svn>   DAV svn   SVNParentPath /usr/local/svn   AuthType Basic   AuthName "Subversion repository"   AuthUserFile /etc/svn-auth-file </Location>

         

这个<Location>区块还没有结束,还不能做任何有用的事情,它只是告诉Apache当需要授权时,要去向Subversion客户端索要用户名和密码。我们这里遗漏的,是一些告诉Apache什么样客户端需要授权的指示。哪里需要授权,Apache就会在哪里要求认证,最简单的方式是保护所有的请求,添加Require valid-user来告诉Apache任何请求需要认证的用户:

<Location /svn>   DAV svn   SVNParentPath /usr/local/svn   AuthType Basic   AuthName "Subversion repository"   AuthUserFile /etc/svn-auth-file   Require valid-user </Location>

         

一定要阅读后面的部分(“授权选项”一节)来得到Require的细节,和授权政策的其他设置方法。

需要警惕:HTTP基本认证的密码是用明文传输,因此非常不可靠的,如果你担心密码偷窥,最好是使用某种SSL加密,所以客户端认证使用https://而不是http://,为了方便,你可以配置Apache为自签名认证。 [41]参考Apache的文档(和OpenSSL文档)来查看怎样做。

SSL 证书管理

商业应用需要越过公司防火墙的版本库访问,防火墙需要小心的考虑非认证用户“吸取”他们的网络流量的情况,SSL让那种形式的关注更不容易导致敏感数据泄露。

如果Subversion使用OpenSSL编译,它就会具备与Subversion服务器使用https://的URL通讯的能力,Subversion客户端使用的Neon库不仅仅可以用来验证服务器证书,也可以必要时提供客户端证书,如果客户端和服务器交换了SSL证书并且成功地互相认证,所有剩下的交流都会通过一个会话关键字加密。

怎样产生客户端和服务器端证书以及怎样使用它们已经超出了本书的范围,许多书籍,包括Apache自己的文档,描述这个任务,现在我们可以覆盖的是普通的客户端怎样来管理服务器与客户端证书。

当通过https://与Apache通讯时,一个Subversion客户端可以接收两种类型的信息:

  • 一个服务器证书

  • 一个客户端证书的要求

如果客户端接收了一个服务器证书,它需要去验证它是可以相信的:这个服务器是它自称的那一个吗?OpenSSL库会去检验服务器证书的签名人或者是核证机构(CA)。如果OpenSSL不可以自动信任这个CA,或者是一些其他的问题(如证书过期或者是主机名不匹配),Subversion命令行客户端会询问你是否愿意仍然信任这个证书:

$ svn list https://host.example.com/repos/project Error validating server certificate for 'https://host.example.com:443':  - The certificate is not issued by a trusted authority. Use the    fingerprint to validate the certificate manually! Certificate information:  - Hostname: host.example.com  - Valid: from Jan 30 19:23:56 2004 GMT until Jan 30 19:23:56 2006 GMT  - Issuer: CA, example.com, 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选项,服务器证书会存放在你存放那个用户名和密码缓存(见“客户端凭证缓存”一节。)的私有运行区auth/中,缓存后,Subversion会自动记住在以后的交流中信任这个证书。

你的运行中servers文件也会给你能力可以让Subversion客户端自动信任特定的CA,包括全局的或是每主机为基础的,只需要设置ssl-authority-files为一组逗号隔开的PEM加密的CA证书列表:

[global] ssl-authority-files = /path/to/CAcert1.pem;/path/to/CAcert2.pem

         

许多OpenSSL安装包括一些预先定义好的可以普遍信任的“缺省的”CA,为了让Subversion客户端自动信任这些标准权威,设置ssl-trust-default-catrue

当与Apache通话时,Subversion客户端也会收到一个证书的要求,Apache是询问客户端来证明自己的身份:这个客户端是否是他所说的那一个?如果一切正常,Subversion客户端会发送回一个通过Apache信任的CA签名的私有证书,一个客户端证书通常会以加密方式存放在磁盘,使用本地密码保护,当Subversion收到这个要求,它会询问你证书的路径和保护用的密码:

$ svn list https://host.example.com/repos/project Authentication realm: https://host.example.com:443 Client certificate filename: /path/to/my/cert.p12 Passphrase for '/path/to/my/cert.p12':  ******** …

         

注意这个客户端证书是一个“p12”文件,为了让Subversion使用客户端证书,它必须是运输标准的PKCS#12格式,大多数浏览器可以导入和导出这种格式的证书,另一个选择是用OpenSSL命令行工具来转化存在的证书为PKCS#12格式。

再次,运行中servers文件允许你为每个主机自动响应这种要求,单个或两条信息可以用运行参数来描述:

[groups] examplehost = host.example.com [examplehost] ssl-client-cert-file = /path/to/my/cert.p12 ssl-client-cert-password = somepassword

         

一旦你设置了ssl-client-cert-filessl-client-cert-password参数,Subversion客户端可以自动响应客户端证书请求而不会打扰你。[42]

授权选项

此刻,你已经配置了认证,但是没有配置授权,Apache可以要求用户认证并且确定身份,但是并没有说明这个身份的怎样允许和限制,这个部分描述了两种控制访问版本库的策略。

整体访问控制

最简单的访问控制形式是授权特定用户为只读版本库访问或者是读/写访问版本库。

你可以通过在<Location>区块添加Require valid-user指示来限制所有的版本库操作,使用我们前面的例子,这意味着只有客户端只可以是harry或者sally,而且他们必须提供正确的用户名及对应密码,这样允许对Subversion版本库做任何事:

<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自己在http://svn.collab.net/repos/svn的源代码允许全世界的人执行版本库的只读操作(例如检出我们的工作拷贝和使用浏览器浏览版本库),但是限定只有认证用户可以执行写操作。为了执行特定的限制,你可以使用LimitLimitExcept配置指示,就像Location指示,这个区块有开始和结束标签,你需要在<Location>中添加这个指示。

LimitLimitExcept中使用的参数是可以被这个区块影响的HTTP请求类型,举个例子,如果你希望禁止所有的版本库访问,只是保留当前支持的只读操作,你可以使用LimitExcept指示,并且使用GETPROPFINDOPTIONSREPORT请求类型参数,然后前面提到过的Require valid-user指示将会在<LimitExcept>区块中而不是在<Location>区块。

<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访问控制Require指示的更深入信息,可以查看Apache文档中的教程集http://httpd.apache.org/docs-2.0/misc/tutorials.html中的Security部分。

每目录访问控制

也可以使用Apache的httpd模块mod_authz_svn更加细致的设置访问权限,这个模块收集客户端传递过来的不同的晦涩的URL信息,询问mod_dav_svn来解码,然后根据在配置文件定义的访问政策来裁决请求。

如果你从源代码创建Subversion,mod_authz_svn会自动附加到mod_dav_svn,许多二进制分发版本也会自动安装,为了验证它是安装正确,确定它是在httpd.confLoadModule指示中的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

         

为了激活这个模块,你需要配置你的Location区块的AuthzSVNAccessFile指示,指定保存路径中的版本库访问政策的文件。(一会儿我们将会讨论这个文件的格式。)

Apache非常的灵活,你可以从三种模式里选择一种来配置你的区块,作为开始,你选择一种基本的配置模式。(下面的例子非常简单;见Apache自己的文档中的认证和授权选项来查看更多的细节。)

最简单的区块是允许任何人可以访问,在这个场景里,Apache决不会发送认证请求,所有的用户作为“匿名”对待。

例 6.1. 匿名访问的配置实例。

<Location /repos>   DAV svn   SVNParentPath /usr/local/svn   # our access control policy   AuthzSVNAccessFile /path/to/access/file </Location>

         
         

在另一个极端,你可以配置为拒绝所有人的认证,所有客户端必须提供证明自己身份的证书,你通过Require valid-user指示来阻止无条件的认证,并且定义一种认证的手段。

例 6.2. 一个认证访问的配置实例。

<Location /repos>   DAV svn   SVNParentPath /usr/local/svn   # our access control policy   AuthzSVNAccessFile /path/to/access/file   # only authenticated users may access the repository   Require valid-user   # how to authenticate a user   AuthType Basic   AuthName "Subversion repository"   AuthUserFile /path/to/users/file </Location>

         
         

第三种流行的模式是允许认证和匿名用户的组合,举个例子,许多管理员希望允许匿名用户读取特定的版本库路径,但希望只有认证用户可以读(或者写)更多敏感的区域,在这个设置里,所有的用户开始时用匿名用户访问版本库,如果你的访问控制策略在任何时候要求一个真实的用户名,Apache将会要求认证客户端,为此,你可以同时使用Satisfy AnyRequire valid-user指示。

例 6.3. 一个混合认证/匿名访问的配置实例。

<Location /repos>   DAV svn   SVNParentPath /usr/local/svn   # our access control policy   AuthzSVNAccessFile /path/to/access/file   # try anonymous access first, resort to real   # authentication if necessary.   Satisfy Any   Require valid-user   # how to authenticate a user   AuthType Basic   AuthName "Subversion repository"   AuthUserFile /path/to/users/file </Location>

         
         

一旦你已经设置了httpd.conf模版之一,你需要在对应的路径创建包含访问规则的文件,在“基于路径的授权”一节中有描述。

禁用基于路径的检查

mod_dav_svn模块做了许多工作来确定你标记为“不可读”的数据不会因意外而泄露,这意味着需要紧密监控通过svn checkout或是svn update返回的路径和文件内容,如果这些命令遇到一些根据认证策略不是可读的路径,这个路径通常会被一起忽略,在历史或者重命名操作时—例如运行一个类似svn cat -r OLD foo.c的命令来操作一个很久以前改过名字的文件 — 如果一个对象的以前的名字检测到是只读的,重命令追踪就会终止。

所有的路径检查在有时会非常昂贵,特别是svn log的情况。当检索一列修订版本时,服务器会查看所有修订版本修改的路径,并且检查可读性,如果发现了一个不可读路径,它会从修订版本的修改路径中忽略(通常可以使用--verbose选项查看),并且整个的日志信息会被禁止,不必多说,这种影响大量文件修订版本的操作会非常耗时。这是安全的代价:即使你并没有配置mod_authz_svn模块,mod_dav_svn还是会询问httpd来对所有路径运行认证检查,mod_dav_svn模块没有办法知道那个认证模块被安装,所以只能要求Apache调用时提供的内容。

在另一方面,也有一个安全舱门允许你用安全特性来交换速度,如果你不是坚持要求有每目录授权(如不使用 mod_authz_svn和类似的模块),你就可以关闭所有的路径检查,在你的httpd.conf文件,使用SVNPathAuthz指示:

例 6.4. 禁用所有的路径检查

<Location /repos>   DAV svn   SVNParentPath /usr/local/svn   SVNPathAuthz off </Location>

         
         

SVNPathAuthz指示缺省是“on”,当设置为“off”时,所有的路径为基础的授权都会关闭;mod_dav_svn停止对每个目录调用授权检查。

额外的糖果

我们已经覆盖了关于认证和授权的Apache和mod_dav_svn的大多数选项,但是Apache还提供了许多很好的特性。

版本库浏览

使用Apache/WebDAV配置Subversion版本库时一个非常有用的好处是可以用普通的浏览器察看最新的版本库文件,因为Subversion使用URL来鉴别版本库版本化的资源,版本库使用的HTTP为基础的URL也可以直接输入到Web浏览器中,你的浏览器会发送一个GET请求到URL,根据访问的URL是指向一个版本化的目录还是文件,mod_dav_svn会负责列出目录列表或者是文件内容。

因为URL不能确定你所希望看到的资源的版本,mod_dav_svn会一直返回最新的版本,这样会有一些美妙的副作用,你可以直接把Subversion的URL传递给文档作为引用,这些URL会一直指向文档最新的材料,当然,你也可以在别的网站作为超链使用这些URL。

我可以看到老的修订版本吗?

通过一个普通的浏览器?一句话:不可以,至少是当你只使用mod_dav_svn作为唯一的工具时。

你的Web浏览器只会说普通的HTTP,也就是说它只会GET公共的URL,这个URL代表了最新版本的文件和目录,根据WebDAV/DeltaV规范,每种服务器定义了一种私有的URL语法来代表老的资源的版本,这个语法对客户端是不透明的,为了得到老的版本,一个客户端必须通过一种规范过程来“发现”正确的URL;这个过程包括执行一系列WebDAV
PROPFIND请求和理解DeltaV概念,这些事情一般是你的web浏览器做不了的。

为了回答这些问题,一个明显的看老版本文件和目录的方式是带--revision (-r)参数的svn listsvn cat命令,为了在浏览器里察看老版本,你可以使用第三方的软件,一个好的例子是ViewVC(http://viewvc.tigris.org/),ViewVC最初写出来是为了在web显示CVS版本库,[43]最新的版本也已经可以理解Subversion版本库了。

正确的文件类型

当浏览Subversion版本库时,web浏览器通过从Apache的HTTP GET返回内容中查看Content-Type:头可以知道如何渲染文件的线索,这个值是一种MIME类型。默认情况下,Apache告诉浏览器所有的版本库文件都是缺省的MIME类型,通常是text/plain,这样有时候会让人沮丧,如果一个用户希望版本库文件能够更有意义的渲染—例如一个foo.html,在浏览时最好能够按照HTML方式渲染。

为了生效,我们只需要确认你的文件有正确的svn:mime-type设置,这将在“文件内容类型”一节详细讨论,你可以设置的你的客户端在文件首次添加到版本库时自动附加svn:mime-type属性;见“自动设置属性”一节

所以在我们的例子中,如果一个人对foo.htmlsvn:mime-type设置为text/html,Apache就会告知浏览器使用HTML方式渲染文件,也可以给图片文件设置合适的image/*类型,这样最终可以使整个web站点直接从版本库浏览,这样做通常没有问题,只要你的站点不包含动态生成的内容。

定制外观

你通常会在版本化的文件的URL之外得到更多地用处—毕竟那里是有趣的内容存在的地方,但是你会偶尔浏览一个Subversion的目录列表,你会很快发现展示列表生成的HTML非常基本,并且一定没有在外观上(或者是有趣上)下功夫,为了自定义这些目录显示,Subversion提供了一个XML目录特性,一个单独的SVNIndexXSLT指示在你的httpd.conf文件版本库的Location块里,它将会指导mod_dav_svn在显示目录列表的时候生成XML输出,并且引用你选择的XSLT样式表文件:

<Location /svn>   DAV svn   SVNParentPath /usr/local/svn   SVNIndexXSLT "/svnindex.xsl"   … </Location>

           

使用SVNIndexXSLT指示和创建一个XSLT样式表,你可以让你的目录列表的颜色模式与你的网站的其它部分匹配,否则,如果你愿意,你可以使用Subversion源分发版本中的tools/xslt/目录下的样例样式表。记住提供给SVNIndexXSLT 指示的路径是一个URL路径—浏览器需要阅读你的样式表来利用它们!

版本库列表

如果你通过 SVNParentPath指示从一个URL维护一组版本库,也可以让Apache在浏览器显示所有存在的版本库,只需要通过SVNListParentPath指示激活:

<Location /svn>   DAV svn   SVNParentPath /usr/local/svn   SVNListParentPath on   … </Location>

           

如果一个用户将浏览器指向http://host.example.com/svn/,她一定会看到/usr/local/svn下所有的Subversion版本库,很明显这是一件安全问题,所以这个特性默认是关闭的。

Apache 日志

因为Apache的核心是一个HTTP服务器,它包含了梦幻般灵活的日志特性。各种配置日志的方式可以超出了本书的范围,但是我们必须指出,即使是最原始的文件httpd.conf也可以让Apache产生两个日志:error_logaccess_log。这些日志会出现在不同的地方,但通常是创建在Apache安装的日志区。(在Unix下,这个目录是/usr/local/apache2/logs/。)

error_log描述了所有Apache运行中的内部错误,access_log记录了Apache接收到的所有HTTP请求,这个日志很容易查看,例如包括Subversion客户端的IP地址,哪些用户正确认证和请求成功还是失败。

不幸的是,因为HTTP是无状态协议,即使最简单的Subversion客户端操作会产生多个网络请求,很难通过查看access_log来确定用户的操作—大多数操作看起来像是一系列神秘的PROPPATCHGETPUTREPORT请求。更糟糕的是,许多客户段操作会发送几乎完全相同的一系列请求,所以更加难以区分。

mod_dav_svn会成为一个辅助,通过激活“operational logging”属性,你可以告诉mod_dav_svn创建另外的日志文件,来描述你的客户度uan做了哪些高级操作。

为此,你需要利用Apache的CustomLog指示(在Apache自己的文档里有详细解释)指示,请确定在Subversion的Location指示之外配置这个指示。

<Location /svn>   DAV svn   … </Location> CustomLog logs/svn_logfile "%t %u %{SVN-ACTION}e" env=SVN-ACTION

         

在这个例子里,我们告诉Apache在标准的Apachelogs目录创建一个svn_logfile日志文件,%t%u变量会被请求的时间和用户名代替,关键的部分是SVN-ACTION的两个实例,当Apache看到变量,会将变量的值替代为环境变量SVN-ACTION,这个环境变量的值是mod_dav_svn在检测到高级客户段操作时自动设置的。

所以我们不选择翻译下面的传统的access_log文件:

[26/Jan/2007:22:25:29 -0600] "PROPFIND /svn/calc/!svn/vcc/default HTTP/1.1" 207 398 [26/Jan/2007:22:25:29 -0600] "PROPFIND /svn/calc/!svn/bln/59 HTTP/1.1" 207 449 [26/Jan/2007:22:25:29 -0600] "PROPFIND /svn/calc HTTP/1.1" 207 647 [26/Jan/2007:22:25:29 -0600] "REPORT /svn/calc/!svn/vcc/default HTTP/1.1" 200 607 [26/Jan/2007:22:25:31 -0600] "OPTIONS /svn/calc HTTP/1.1" 200 188 [26/Jan/2007:22:25:31 -0600] "MKACTIVITY /svn/calc/!svn/act/e6035ef7-5df0-4ac0-b811-4be7c823f998 HTTP/1.1" 201 227 …

         

… 你可以细读一个更加智能的svn_logfile文件:

[26/Jan/2007:22:24:20 -0600] - list-dir '/' [26/Jan/2007:22:24:27 -0600] - update '/' [26/Jan/2007:22:25:29 -0600] - remote-status '/' [26/Jan/2007:22:25:31 -0600] sally commit r60

                         

其它特性

Apache作为一个健壮的Web服务器的许多特性也可以用来增加Subversion的功能性和安全性,Subversion使用Neon与Apache通讯,这是一种一般的HTTP/WebDAV库,可以支持SSL(Secure
 Socket Layer,将在后面讨论)。如果你的Subversion是以支持SSL(安全套接层,过一会儿讨论)编译,则你可以使用https://访问Apache服务器。

同样有用的是Apache和Subversion关系的一些特性,像可以指定自定义的端口(而不是缺省的HTTP的80)或者是一个Subversion可以被访问的虚拟主机名,或者是通过HTTP代理服务器访问的能力,这些特性都是Neon所支持的,所以Subversion轻易得到这些支持。

最后,因为mod_dav_svn是使用一个半完成的WebDAV/DeltaV方言,所以通过第三方的DAV客户端访问也是可能的,几乎所有的现代操作系统(Win32、OS X和Linux)都有把DAV服务器影射为普通的网络“共享”的内置能力,这是一个复杂的主题;察看附录 C, WebDAV和自动版本来得到更多细节。


[40] 他们讨厌这样做。

[41] 当使用自签名的服务器时仍会遭受“中间人”攻击,但是与偷取未保护的密码相比,这样的攻击比一个偶然的获取要艰难许多。

[42] 更多有安全意识的人不会希望在运行中servers文件保存客户端证书密码。

[43] 之前叫做“ViewCVS”。