SVN+Apache+SSL的配置说明
夏妙
二零一零年十月
目 录
第 1 章 前言.... 1
第 2 章 CollabNetSubversion.. 1
第 3 章 SSL的个人浅见.... 2
第 4 章 SVN+Apache+SSL环境搭建过程.... 5
4.1 第一步:安装CollabNetSubversion服务端... 5
4.2 第二步:安装Subversion客户端... 8
4.3 第三步:创建测试用的版本库(repository)... 11
4.4 第四步:配置Apache服务... 11
4.4.1 配置Apache 和 Subversion的集成... 11
4.4.2 配置Apache响应客户端提交的svn访问请求... 12
4.4.3 创建Apache服务要求的基本认证密码文件“passwd”. 13
4.5 第五步:测试Apache服务... 14
4.6 第六步:使用SVN客户端在测试版本库TestRepository1中创建若干测试项目文件夹... 26
4.7 第七步:配置版本库目录精确授权访问... 28
4.8 第八步:使用SVN客户端在测试版版本库精确目录授权访问功能... 31
4.9 第九步:为Apache服务配置SSL功能(不进行客户端身份鉴别)... 36
4.9.1 虚拟一个CA认证中心... 38
4.9.2 SVN服务器端向CA中心申请数字证书... 39
4.9.3 CA中心为SVN服务器端颁发数字证书... 42
4.9.4 启用Apache的SSL功能... 46
4.9.5 配置SSL功能模块... 47
4.9.6 测试SSL功能... 59
4.9.6.1 测试启用了SSL的Apache服务... 59
4.9.6.2 测试启用了SSL的版本库访问... 61
4.9.6.3 采用TortoiseSVN客户端测试基于SSL的版本库访问... 63
4.9.7 在客户端安装CA根证书... 67
4.9.7.1 在客户端浏览器中安装数字证书... 69
4.9.7.2 在TortoiseSVN客户端中安装CA根证书... 73
4.9.8 再次测试SSL功能(在客户端安装了CA根证书后)... 78
4.9.8.1 测试启用了SSL的Apache服务... 78
4.9.8.2 测试启用了SSL的版本库访问... 80
4.9.8.3 采用TortoiseSVN客户端测试基于SSL的版本库访问... 81
4.10 第十步:为Apache服务配置SSL功能(要求进行客户端身份鉴别)... 85
4.10.1 客户端向CA中心申请数字证书... 86
4.10.2 CA中心为客户端颁发数字证书... 88
4.10.3 配置SSL启用客户端身份鉴别功能... 90
4.10.4 在客户端安装个人专用的客户端数字证书... 102
4.10.4.1 在客户端浏览器中安装个人客户端数字证书... 103
4.10.4.2 在TortoiseSVN客户端中安装个人数字证书... 107
4.10.5 测试要求进行客户端身份鉴别的SSL功能(在客户端安装了CA根证书以及个人客户端证书后) 111
4.10.5.1 测试启用了SSL的Apache服务... 111
4.10.5.2 测试启用了SSL的版本库访问... 113
4.10.5.3 采用TortoiseSVN客户端测试基于SSL的版本库访问... 114
花了3天的时间终于搞定了SVN+Apache+SSL的环境搭建,网上疯狂的搜索大部分都是针对SVN+svnserve或者SVN+Apache的配置(都比较简单,照着网上的文章配置成功率很高),但是针对SVN+Apache+SSL的配置都讲得太过简单,可操作性不强,下面把自己的辛苦经历归纳整理成文,希望能够帮助到新手少走弯路。
SVN(Subversion)是一个开源项目,有很多赞助商提供免费的维护升级,我这里选择的是CollabNet提供的版本,目前该公司提供了一个集成了SVN+Apache+ViewVC的集成安装版本,叫:CollabNetSubversionEdge,于是下载了最新版:CollabNetSubversionEdge-1.2.2,安装后试用后各项功能都比较方便(基本上不用进行配置),提供了基于浏览器的管理平台,所有的版本库、用户、目录授权等都可以基于该管理平台实现,并且给客户端提供了ViewVC应用(客户端可以直接使用浏览器查看版本库内容)。但是唯一不好使的是启用SSL后就不能够正常访问了,并且其安装目录下的各配置文件目录结构,包括配置内容都与早期SVN+Apache版本大相径庭,相去甚远,从网络上搜索的资料都没法实验(这个集成安装版本出来还没有几天,资料匮乏)。
最终也没有能够使用这个集成安装版本(CollabNetSubversionEdge-1.2.2)实现基于SSL的安全访问(https://),当时就想怎么给配起来能够正常运转,也没有弄清楚SSL的真实含义和应用机制以及验证流程(只知道是比http安全,数据内容都是加密传输),结果是囫囵了大半天也未果,对于出现的错误没有办法发挥主观能动性进行积极的思考。痛定思痛后,决定先搞清楚SSL是个啥,经过多方查阅后,从应用层面上对SSL算是基本搞清楚了。
SSL(Secure Sockets Layer 安全套接层)主要用于实现http请求会话的客户端和服务器端的双向身份认证,并对会话过程中的数据进行加密传输,从而保证网络访问的安全性。这些安全功能都是由客户端浏览器和服务器端http服务之间协作自动完成的,对使用者完全透明,使用者只是看见了一个https而已。但是现在是要自己来配置实现就不得不搞清楚其验证机制了,网上有较多文章对该验证过程进行了详细的描述,摘抄部分如下:
----------以下来自百度百科--------------------------------------------
服务器认证阶段:
1)客户端向服务器发送一个开始信息“Hello”以便开始一个新的会话连接;
2)服务器根据客户的信息确定是否需要生成新的主密钥,如需要则服务器在响应客户的“Hello”信息时将包含生成主密钥所需的信息;
3)客户根据收到的服务器响应信息,产生一个主密钥,并用服务器的公开密钥加密后传给服务器;
4)服务器恢复该主密钥,并返回给客户一个用主密钥认证的信息,以此让客户认证服务器。
用户认证阶段:
在此之前,服务器已经通过了客户认证,这一阶段主要完成对客户的认证。经认证的服务器发送一个提问给客户,客户则返回(数字)签名后的提问和其公开密钥,从而向服务器提供认证。
------------------以下来自:http://blog.csdn.net/ast_224/archive/2009/01/19/3837155.aspx,这里面还有详尽的图示,值的一看------------------------
SSL握手过程:
摘录自《SSL与TLS》
目的:
1. 客户端与服务器需要就一组用于保护数据的算法达成一致;
2. 它们需要确立一组由那些算法所使用的加密密钥;
3. 握手还可以选择对客户端进行认证。
过程:
1. 客户端将它所支持的算法列表和一个用作产生密钥的随机数发送给服务器;
2. 服务器从算法列表中选择一种加密算法,并将它和一份包含服务器公用密钥的证书发送给客户端;该证书还包含了用于认证目的的服务器标识,服务器同时还提供了一个用作产生密钥的随机数;
3. 客户端对服务器的证书进行验证(有关验证证书,可以参考数字签名),并抽取服务器的公用密钥;然后,再产生一个称作pre_master_secret的随机密码串,并使用服务器的公用密钥对其进行加密(参考非对称加/解密),并将加密后的信息发送给服务器;
4. 客户端与服务器端根据pre_master_secret以及客户端与服务器的随机数值独立计算出加密和MAC密钥(参考DH密钥交换算法)。
5. 客户端将所有握手消息的MAC值发送给服务器;
6. 服务器将所有握手消息的MAC值发送给客户端。
上述SSL验证流程的说明都没有结合CA(认证中心)讲解数字证书在整个验证过程的应用模式,在此将个人理解补充如下。
下面会涉及到公钥和私钥的概念,个人简单理解就是:他们是成对出现的,如果有这么一对公钥/私钥(公钥是P,私钥是S),那么用P加密后的数据必须用S才能够正确解密,反过来也是一样的,用S加密的数据只有用P才能解密。至于他们到底干啥用的,举个形象的例子来说明。财务室有个上锁的保险柜(比拟服务器端),xm是财务出纳并且分配拥有一把钥匙,保险柜知道目前公司只有xm具备钥匙(xm比拟为客户端,锁比拟为公钥P,钥匙比拟为私钥S,保险柜里面的钱比拟为用公钥P加密后的数据),而锁和钥匙是成对出现的,如果现在有人用钥匙把锁打开了并拿到了钱(比拟为通过用私钥S对公钥P加密的数据进行了正确解密,并得到了解密后数据--钱!),保险柜当即就认为开锁从保险柜拿钱的人是xm,因为他知道只有公司出纳xm才拥有钥匙,当初是因为信任xm才会分发钥匙给他的,现在锁开了就认定这个拿钱人一定是xm,从而实现了拿钱人(数据访问者/客户端)身份的鉴别,总之就是可以用于在网络会话中鉴别对方的身份。
数字证书在整个SSL会话验证过程中的完整应用机制如下图所示:
经过后面的摸索过程才知道上图中的SSL只进行了服务器端身份的鉴别,并没有进行客户端身份的鉴别。SSL可以配置是否要求鉴别客户端身份,这个在后面详述。下面就先针对这种不鉴别客户端身份的SVN+Apache+SSL应用环境阐述其在Windows下的搭建过程。
可以从官网http://www.open.collab.net/downloads/subversion/svn1.5.html下载最新版的CollabNet Subversion Server and Client,目前最新版本是 v1.6.13 (for Windows),注意不要下载CollabNetSubversionEdge集成安装包,下面的搭建过程对其不适用。
这里我采用了默认的安装目录 C:\Program Files\CollabNet\Subversion Server
安装过程中的下面这个步骤要特别注意,下图中的Apache(MOD_DAV_SVN)一定要勾上,表示安装Apache http服务,并且集成对SVN的访问处理。
附带说明一下图中的SVNSERVE是适用于局域网的SVN服务,支持svn:的访问处理,安装Apache后可以支持svn服务的http:访问处理,后面我们再为Apache配置上SSL,那么就可以支持svn服务的https:访问处理了。
安装向导要求输入服务的端口号,SVNSERVE的端口缺省填入的是3690,Apache服务的端口缺省填入的是80,因为我有安装IIS(80已被占用),故调整为8080。
然后还要求输入SVN版本库的安装目录,我选择:e:\svn_repository
向导界面上的其他选项保持缺省值不变,然后下一步直至安装完成,安装完毕后会在windows服务中注册两个服务程序。
注意:如果是XP等具备Windows防火墙的操作系统,需要将上述TCP端口号3690和8080添加至正常访问列表中,可通过防火墙设置程序来添加例外通过的端口号,也可以通过以下命令行脚本来添加(在运行框或DOS窗口中执行即可)。
执行下面这行表示添加TCP 3690端口号至防火墙例外通过的端口列表中
netsh firewall set portopening protocol = TCP port = 3690 name = SvnservePort mode = ENABLE scope = SUBNET profile = CURRENT
执行下面这行表示添加TCP 8080端口号至防火墙例外通过的端口列表中
netsh firewall set portopening protocol = TCP port = 8080 name = ApachePort mode = ENABLE scope = SUBNET profile = CURRENT
关于SVNSERVE的配置比较简单(略过),如果只允许通过http:访问SVN,那么可以不用安装SVNSERVE服务,下面针对Apache进行配置说明。
实际上在SVN服务端是不需要安装Subversion客户端的,但是如果安装了那么我们在创建版本库的时候会很便捷,可以抛弃比较繁琐的命令行方式。
这里我选择的Subversion客户端是赫赫有名的TortoiseSVN,他很好的与Windows资源管理器进行了集成,并且最有价值的是提供了非常有用的帮助文档,可以对SVN服务的配置有个全面的认识,但是里面对Apache的SSL配置太模糊,使我走了很多弯路。
可以从官网(http://tortoisesvn.net/downloads)下载最新版本,目前是1.6.11,记得同时下载简体中文语言安装包(在同一个下载页面的底部)。
TortoiseSVN安装界面如下:
简体中文语言包安装界面如下:
接着需要设置客户端语言环境为中文:
在Windows资源管理器任意地方点击右键选择TortoiseSVN菜单中的Settings
在设置界面上的Language选项中选择:中文(简体)即可。
在windows资源管理器中打开我选择的版本库目录:e:\svn_repository,新建文件夹TestRepository1,然后再新建的TestRepository1文件夹上点击鼠标右键,选择TortoiseSVN菜单”在此创建版本库”,该测试版本库留待后面的Apache服务配置完成后进行测试使用。
如果采用上述安装包进行Subversion和Apache的集成安装,那么安装向导会自动完成了大部分在Apache服务中集成SVN的配置,例如完成了mod_dav_svn.so
和mod_authz_svn.so文件的拷贝处理,但仍有小量的配置工作要做。用UltraEdit之类的文本编辑器打开Apache服务的配置文件(D:\Program Files\CollabNet\Subversion Server\httpd\conf\httpd.conf)进行如下配置:
搜索到下面这行配置内容,去掉首字符#(带#表示注释信息,去掉#表示生效的配置信息)
#LoadModule dav_fs_module modules/mod_dav_fs.so
将以下配置内容添加到 LoadModule
节的末尾
LoadModule authz_svn_module modules/mod_authz_svn.so
从D:\Program Files\CollabNet\Subversion Server目录下拷贝以下文件至Apache的bin目录(D:\Program Files\CollabNet\Subversion Server\httpd\bin):
libdb41.dll
libapr-1.dll
libaprutil-1.dll
libsvn_delta-1.dll
libsvn_fs-1.dll
libsvn_repos-1.dll
libsvn_subr-1.dll
拷贝过程中如果提示目标文件已经存在,可以选择否(不覆盖)。
注意:上述这些文件必须确保都存在于Apache的bin目录,否则Apache服务将无法启动,报cannot load mod_dav_svn.so的错误信息。
在Apache服务的配置文件(D:\Program Files\CollabNet\Subversion Server\httpd\conf\httpd.conf)末尾将
#
#告诉Apache是哪个模块响应那个URL的请求-此刻是Subversion模块。
DAV svn
#对于 Subversion 1.3 或者更高版本,这个指示会列出所有 SVNParentPath 中的版本库。
SVNListParentPath on
#告诉Subversion需要查看的版本库位于e:\svn_repository之下
SVNParentPath e:\svn_repository
#激活基本认证,就是用户名/密码
AuthType Basic
#指定当客户端在访问版本库时弹出要求用户输入认证信息的认证对话框上显示的信息
AuthName "Subversion repositories login:"
#指定使用的认证密码文件,passwd是用户密码验证文件,要求放置在httpd子目录下
AuthUserFile passwd
#指定精确的控制版本库目录访问的授权文件路径,
#svnaccessfile是目录授权文件(可对访问用户进行版本库中任意目录的授权),要求放置在httpd目录下
#如果不需要进行细粒度的目录授权控制,则可以把下面这行配置内容用#注释掉
#AuthzSVNAccessFile svnaccessfile
#指定只有输入了正确的用户/密码的用户可以访问URL
Require valid-user
这个密码文件的文件名在前面的配置文件中由下面这句话指定了:
#指定使用的认证密码文件,passwd是用户密码验证文件,要求放置在httpd子目录下
AuthUserFile passwd
打开命令行提示符(DOS 窗口),进入 D:\Program Files\CollabNet\Subversion Server\httpd\bin 目录,通过输入下面的命令创建密码文件passwd,并添加一个访问用户xm,后续会要求输入用户的密码。
htpasswd –c ..\passwd xm
用下面的命令增加其它用户:
htpasswd ..\passwd otherusername
至此,Apache集成Subversion服务的配置基本完成(不开启SSL),下面进行测试。
在Windows服务管理界面找到CollabNet Subversion Apache服务,并启动/重新启动它,如果前面的配置都没有遗漏的话应该就可以顺序启动Apache服务了。
注意:下面的图示都是直接在Apache服务端进行测试,如果在另一台客户端机器上做测试,需要将地址栏中的localhost替换为该Apache服务器的计算机名称或IP地址。
在IE浏览器中输入地址http://localhost:8080,显示It works!,表示Apache服务已经在工作了。
下面进一步测试Apache对Subversion请求的处理是否正常。
在IE浏览器中输入地址:http://localhost:8080/svn/,并且输入我们之前创建的版本库用户名和密码后,浏览器显示出了我们之前创建的测试版本库TestRepository1,表示Apache与Subversion已经正确集成,可以处理客户端提交的svn访问请求。
Apache服务配置文件内容实例
此时,整个Apache服务配置文件(D:\Program Files\CollabNet\Subversion Server\httpd\conf\httpd.conf)的内容如下:
#
# This is the main Apache HTTP server configuration file. It contains the
# configuration directives that give the server its instructions.
# See
# In particular, see
#
# for a discussion of each configuration directive.
#
# Do NOT simply read the instructions in here without understanding
# what they do. They're here only as hints or reminders. If you are unsure
# consult the online docs. You have been warned.
#
# Configuration and logfile names: If the filenames you specify for many
# of the server's control files begin with "/" (or "drive:/" for Win32), the
# server will use that explicit path. If the filenames do *not* begin
# with "/", the value of ServerRoot is prepended -- so "logs/foo.log"
# with ServerRoot set to "C:\Program Files\CollabNet\Subversion Server/httpd" will be interpreted by the
# server as "C:\Program Files\CollabNet\Subversion Server/httpd/logs/foo.log".
#
# NOTE: Where filenames are specified, you must use forward slashes
# instead of backslashes (e.g., "c:/apache" instead of "c:\apache").
# If a drive letter is omitted, the drive on which Apache.exe is located
# will be used by default. It is recommended that you always supply
# an explicit drive letter in absolute paths, however, to avoid
# confusion.
#
# ThreadsPerChild: constant number of worker threads in the server process
# MaxRequestsPerChild: maximum number of requests a server process serves
ThreadsPerChild 250
MaxRequestsPerChild 0
#
# ServerRoot: The top of the directory tree under which the server's
# configuration, error, and log files are kept.
#
# Do not add a slash at the end of the directory path. If you point
# ServerRoot at a non-local disk, be sure to point the LockFile directive
# at a local disk. If you wish to share the same ServerRoot for multiple
# httpd daemons, you will need to change at least LockFile and PidFile.
#
ServerRoot "C:\Program Files\CollabNet\Subversion Server/httpd"
#
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the
# directive.
#
# Change this to Listen on specific IP addresses as shown below to
# prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
#
#Listen 12.34.56.78:80
Listen 8080
#
# Dynamic Shared Object (DSO) Support
#
# To be able to use the functionality of a module which was built as a DSO you
# have to place corresponding `LoadModule' lines at this location so the
# directives contained in it are actually available _before_ they are used.
# Statically compiled modules (those listed by `httpd -l') do not need
# to be loaded here.
#
# Example:
# LoadModule foo_module modules/mod_foo.so
#
LoadModule actions_module modules/mod_actions.so
LoadModule alias_module modules/mod_alias.so
LoadModule asis_module modules/mod_asis.so
LoadModule auth_basic_module modules/mod_auth_basic.so
#LoadModule auth_digest_module modules/mod_auth_digest.so
#LoadModule authn_anon_module modules/mod_authn_anon.so
#LoadModule authn_dbm_module modules/mod_authn_dbm.so
LoadModule authn_default_module modules/mod_authn_default.so
LoadModule authn_file_module modules/mod_authn_file.so
#LoadModule authz_dbm_module modules/mod_authz_dbm.so
LoadModule authz_default_module modules/mod_authz_default.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule autoindex_module modules/mod_autoindex.so
#LoadModule cern_meta_module modules/mod_cern_meta.so
LoadModule cgi_module modules/mod_cgi.so
#LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
#LoadModule deflate_module modules/mod_deflate.so
LoadModule dir_module modules/mod_dir.so
LoadModule env_module modules/mod_env.so
#LoadModule expires_module modules/mod_expires.so
#LoadModule file_cache_module modules/mod_file_cache.so
#LoadModule headers_module modules/mod_headers.so
LoadModule imagemap_module modules/mod_imagemap.so
LoadModule include_module modules/mod_include.so
#LoadModule info_module modules/mod_info.so
LoadModule isapi_module modules/mod_isapi.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule mime_module modules/mod_mime.so
#LoadModule mime_magic_module modules/mod_mime_magic.so
LoadModule proxy_module modules/mod_proxy.so
#LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
#LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
#LoadModule proxy_connect_module modules/mod_proxy_connect.so
#LoadModule proxy_http_module modules/mod_proxy_http.so
#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule negotiation_module modules/mod_negotiation.so
#LoadModule rewrite_module modules/mod_rewrite.so
LoadModule setenvif_module modules/mod_setenvif.so
#LoadModule speling_module modules/mod_speling.so
#LoadModule status_module modules/mod_status.so
#LoadModule unique_id_module modules/mod_unique_id.so
LoadModule userdir_module modules/mod_userdir.so
#LoadModule usertrack_module modules/mod_usertrack.so
#LoadModule vhost_alias_module modules/mod_vhost_alias.so
#LoadModule ssl_module modules/mod_ssl.so
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
# 'Main' server configuration
#
# The directives in this section set up the values used by the 'main'
# server, which responds to any requests that aren't handled by a
#
# any
#
# All of these directives may appear inside
# in which case these default settings will be overridden for the
# virtual host being defined.
#
#
# ServerAdmin: Your address, where problems with the server should be
# e-mailed. This address appears on some server-generated pages, such
# as error documents. e.g. [email protected]
#
ServerSignature On
ServerAdmin localhost@localdomain
#
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If your host doesn't have a registered DNS name, enter its IP address here.
#
ServerName localhost:8080
#
# DocumentRoot: The directory out of which you will serve your
# documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations.
#
DocumentRoot "C:\Program Files\CollabNet\Subversion Server/httpd/htdocs"
#
# Each directory to which Apache has access can be configured with respect
# to which services and features are allowed and/or disabled in that
# directory (and its subdirectories).
#
# First, we configure the "default" to be a very restrictive set of
# features.
#
Options FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
Satisfy all
#
# Note that from this point forward you must specifically allow
# particular features to be enabled - so if something's not working as
# you might expect, make sure that you have specifically enabled it
# below.
#
#
# This should be changed to whatever you set DocumentRoot to.
#
#
# Possible values for the Options directive are "None", "All",
# or any combination of:
# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#
# The Options directive is both complicated and important. Please see
# http://httpd.apache.org/docs/2.2/mod/core.html#options
# for more information.
#
Options Indexes FollowSymLinks
#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
# Options FileInfo AuthConfig Limit
#
AllowOverride None
#
# Controls who can get stuff from this server.
#
Order allow,deny
Allow from all
#
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#
DirectoryIndex index.html
#
# The following lines prevent .htaccess and .htpasswd files from being
# viewed by Web clients.
#
Order allow,deny
Deny from all
#
# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a
# container, error messages relating to that virtual host will be
# logged here. If you *do* define an error logfile for a
# container, that host's errors will be logged there and not here.
#
ErrorLog logs/error.log
#
# LogLevel: Control the number of messages logged to the error_log.
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
#
LogLevel warn
#
# The following directives define some format nicknames for use with
# a CustomLog directive (see below).
#
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
# You need to enable mod_logio.c to use %I and %O
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
#
# The location and format of the access logfile (Common Logfile Format).
# If you do not define any access logfiles within a
# container, they will be logged here. Contrariwise, if you *do*
# define per-
# logged therein and *not* in this file.
#
CustomLog logs/access.log common
#
# If you prefer a logfile with access, agent, and referer information
# (Combined Logfile Format) you can use the following directive.
#
#CustomLog logs/access.log combined
#
# Redirect: Allows you to tell clients about documents that used to
# exist in your server's namespace, but do not anymore. The client
# will make a new request for the document at its new location.
# Example:
# Redirect permanent /foo http://www.example.com/bar
#
# Alias: Maps web paths into filesystem paths and is used to
# access content that does not live under the DocumentRoot.
# Example:
# Alias /webpath /full/filesystem/path
#
# If you include a trailing / on /webpath then the server will
# require it to be present in the URL. You will also likely
# need to provide a
# the filesystem path.
#
# ScriptAlias: This controls which directories contain server scripts.
# ScriptAliases are essentially the same as Aliases, except that
# documents in the target directory are treated as applications and
# run by the server when requested rather than as documents sent to the
# client. The same rules about trailing "/" apply to ScriptAlias
# directives as to Alias.
#
ScriptAlias /cgi-bin/ "C:\Program Files\CollabNet\Subversion Server/httpd/cgi-bin/"
#
# "C:\Program Files\CollabNet\Subversion Server/httpd/cgi-bin" should be changed to whatever your ScriptAliased
# CGI directory exists, if you have that configured.
#
AllowOverride None
Options None
Order allow,deny
Allow from all
#
# Apache parses all CGI scripts for the shebang line by default.
# This comment line, the first line of the script, consists of the symbols
# pound (#) and exclamation (!) followed by the path of the program that
# can execute this specific script. For a perl script, with perl.exe in
# the C:\Program Files\Perl directory, the shebang line should be:
#!c:/program files/perl/perl
# Note you _must_not_ indent the actual shebang line, and it must be the
# first line of the file. Of course, CGI processing must be enabled by
# the appropriate ScriptAlias or Options ExecCGI directives for the files
# or directory in question.
#
# However, Apache on Windows allows either the Unix behavior above, or can
# use the Registry to match files by extention. The command to execute
# a file of this type is retrieved from the registry by the same method as
# the Windows Explorer would use to handle double-clicking on a file.
# These script actions can be configured from the Windows Explorer View menu,
# 'Folder Options', and reviewing the 'File Types' tab. Clicking the Edit
# button allows you to modify the Actions, of which Apache 1.3 attempts to
# perform the 'Open' Action, and failing that it will try the shebang line.
# This behavior is subject to change in Apache release 2.0.
#
# Each mechanism has it's own specific security weaknesses, from the means
# to run a program you didn't intend the website owner to invoke, and the
# best method is a matter of great debate.
#
# To enable the this Windows specific behavior (and therefore -disable- the
# equivilant Unix behavior), uncomment the following directive:
#
#ScriptInterpreterSource registry
#
# The directive above can be placed in individual
# .htaccess file, with either the 'registry' (Windows behavior) or 'script'
# (Unix behavior) option, and will override this server default option.
#
#
# DefaultType: the default MIME type the server will use for a document
# if it cannot otherwise determine one, such as from filename extensions.
# If your server contains mostly text or HTML documents, "text/plain" is
# a good value. If most of your content is binary, such as applications
# or images, you may want to use "application/octet-stream" instead to
# keep browsers from trying to display binary files as though they are
# text.
#
DefaultType text/plain
#
# TypesConfig points to the file containing the list of mappings from
# filename extension to MIME-type.
#
TypesConfig conf/mime.types
#
# AddType allows you to add to or override the MIME configuration
# file specified in TypesConfig for specific file types.
#
#AddType application/x-gzip .tgz
#
# AddEncoding allows you to have certain browsers uncompress
# information on the fly. Note: Not all browsers support this.
#
#AddEncoding x-compress .Z
#AddEncoding x-gzip .gz .tgz
#
# If the AddEncoding directives above are commented-out, then you
# probably should define those extensions to indicate media types:
#
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
#
# AddHandler allows you to map certain file extensions to "handlers":
# actions unrelated to filetype. These can be either built into the server
# or added with the Action directive (see below)
#
# To use CGI scripts outside of ScriptAliased directories:
# (You will also need to add "ExecCGI" to the "Options" directive.)
#
#AddHandler cgi-script .cgi
# For type maps (negotiated resources):
#AddHandler type-map var
#
# Filters allow you to process content before it is sent to the client.
#
# To parse .shtml files for server-side includes (SSI):
# (You will also need to add "Includes" to the "Options" directive.)
#
#AddType text/html .shtml
#AddOutputFilter INCLUDES .shtml
#
# The mod_mime_magic module allows the server to use various hints from the
# contents of the file itself to determine its type. The MIMEMagicFile
# directive tells the module where the hint definitions are located.
#
#MIMEMagicFile conf/magic
#
# Customizable error responses come in three flavors:
# 1) plain text 2) local redirects 3) external redirects
#
# Some examples:
#ErrorDocument 500 "The server made a boo boo."
#ErrorDocument 404 /missing.html
#ErrorDocument 404 "/cgi-bin/missing_handler.pl"
#ErrorDocument 402 http://www.example.com/subscription_info.html
#
#
# EnableMMAP and EnableSendfile: On systems that support it,
# memory-mapping or the sendfile syscall is used to deliver
# files. This usually improves server performance, but must
# be turned off when serving from networked-mounted
# filesystems or if support for these functions is otherwise
# broken on your system.
#
#EnableMMAP off
#EnableSendfile off
# Supplemental configuration
#
# The configuration files in the conf/extra/ directory can be
# included to add extra features or to modify the default configuration of
# the server, or you may simply copy their contents here and change as
# necessary.
# Server-pool management (MPM specific)
#Include conf/extra/httpd-mpm.conf
# Multi-language error messages
#Include conf/extra/httpd-multilang-errordoc.conf
# Fancy directory listings
#Include conf/extra/httpd-autoindex.conf
# Language settings
#Include conf/extra/httpd-languages.conf
# User home directories
#Include conf/extra/httpd-userdir.conf
# Real-time info on requests and configuration
#Include conf/extra/httpd-info.conf
# Virtual hosts
#Include conf/extra/httpd-vhosts.conf
# Local access to the Apache HTTP Server Manual
#Include conf/extra/httpd-manual.conf
# Distributed authoring and versioning (WebDAV)
#Include conf/extra/httpd-dav.conf
# Various default settings
#Include conf/extra/httpd-default.conf
# Secure (SSL/TLS) connections
#Include conf/extra/httpd-ssl.conf
#
# Note: The following must must be present to support
# starting without SSL on platforms with no /dev/random equivalent
# but a statically compiled-in mod_ssl.
#
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
#
#告诉Apache是哪个模块响应那个URL的请求-此刻是Subversion模块。
DAV svn
#对于 Subversion 1.3 或者更高版本,这个指示会列出所有 SVNParentPath 中的版本库。
SVNListParentPath on
#告诉Subversion需要查看的版本库位于e:\svn_repository之下
SVNParentPath e:\svn_repository
#激活基本认证,就是用户名/密码
AuthType Basic
#指定当客户端在访问版本库时弹出要求用户输入认证信息的认证对话框上显示的信息
AuthName "Subversion repositories login:"
#指定使用的认证密码文件,passwd是用户密码验证文件,要求放置在httpd子目录下
AuthUserFile passwd
#指定精确的控制版本库目录访问的授权文件路径,
#svnaccessfile是目录授权文件(可对访问用户进行版本库中任意目录的授权),要求放置在httpd目录下
#如果不需要进行细粒度的目录授权控制,则可以把下面这行配置内容用#注释掉
#AuthzSVNAccessFile svnaccessfile
#指定只有输入了正确的用户/密码的用户可以访问URL
Require valid-user
下面我将在测试版本库TestRepository1中创建如下测试项目文件夹,我们采用之前安装的TortoiseSVN客户端来完成。
选择TortoiseSVN菜单“版本库浏览器”,要求输入版本库地址。
输入TestRepository1测试版本库的访问地址:http://localhost:8080/svn/TestRepository1,确定后需要继续进行身份认证。
输入我们之前创建的版本库用户名和密码后,版本库浏览器将显示TestRepository1版本库下面的目录结构,目前是空白的,没有任何子目录,下面通过右键菜单“创建文件夹”来分别创建project1、project2、project3三个测试项目文件夹。
这里创建的TestRepository1测试版本库中的3个项目子目录(project1-3)留待备用,下面在阐述对版本库目录精确授权访问的配置过程时将要使用它们。
作为源代码管理,一般都是应该实现版本库目录的精确授权访问,否则隐患很大!很有可能团队中的某个人误操作或主观上有意无意的给你吧整个版本库下的所有项目源代码都删除了,虽然之前的代码不会丢,但会给正在工作的各个项目团队带来不小的麻烦。
首先要启用目录精确授权访问功能,可以通过修改前面配置完毕的Apache服务配置文件(C:\Program Files\CollabNet\Subversion Server\httpd\conf\httpd.conf)来启用该功能。
搜索到下面这行配置内容,去掉首字符#(带#表示注释信息,去掉#表示生效的配置信息)
#AuthzSVNAccessFile svnaccessfile
该配置项表示要求根据指定的svnaccessfile文件进行精确的版本库目录访问权限检查,未授权的目录不允许访问。svnaccessfile是目录授权文件(可对访问用户进行版本库中任意目录的授权)。
注意:该svnaccessfile文件要求放置在httpd目录下,这个文件的配置有格式要求,不过我们在创建版本库目录时程序会自动生成该配置文件样例,直接拷贝过来即可,然后在其基础上进行修改配置。
该样例配置文件在版本库目录中的具体存放位置,以之前创建的TestRepository1测试版本库目录为例,路径为:e:\svn_repository\TestRepository1\conf\authz,现在需要把这个authz文件拷贝至C:\Program Files\CollabNet\Subversion Server\httpd\conf目录下,重命名为svnaccessfile,然后用记事本或UltraEdit之类的文本编辑器打开它进行如下修改(下面是svnaccessfile文件直接配置完毕的结果),该配置文件各节含义比较简单,话不多说,直接看配置文件中的注释。
### This file is an example authorization file for svnserve.
### Its format is identical to that of mod_authz_svn authorization
### files.
### As shown below each section defines authorizations for the path and
### (optional) repository specified by the section name.
### The authorizations follow. An authorization line can refer to:
### - a single user,
### - a group of users defined in a special [groups] section,
### - an alias defined in a special [aliases] section,
### - all authenticated users, using the '$authenticated' token,
### - only anonymous users, using the '$anonymous' token,
### - anyone, using the '*' wildcard.
###
### A match can be inverted by prefixing the rule with '~'. Rules can
### grant read ('r') access, read-write ('rw') access, or no access
### ('').
[aliases]
# joe = /C=XZ/ST=Dessert/L=Snake City/O=Snake Oil, Ltd./OU=Research Institute/CN=Joe Average
#[groups]下配置的是用户组及其成员信息
[groups]
# 定义一个名为project1Group的用户组,代表project1项目组的研发人员,目前包括 dxt 和 tby 两个用户成员
project1Group = dxt,tyb
# harry_sally_and_joe = harry,sally,&joe
# [/foo/bar]
# harry = rw
# &joe = r
# * =
# 精确指定具体版本库下面的某个子目录,然后配置那些用户或用户组具备哪些访问权限(其下所有子目录都继承该权限),未配置的用户无权访问该目录
# 访问权限标识符说明:r表示只读,w表示可写,rw表示可读写,空格表示无权访问
# [repository:/baz/fuz]
# @harry_and_sally = rw
# * = r
# 配置版本库TestRepository1的根目录的访问授权(其下所有子目录都继承该权限)
[TestRepository1:/]
# xm可以读写
xm = rw
# 配置版本库TestRepository1下的project1子目录的访问授权(其下所有子目录都继承该权限)
[TestRepository1:/project1]
# dxt可以读写
dxt = rw
# tyb可以读写
tyb = rw
# project1Group的用户组可以读写
project1Group = rw
此时,整个Apache服务配置文件(D:\Program Files\CollabNet\Subversion Server\httpd\conf\httpd.conf)底部的内容如下:
#
#告诉Apache是哪个模块响应那个URL的请求-此刻是Subversion模块。
DAV svn
#对于 Subversion 1.3 或者更高版本,这个指示会列出所有 SVNParentPath 中的版本库。
SVNListParentPath on
#告诉Subversion需要查看的版本库位于e:\svn_repository之下
SVNParentPath e:\svn_repository
#激活基本认证,就是用户名/密码
AuthType Basic
#指定当客户端在访问版本库时弹出要求用户输入认证信息的认证对话框上显示的信息
AuthName "Subversion repositories login:"
#指定使用的认证密码文件,passwd是用户密码验证文件,要求放置在httpd子目录下
AuthUserFile passwd
#指定精确的控制版本库目录访问的授权文件路径,
#svnaccessfile是目录授权文件(可对访问用户进行版本库中任意目录的授权),要求放置在httpd目录下
#如果不需要进行细粒度的目录授权控制,则可以把下面这行配置内容用#注释掉
AuthzSVNAccessFile svnaccessfile
#指定只有输入了正确的用户/密码的用户可以访问URL
Require valid-user
在Windows服务管理界面找到CollabNet Subversion Apache服务,并启动/重新启动它。
注意:下面的图示都是直接在Apache服务端进行测试,如果在另一台客户端机器上做测试,需要将地址栏中的localhost替换为该Apache服务器的计算机名称或IP地址。
下面我将在测试版本库TestRepository1中创建如下测试项目文件夹,我们采用之前安装的TortoiseSVN客户端来完成。
选择TortoiseSVN菜单“版本库浏览器”,要求输入版本库地址。
输入TestRepository1测试版本库的访问地址:http://localhost:8080/svn/TestRepository1,确定后需要继续进行身份认证。
这里我们使用dxt用户进行登录,结果显示禁止访问的错误信息(在前面的目录授权中没有对dxt授予该目录的访问权限),这就证明我们配置的目录精确授权控制起作用了。
然后重新用xm进行登录(在前面的目录授权中对xm授予了该目录的读写访问权限),结果正确显示出了该目录下的子目录信息),这就再次证明我们配置的目录精确授权控制确实起作用了。
至此,我们实现了SVN版本库的http:方式的精确目录授权访问,如果再配置一个花生壳动态域名,就可以把我们的SVN服务放置在外网上了,从而实现异地多支项目团队的协作开发。
但是http对身份验证等会话信息都是以明文方式进行网络传输,总归是不太安全,我们可以进一步为Apache配置SSL来加强网络传输安全。
SSL这个东西的出现就是为了进行网络两端身份的鉴别,并且对传输数据进行加密处理。网络上针对Apache的SSL配置有很多文章,但是最麻烦的数字证书制作与配置这个环节基本上讲得都比较模糊,个人经过艰难的摸索验证,基本上理解了SSL这个应用环境的运作机制,数字证书在整个SSL会话验证过程中的应用机制如下图所示:
经过后面的摸索过程才知道上图中的SSL只进行了服务器端身份的鉴别,并没有进行客户端身份的鉴别。SSL可以配置是否要求鉴别客户端身份,这个在后面详述。
下面就针对这种不鉴别客户端身份的SSL应用环境,根据上图中的应用流程阐述其配置过程,包括各种数字证书的制作过程。
商业用的CA认证中心不是谁都能干的,有很多严格的资格审查,如果是自己内部用完全可以自己来虚拟一个CA认证中心,下面就来生成CA认证中心必备的私钥和自签名的根证书。
打开命令行提示符(DOS 窗口),进入 Apache的bin目录(C:\Program Files\CollabNet\Subversion Server\httpd\bin),通过输入下面的命令创建ca_cert子目录,用于存放CA中心的相关数字证书和密钥等文件。
md ca_cert
接着用下面的命令生成CA中心的私钥文件 ca_privkey.key(保存在ca_cert目录下)
openssl genrsa -out ca_cert\ca_privkey.key 1024
DOS窗口截图如下:
然后用下面的命令生成CA中心的自签名数字证书文件ca.crt(保存在ca_cert目录下)
openssl req -new -x509 -days 4000 -key ca_cert\ca_privkey.key -out ca_cert\ca.crt -config ..\conf\openssl.cnf
该命令会要求输入以下身份信息,表示CA中心的身份:
Country Name (2 letter code) [AU]:CN --国家代码,中国用CN
State or Province Name (full name) [Some-State]:BeiJing --国家或所在省份
Locality Name (eg, city) []:BeiJing --城市名称
Organization Name (eg, company) [Internet Widgits Pty Ltd]:orifound --组织名称
Organizational Unit Name (eg, section) []:orifound_ca --组织单位名称
Common Name (eg, YOUR name) []:orifound_ca --你的名称或网站域名
Email Address []:[email protected] --邮件地址
DOS窗口截图如下:
要实现SSL验证,服务器端必须具备数字证书,故SVN服务器端需要向CA中心申请一个数字证书。
申请数字证书需要提交一个采用私钥签名了的申请文件(.csr),下面就来为SVN服务器端生成其私钥和证书制作申请文件。
打开命令行提示符(DOS 窗口),进入 Apache的bin目录(C:\Program Files\CollabNet\Subversion Server\httpd\bin),通过输入下面的命令创建svn_server_cert子目录,用于存放SVN服务器端的相关数字证书和密钥等文件。
md svn_server_cert
接着用下面的命令生成svn服务器端的密钥文件 svn_server_privkey.key(保存在svn_server_cert目录下)
openssl genrsa -out svn_server_cert\svn_server_privkey.key 1024
然后用下面的命令生成svn服务器端准备提交给CA中心的数字证书制作申请文件 svn_server.csr(保存在svn_server_cert目录下)
openssl req -new -out svn_server_cert\svn_server.csr -key svn_server_cert\svn_server_privkey.key -config ..\conf\openssl.cnf
该命令会要求输入以下身份信息,表示SVN服务器端的身份:
Country Name (2 letter code) [AU]:CN --国家代码,中国用CN(建议与CA根证书一致)
State or Province Name (full name) [Some-State]:BeiJing --国家或所在省份(建议与CA根证书一致)
Locality Name (eg, city) []:BeiJing --城市名称
Organization Name (eg, company) [Internet Widgits Pty Ltd]:orifound --组织名称(建议与CA根证书一致)
Organizational Unit Name (eg, section) []:orifound_svn_server --组织单位名称
Common Name (eg, YOUR name) []:xp --你的名称或网站域名
Email Address []:[email protected] --邮件地址
特别注意:
这里的Common Name 在输入时一定要仔细考虑,如果你的SVN服务器部署在局域网内,那么该名称一定要和客户端访问该SVN服务器的地址中的“https://xp:8080/svn/” xp完全一致,实际上就是你的SVN服务器主机名或IP地址,因为SSL会检查客户端https请求的域名是否与服务器身份完全一致(通过检查这个Common Name来判断是否一致),否则无法正确访问,提示SSL验证失败的错误信息。
如果这里的Common Name 设置为主机名xp,那么日后就只能够用“https://xp:8080/svn/”来访问版本库;
如果这里的Common Name 设置为主机IP地址192.168.0.22,那么日后就只能够用“https://192.168.0.22:8080/svn/”来访问版本库;
如果SVN服务器部署在外网上,并且域名是www.yourdomain.com,那么这里的Common Name 必须设置为www.yourdomain.com
另外,这里输入的Country Name、State or Province Name和Organization Name都强烈建议与CA证书的完全一致,因为我们后面基于缺省的openssl.cnf配置文件颁发证书时要求证书使用者的上述信息与CA证书的完全一致,否则报错无法生成数字证书,除非修改openssl.cnf配置文件。
openssl.cnf配置文件的存放路径为:
C:\Program Files\CollabNet\Subversion Server\httpd\conf\openssl.cnf
其内容如下图所示,图中黄色标记部分就是在生成数字证书时对上述三项内容的匹配要求。
DOS窗口截图如下:
CA中心拿到SVN服务器端提交过来的证书制作申请文件(.csr)后,下面就可以为SVN服务器端其生成数字证书了。
在生成数字证书时要用到openssl配置文件(D:\Program Files\CollabNet\Subversion Server\httpd\conf\openssl.cnf),该配置文件中配置了几个目录和文件,我们必须事先创建好,否则在生成数字证书的时候会出现一系列的错误,具体要创建的目录和文件如下:
接下来就可以用下面的DOS命令生成由CA中心向svn服务器端颁发的数字证书 svn_server.crt(保存在svn_server_cert目录下),CA中心必须用自己的私钥和根证书对最终颁发的svn服务器端数字证书文件进行签名处理。
打开命令行提示符(DOS 窗口),进入 Apache的bin目录(C:\Program Files\CollabNet\Subversion Server\httpd\bin),输入以下命令:
openssl ca -in svn_server_cert\svn_server.csr -out svn_server_cert\svn_server.crt -cert ca_cert\ca.crt -keyfile ca_cert\ca_privkey.key -config ..\conf\openssl.cnf -days 4000
注意:
该命令会询问是否要签名等两个问题,都输入y回车,证书才能够正确生成,否则证书文件虽然生成了但却是0字节,我当时摸索研究时没有细看,把这个空文件直接配置到服务器端,结果在启动服务时失败,日志记录了证书文件内容为空的错误信息。
DOS窗口截图如下:
如果前面没有按要求事先创建好openssl配置文件(D:\Program Files\CollabNet\Subversion Server\httpd\conf\openssl.cnf)所需的目录和文件,在生成证书时会出现下面一系列的错误。
至此,我们已经制作了SSL(不鉴别客户端身份)验证过程所需的各种数字证书,下面需要来配置Apache以启用SSL功能。
可以通过修改前面配置完毕的Apache服务配置文件(D:\Program Files\CollabNet\Subversion Server\httpd\conf\httpd.conf)来启用该功能,具体修改如下。
搜索到下面两行配置内容,分别删除首部的#(带#表示注释信息,去掉#表示生效的配置信息)
#LoadModule ssl_module modules/mod_ssl.so
#Include conf/extra/httpd-ssl.conf
如果希望关闭非SSL的普通http访问请求,强制要求客户端采用https的SSL方式来访问版本库,那么可以对上述配置文件进一步做如下修改。
在配置文件底部的
SSLRequireSSL
此时,整个Apache服务配置文件(D:\Program Files\CollabNet\Subversion Server\httpd\conf\httpd.conf)底部的内容如下:
#
#告诉Apache是哪个模块响应那个URL的请求-此刻是Subversion模块。
DAV svn
#对于 Subversion 1.3 或者更高版本,这个指示会列出所有 SVNParentPath 中的版本库。
SVNListParentPath on
#告诉Subversion需要查看的版本库位于e:\svn_repository之下
SVNParentPath e:\svn_repository
#强制要求SSL认证,不响应非SSL方式的http请求
SSLRequireSSL
#激活基本认证,就是用户名/密码
AuthType Basic
#指定当客户端在访问版本库时弹出要求用户输入认证信息的认证对话框上显示的信息
AuthName "Subversion repositories login:"
#指定使用的认证密码文件,passwd是用户密码验证文件,要求放置在httpd子目录下
AuthUserFile passwd
#指定精确的控制版本库目录访问的授权文件路径,
#svnaccessfile是目录授权文件(可对访问用户进行版本库中任意目录的授权),要求放置在httpd目录下
#如果不需要进行细粒度的目录授权控制,则可以把下面这行配置内容用#注释掉
AuthzSVNAccessFile svnaccessfile
#指定只有输入了正确的用户/密码的用户可以访问URL
Require valid-user
至此,我们已经启用了Apache的SSL功能模块,但尚无法正确使用SSL,因为还需要进一步对SSL功能模块进行配置。
SSL功能模块的配置文件路径为:
C:\Program Files\CollabNet\Subversion Server\httpd\conf\extra\httpd-ssl.conf
用UltraEdit或记事本之类的编辑器打开这个配置文件,做如下修改。
该配置文件中有很多文件路径,需要把这些路径中的相对父目录都配置为我们的Apache服务的安装路径(D:\Program Files\CollabNet\Subversion Server\httpd),需要修改的地方是下面图中的黄色标记部分,比较快捷的做法如下。
使用文本编辑器的搜索替换功能,直接将配置文件中的
E:/1.6.9/subversion/../httpd/tmp/httpd/Apache
全部替换为:
C:/Program Files/CollabNet/Subversion Server/httpd
注意:并注意路径分隔符要用/
将上图中的路径修全部改完毕后,接着需要配置SVN服务器端的数字证书和私钥文件路径。
在当前SSL配置文件中搜索 “SSLCertificateFile” 和 “SSLCertificateKeyFile” 配置项,如下图所示:
SSLCertificateFile配置项用来指定SVN服务器端的数字证书文件路径。在SSL验证过程中,SVN服务器会将该数字证书传输给客户端,客户端通过读取证书中的身份信息和证书颁发机构来完成对SVN服务器的身份鉴别。
SSLCertificateKeyFile配置项用来指定SVN服务器端的私钥文件路径。在SSL验证过程中,客户端会生成一个随机的明文密码串,然后从SVN服务器端数字证书中获取服务器端的公钥信息,并用该公钥加密这个密文密码串后发给SVN服务器,SVN服务器则会采用该配置项指定的私钥来解密接收到的密码串,得到真正的明文密码串,此后客户端和服务器端都采用该明文密码串进行数据加密传输,从而保证SSL会话通道内数据传输的安全性。
我们在前面的数字证书制作部分已经将SVN服务器端的数字证书和密钥文件都生成好了,并且存放路径如下。
SVN服务器数字证书文件路径:
C:\Program Files\CollabNet\Subversion Server\httpd\bin\svn_server_cert\svn_server.crt
SVN服务器私钥文件路径:
C:\Program Files\CollabNet\Subversion Server\httpd\bin\svn_server_cert\svn_server_privkey.key
如下图所示:
根据上述数字证书和私钥文件路径,将SSLCertificateFile配置项修改为(注意路径分隔符用/):
SSLCertificateFile "C:/Program Files/CollabNet/Subversion Server/httpd/bin/svn_server_cert/svn_server.crt"
将SSLCertificateKeyFile配置项修改为(注意路径分隔符用/):
SSLCertificateKeyFile "C:/Program Files/CollabNet/Subversion Server/httpd/bin/svn_server_cert/svn_server_privkey.key"
上面这个配置可以理解为安装SVN服务器端数字证书和私钥,数字证书和私钥文件其实可以放在服务器端任意位置,然后在这里配置其正确的存放路径即可。
从这个配置文件中我们可以看到下面这句配置内容:
它表示SVN服务器主机的SSL处理功能(https://)将侦听443端口,这也是SSL访问方式(https://)的缺省端口号,就像http的缺省端口号是80一样。如果SVN服务器是带有Windows防火墙的操作系统(例如XP等等),那么这里为了能够让客户端能够正确访问到SSL功能,SVN服务器端必须在防火墙中开启443端口的正常访问(如果有其他防火墙软件同样也需要开启该端口)。
对于Windows防火墙,可在运行框或DOS窗口中执行如下命令行脚本来开启TCP 443端口的正常访问:
netsh firewall set portopening protocol = TCP port = 443 name = ApacheSSLPort mode = ENABLE scope = SUBNET profile = CURRENT
SSL功能模块的配置文件内容实例:
上述配置完成后,SSL功能模块的配置文件(C:\Program Files\CollabNet\Subversion Server\httpd\conf\extra\httpd-ssl.conf)的完整内容实例如下:
#
# This is the Apache server configuration file providing SSL support.
# It contains the configuration directives to instruct the server how to
# serve pages over an https connection. For detailing information about these
# directives see
#
# Do NOT simply read the instructions in here without understanding
# what they do. They're here only as hints or reminders. If you are unsure
# consult the online docs. You have been warned.
#
#
# Pseudo Random Number Generator (PRNG):
# Configure one or more sources to seed the PRNG of the SSL library.
# The seed data should be of good random quality.
# WARNING! On some platforms /dev/random blocks if not enough entropy
# is available. This means you then cannot use the /dev/random device
# because it would lead to very long connection times (as long as
# it requires to make more entropy available). But usually those
# platforms additionally provide a /dev/urandom device which doesn't
# block. So, if available, use this one instead. Read the mod_ssl User
# Manual for more details.
#
#SSLRandomSeed startup file:/dev/random 512
#SSLRandomSeed startup file:/dev/urandom 512
#SSLRandomSeed connect file:/dev/random 512
#SSLRandomSeed connect file:/dev/urandom 512
#
# When we also provide SSL we have to listen to the
# standard HTTP port (see above) and to the HTTPS port
#
# Note: Configurations that use IPv6 but not IPv4-mapped addresses need two
# Listen directives: "Listen [::]:443" and "Listen 0.0.0.0:443"
#
Listen 443
##
## SSL Global Context
##
## All SSL configuration in this context applies both to
## the main server and all SSL-enabled virtual hosts.
##
#
# Some MIME-types for downloading Certificates and CRLs
#
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl
# Pass Phrase Dialog:
# Configure the pass phrase gathering process.
# The filtering dialog program (`builtin' is a internal
# terminal dialog) has to provide the pass phrase on stdout.
SSLPassPhraseDialog builtin
# Inter-Process Session Cache:
# Configure the SSL Session Cache: First the mechanism
# to use and second the expiring timeout (in seconds).
#SSLSessionCache "dbm:C:/Program Files/CollabNet/Subversion Server/httpd/logs/ssl_scache"
SSLSessionCache "shmcb:C:/Program Files/CollabNet/Subversion Server/httpd/logs/ssl_scache(512000)"
SSLSessionCacheTimeout 300
# Semaphore:
# Configure the path to the mutual exclusion semaphore the
# SSL engine uses internally for inter-process synchronization.
SSLMutex default
##
## SSL Virtual Host Context
##
# General setup for the virtual host
DocumentRoot "C:/Program Files/CollabNet/Subversion Server/httpd/htdocs"
ServerName www.example.com:443
ServerAdmin [email protected]
ErrorLog "C:/Program Files/CollabNet/Subversion Server/httpd/logs/error.log"
TransferLog "C:/Program Files/CollabNet/Subversion Server/httpd/logs/access.log"
# SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on
# SSL Cipher Suite:
# List the ciphers that the client is permitted to negotiate.
# See the mod_ssl documentation for a complete list.
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
# Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate. If
# the certificate is encrypted, then you will be prompted for a
# pass phrase. Note that a kill -HUP will prompt again. Keep
# in mind that if you have both an RSA and a DSA certificate you
# can configure both in parallel (to also allow the use of DSA
# ciphers, etc.)
SSLCertificateFile "C:/Program Files/CollabNet/Subversion Server/httpd/bin/svn_server_cert/svn_server.crt"
#SSLCertificateFile "C:/Program Files/CollabNet/Subversion Server/httpd/conf/server-dsa.crt"
# Server Private Key:
# If the key is not combined with the certificate, use this
# directive to point at the key file. Keep in mind that if
# you've both a RSA and a DSA private key you can configure
# both in parallel (to also allow the use of DSA ciphers, etc.)
SSLCertificateKeyFile "C:/Program Files/CollabNet/Subversion Server/httpd/bin/svn_server_cert/svn_server_privkey.key"
#SSLCertificateKeyFile "C:/Program Files/CollabNet/Subversion Server/httpd/conf/server-dsa.key"
# Server Certificate Chain:
# Point SSLCertificateChainFile at a file containing the
# concatenation of PEM encoded CA certificates which form the
# certificate chain for the server certificate. Alternatively
# the referenced file can be the same as SSLCertificateFile
# when the CA certificates are directly appended to the server
# certificate for convinience.
#SSLCertificateChainFile "C:/Program Files/CollabNet/Subversion Server/httpd/conf/server-ca.crt"
# Certificate Authority (CA):
# Set the CA certificate verification path where to find CA
# certificates for client authentication or alternatively one
# huge file containing all of them (file must be PEM encoded)
# Note: Inside SSLCACertificatePath you need hash symlinks
# to point to the certificate files. Use the provided
# Makefile to update the hash symlinks after changes.
#SSLCACertificatePath "C:/Program Files/CollabNet/Subversion Server/httpd/conf/ssl.crt"
#SSLCACertificateFile "C:/Program Files/CollabNet/Subversion Server/httpd/conf/ssl.crt/ca-bundle.crt"
# Certificate Revocation Lists (CRL):
# Set the CA revocation path where to find CA CRLs for client
# authentication or alternatively one huge file containing all
# of them (file must be PEM encoded)
# Note: Inside SSLCARevocationPath you need hash symlinks
# to point to the certificate files. Use the provided
# Makefile to update the hash symlinks after changes.
#SSLCARevocationPath "C:/Program Files/CollabNet/Subversion Server/httpd/conf/ssl.crl"
#SSLCARevocationFile "C:/Program Files/CollabNet/Subversion Server/httpd/conf/ssl.crl/ca-bundle.crl"
# Client Authentication (Type):
# Client certificate verification type and depth. Types are
# none, optional, require and optional_no_ca. Depth is a
# number which specifies how deeply to verify the certificate
# issuer chain before deciding the certificate is not valid.
#SSLVerifyClient require
#SSLVerifyDepth 10
# Access Control:
# With SSLRequire you can do per-directory access control based
# on arbitrary complex boolean expressions containing server
# variable checks and other lookup directives. The syntax is a
# mixture between C and Perl. See the mod_ssl documentation
# for more details.
#
#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \
# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \
# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
#
# SSL Engine Options:
# Set various options for the SSL engine.
# o FakeBasicAuth:
# Translate the client X.509 into a Basic Authorisation. This means that
# the standard Auth/DBMAuth methods can be used for access control. The
# user name is the `one line' version of the client's X.509 certificate.
# Note that no password is obtained from the user. Every entry in the user
# file needs this password: `xxj31ZMTZzkVA'.
# o ExportCertData:
# This exports two additional environment variables: SSL_CLIENT_CERT and
# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
# server (always existing) and the client (only existing when client
# authentication is used). This can be used to import the certificates
# into CGI scripts.
# o StdEnvVars:
# This exports the standard SSL/TLS related `SSL_*' environment variables.
# Per default this exportation is switched off for performance reasons,
# because the extraction step is an expensive operation and is usually
# useless for serving static content. So one usually enables the
# exportation for CGI and SSI requests only.
# o StrictRequire:
# This denies access when "SSLRequireSSL" or "SSLRequire" applied even
# under a "Satisfy any" situation, i.e. when it applies access is denied
# and no other module can change it.
# o OptRenegotiate:
# This enables optimized SSL connection renegotiation handling when SSL
# directives are used in per-directory context.
#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
SSLOptions +StdEnvVars
SSLOptions +StdEnvVars
# SSL Protocol Adjustments:
# The safe and default but still SSL/TLS standard compliant shutdown
# approach is that mod_ssl sends the close notify alert but doesn't wait for
# the close notify alert from client. When you need a different shutdown
# approach you can use one of the following variables:
# o ssl-unclean-shutdown:
# This forces an unclean shutdown when the connection is closed, i.e. no
# SSL close notify alert is send or allowed to received. This violates
# the SSL/TLS standard but is needed for some brain-dead browsers. Use
# this when you receive I/O errors because of the standard approach where
# mod_ssl sends the close notify alert.
# o ssl-accurate-shutdown:
# This forces an accurate shutdown when the connection is closed, i.e. a
# SSL close notify alert is send and mod_ssl waits for the close notify
# alert of the client. This is 100% SSL/TLS standard compliant, but in
# practice often causes hanging connections with brain-dead browsers. Use
# this only for browsers where you know that their SSL implementation
# works correctly.
# Notice: Most problems of broken clients are also related to the HTTP
# keep-alive facility, so you usually additionally want to disable
# keep-alive for those clients, too. Use variable "nokeepalive" for this.
# Similarly, one has to force some clients to use HTTP/1.0 to workaround
# their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
# "force-response-1.0" for this.
BrowserMatch ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
# Per-Server Logging:
# The home of a custom SSL log file. Use this when you want a
# compact non-error SSL logfile on a virtual host basis.
CustomLog "C:/Program Files/CollabNet/Subversion Server/httpd/logs/ssl_request.log" \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
在Windows服务管理界面找到CollabNet Subversion Apache服务,并启动/重新启动它。
注意:下面的图示都是直接在Apache服务端进行测试,如果在另一台客户端机器上做测试,需要将地址栏中的localhost替换为该Apache服务器的计算机名称或IP地址。
在IE浏览器中输入如下地址:https://localhost 或 https://localhost:443
https缺省就是采用443端口进行访问。
注意:
客户端采用https://访问的时候就不要用端口8080了,我这里配置的SVN服务器针对http的端口是8080,针对https的端口是443。SVN服务器首先在443端口上响应并处理SSL验证流程,SSL验证通过后Apache会将https://里面封装的http://请求继续发送给8080端口进行处理。
测试结果如下图所示,IE浏览器客户端弹出一个安全警报提示框,表示SVN服务器端证书的颁发机构未在客户端信任列表中。
点击是继续浏览我们可以看到更为详尽的证书情况说明,如下图:
点击是继续浏览可以正确访问到SVN服务器的Apache服务缺省页面(http请求返回的结果):
如果想测试SVN版本库的SSL访问,以我们之前创建的测试版本库TestRepository1为例,可以在IE浏览器中输入如下地址:
https://localhost/svn/TestRepository1
同样的,客户端会警示服务器端数字证书的颁发机构未在信任列表中等安全性警告,点击是继续浏览,此时会弹出SVN版本库的身份认证信息,要求客户端进行身份认证,这里使用前面创建的版本库用户xm进行登录。
版本库用户身份认证通过后,显示出了TestRepository1版本库中的目录信息(我们之前创建的project1-3子目录)。
由此说明,客户端采用https:来访问SVN服务测试通过!
对于版本库的SSL访问方式,还可以用SVN客户端来进行测试。
这里还是采用之前安装的TortoiseSVN客户端来完成该测试,你也可以使用别的SVN客户端(例如直接在安装了Subclipse插件的Eclipse IDE中进行测试)。
选择TortoiseSVN菜单“版本库浏览器”,要求输入版本库地址。
输入TestRepository1测试版本库的访问地址:https://localhost/svn/TestRepository1,确定后弹出一个SVN服务器端数字证书颁发人不在客户端信任列表中的警告信息(与IE浏览器的警告大同小异),总的意思就是说客户端没法鉴别SVN服务器的身份,因为在客户端信任的证书颁发机构列表中没有该SVN服务器端数字证书的颁发机构。
点击接受继续,SVN客户端弹出版本库用户认证框。
使用前面创建的版本库用户xm登录,用户验证通过后,可能继续会弹出服务器端数字证书的警告信息,点击接受继续,即可显示出TestRepository1版本库下的子目录信息。
至此,采用SVN客户端测试基于SSL的版本库访问测试通过!
前面在测试SSL访问功能时,不论是IE浏览器客户端还是SVN客户端程序都会报服务器端身份无法鉴别的警示信息(并询问是否继续访问)。
出现这个警示信息的原因是SVN服务器端将其数字证书传给客户端后,客户端可以从证书中获取其颁发机构以及相应身份信息,客户端会预安装很多商业的证书颁发机构至信任列表中,而这个SVN服务器端证书是由我们自己虚拟的CA中心颁发的,当然不在客户端证书颁发机构信任列表中。
既然是这个原因造成的,那么只要把之前创建的CA中心的根证书安装到客户端的证书颁发机构信任列表中就可以解决该问题。
前面数字证书制作部分,已经将CA中心的根证书文件生成了,其存放地址为:
C:\Program Files\CollabNet\Subversion Server\httpd\bin\ca_cert\ca.crt
如下图:
为了在客户端安装该证书,首先要将该CA根证书文件拷贝至客户端机器的任意位置,我这里是拷贝至客户端机器的 C:\orifound_ca\ca.crt
客户端主机上CA根证书文件的存放位置截图:
把该CA根证书文件(ca.crt)拷贝至客户端机器上后,用鼠标双击可以打开该证书文件。
点击上图的安装证书,将打开证书导入向导。
点击下一步,选择证书导入后存放的位置。
注意:这里一定要选择“受信任的根证书颁发机构”。
点击完成,此时会再次弹出一个颁发机构证书安装确认提示框。
点击是,CA根证书在客户端安装完毕!
可以通过IE浏览器的“Internet选项”来检查证书的安装情况。
点击上图中的“证书(C)...”按钮,然后选择受信任的根证书颁发机构,从下图中可以看到我们自己虚拟的CA中心的根证书已经安装到了客户端的受信任的根证书颁发机构列表中。
也可以直接通过上图的“导入(I)…”来进行数字证书的安装。
对于SVN客户端,我们同样也需要安装CA根证书,否则就像前面测试结果一样总是弹出警告提示框。
在Windows资源管理器(或桌面上)任意空白位置,点击右键选择TortoiseSVN菜单“设置(S)”。
打开TortoiseSVN客户端的设置界面后,选择网络节点,然后点击下图中的“编辑”按钮来对Subversion服务器进行设置。
此时将打开一个配置文件,如下图所示,我们要对图中的黄色标记部分进行修改。
该配置文件的存放位置为:
C:\Documents and Settings\Administrator\Application Data\Subversion\servers
在该配置文件中搜索“ssl-authority-files”,该配置项用于指定客户端信任的所有CA数字证书文件路径,用;隔开。
前面已经把CA根证书文件拷贝至客户端机器的 C:\orifound_ca\ca.crt
客户端主机上CA根证书文件的存放位置截图:
根据该CA根证书文件的路径,在该配置文件中对“ssl-authority-files”配置项做如下配置:
去掉首字符#,并把CA根证书文件路径配置上去(注意:路径分隔符为/)。
ssl-authority-files = C:/orifound_ca/ca.crt
配置完成后的截图如下(黄色标记部分为修改内容):
在IE浏览器中输入如下地址:https://localhost 或 https://localhost:443
https缺省就是采用443端口进行访问。
测试结果如下图所示,IE浏览器客户端仍然弹出一个安全警报提示框,但于未安装CA根证书之前的提示信息不一样了。
从警告信息框可以看出,客户端从SVN服务器端数字证书中识别的颁发机构,已经是可信的(因为我们已经把其颁发机构--CA的根证书导入到了客户端的受信任根证书颁发结构列表中),只是SVN服务器端数字证书中登记的名称(Common Name )与现在请求的主机名称不匹配。
查看Apache服务器端的错误日志内容如下:
[Sun Oct 10 16:36:35 2010] [warn] RSA server certificate CommonName (CN) `xp' does NOT match server name!?
从错误日志中可以看出,SVN服务器端数字证书中登记的名称(Common Name )是xp,而我们通过https://localhost请求的主机名是localhost,显然不匹配,既然SSL验证过程中要求请求的主机与服务器端数字证书中登记的名称要一致,那么我们当初在制作SVN服务器端数字证书的时候就一定要仔细核对登记的Common Name ,将来就用该Common Name 作为https://访问地址中的主机名。
点击是继续浏览我们可以看到更为详尽的证书情况说明,如下图:
点击否,然后将浏览器中的地址修改为https://xp 后回车,此时不再出现前面的警示框,而是直接显示Apache服务的缺省页面,说明SSL测试通过!
如果想测试SVN版本库的SSL访问,以我们之前创建的测试版本库TestRepository1为例,可以在IE浏览器中输入如下地址:
https://xp/svn/TestRepository1,此时也不再弹出警示框,而是要求客户端进行版本库身份认证,这里使用前面创建的版本库用户xm登录。
版本库用户身份认证通过后,显示出了TestRepository1版本库中的目录信息(我们之前创建的project1-3子目录)。
由此说明,客户端采用https:来访问SVN服务测试通过!
对于版本库的SSL访问方式,还可以用SVN客户端来进行测试。
这里还是采用之前安装的TortoiseSVN客户端来完成该测试,你也可以使用别的SVN客户端(例如直接在安装了Subclipse插件的Eclipse IDE中进行测试)。
选择TortoiseSVN菜单“版本库浏览器”,要求输入版本库地址。
输入TestRepository1测试版本库的访问地址:https://xp/svn/TestRepository1,确定。
此时没有再弹出之前的服务器凭证检核错误的警示框,而是直接要求进行版本库身份认证。
点击接受继续,SVN客户端弹出版本库用户认证框。
使用前面创建的版本库用户xm登录,用户验证通过后,即可显示出TestRepository1版本库下的子目录信息。
至此,采用SVN客户端测试基于SSL的版本库访问测试通过!
到目前为止,SVN客户端已经可以使用基于SSL的访问方式(https://)来访问SVN版本库数据了,该SSL并没有要求鉴别客户端身份,如果是在局域网中问题不大,但是如果是将该SVN服务器配置中外网上访问,以支持不同城市甚至国家的团队协同开发,显然不合适,存在验证的安全问题,因为一旦有团队成员的身份验证信息(用户口令)泄漏了,就等同于它能够访问的源代码资源泄漏了。
为了解决这个问题,我们可以将SSL功能配置为要求鉴别客户端身份,实现SSL的双向身份鉴别,即客户端会鉴别服务器端身份,同时服务器端也会鉴别客户端身份,只有客户端身份鉴别通过后,SVN服务器端才响应客户端的请求。
前面已经讲解了SSL不要进行客户端身份鉴别的验证流程,现在为了能够在外网实现SVN的安全访问,要求SSL验证流程中必须进行客户端身份鉴别。其验证流程相比前面增加了一个验证环节,具体的SSL会话验证过程如下图所示:
下面就针对这种要求鉴别客户端身份的SSL应用环境,根据上图中的应用流程阐述其配置过程,包括各种数字证书的制作过程。
现在SSL验证要求鉴别客户端身份,那么客户端必须具备一个数字证书,在前面制作了CA根证书和SVN服务器端证书的基础上,还必须为每个客户端颁发一个数字证书(与SVN服务器端证书一样,客户端证书也是由CA中心来制作颁发)。
每个客户端都需要提交一个证书制作申请给CA中心,然后由CA中心根据申请内容来制作其数字证书。
对于CA而言,SVN服务器端和客户端都是同级的,他们的证书制作流程完全相同。
这里的客户端从某种程度上可以映射为研发团队中的研发人员,现在需要给每个团队成员制作一个专有的客户端数字证书。
下面以客户端用户xm为例,详细讲解为团队成员xm制作他专有的客户端数字证书的步骤。
客户端需要向CA中心申请一个数字证书,申请数字证书必须提交一个采用私钥签名了的申请文件(.csr),下面就来为客户端生成其私钥和证书制作申请文件。
打开命令行提示符(DOS 窗口),进入 Apache的bin目录(C:\Program Files\CollabNet\Subversion Server\httpd\bin),通过输入下面的命令创建svn_client_cert子目录,用于存放客户端的相关数字证书和密钥等文件。
md svn_client_cert
接着用下面的命令生成客户端的密钥文件 svn_client_privkey_xm.key(保存在svn_client_cert目录下)
openssl genrsa -out svn_client_cert\svn_client_privkey_xm.key 1024
用下面的命令生成客户端准备提交给CA中心的数字证书制作申请文件 svn_client_xm.csr(保存在svn_client_cert目录下)
openssl req -new -out svn_client_cert\svn_client_xm.csr -key svn_client_cert\svn_client_privkey_xm.key -config ..\conf\openssl.cnf
该命令会要求输入以下身份信息,表示客户端的身份:
Country Name (2 letter code) [AU]:CN --国家代码,中国用CN(建议与CA根证书一致)
State or Province Name (full name) [Some-State]:BeiJing --国家或所在省份(建议与CA根证书一致)
Locality Name (eg, city) []:BeiJing --城市名称
Organization Name (eg, company) [Internet Widgits Pty Ltd]:orifound --组织名称(建议与CA根证书一致)
Organizational Unit Name (eg, section) []:orifound_svn_client --组织单位名称
Common Name (eg, YOUR name) []:xm --你的名称或网站域名
Email Address []:[email protected] --邮件地址
强烈建议:涂银波
这里输入的Country Name、State or Province Name和Organization Name都强烈建议与CA证书的完全一致,因为我们后面基于缺省的openssl.cnf配置文件颁发证书时要求证书使用者的上述信息与CA证书的完全一致,否则报错无法生成数字证书,除非修改openssl.cnf配置文件。
openssl.cnf配置文件的存放路径为:
C:\Program Files\CollabNet\Subversion Server\httpd\conf\openssl.cnf
其内容如下图所示,图中黄色标记部分就是在生成数字证书时对上述三项内容的匹配要求。
DOS窗口截图如下:
CA中心收到客户端提交过来的证书制作申请文件(.csr)后,下面就可以为客户端生成数字证书了。
在生成数字证书时要用到openssl配置文件(D:\Program Files\CollabNet\Subversion Server\httpd\conf\openssl.cnf),该配置文件中配置了几个目录和文件,必须事先创建好,否则在生成数字证书的时候会出现一系列的错误,我们已经在前面制作SVN服务器端数字证书的时候就已经创建好了,这里跳过不讲,如果在执行下面步骤中出现错误请参考前面制作SVN服务器端数字证书的说明来创建openssl.cnf配置文件中需要的几个目录和文件。
接下来就可以用下面的DOS命令生成由CA中心向客户端颁发的数字证书 svn_client_xm.crt(保存在svn_client_cert目录下),CA中心必须用自己的私钥和根证书对最终颁发的客户端数字证书文件进行签名处理。
打开命令行提示符(DOS 窗口),进入 Apache的bin目录(C:\Program Files\CollabNet\Subversion Server\httpd\bin),输入以下命令:
openssl ca -in svn_client_cert\svn_client_xm.csr -out svn_client_cert\svn_client_xm.crt -cert ca_cert\ca.crt -keyfile ca_cert\ca_privkey.key -config ..\conf\openssl.cnf -days 4000
注意:该命令会询问是否要签名等两个问题,都输入y回车,证书才能够正确生成,否则证书文件虽然生成了但却是0字节。
DOS窗口截图如下:
到现在为止,客户端数字证书尚未制作完成,因为上面生成的数字证书格式无法安装到客户端个人数字证书列表中,而p12格式的数字证书可以正确安装,故需要再生成一个p12格式的数字证书。
可以用下面的DOS命令从上面的客户端数字证书svn_client_xm.crt 中导出一个p12格式的客户端数字证书svn_client_xm.p12,内部已包含私钥信息(保存在svn_client_cert目录下):
openssl pkcs12 -export -clcerts -in svn_client_cert\svn_client_xm.crt -inkey svn_client_cert\svn_client_privkey_xm.key -out svn_client_cert\svn_client_xm.p12
该命令要求输入将用于保护私钥信息的口令,将来任何程序要读取该证书中的私钥,都必须输入该口令,这里我将口令设置为123456,DOS窗口截图如下:
至此,我们已经制作了用于SSL(鉴别客户端身份)的客户端数字证书,下面需要来配置Apache以启用SSL的客户端身份鉴别功能。
SSL功能模块的配置文件路径为:
C:\Program Files\CollabNet\Subversion Server\httpd\conf\extra\httpd-ssl.conf
用UltraEdit或记事本之类的编辑器打开这个配置文件,做如下修改。
搜索"
经验教训:当初自己做配置时,因为没有修改这一项,结果客户端SSL验证总是失败,有网文说修改为主机域名,结果还是出错,查阅好多文章后终于找到了上述解决方案。
搜索"SSLCACertificatePath"和"SSLCACertificateFile",如下图黄色标记部分。
在前面数字证书制作部分,已经将CA中心的根证书文件生成了,其存放地址为:
C:\Program Files\CollabNet\Subversion Server\httpd\bin\ca_cert\ca.crt
如下图:
根据上述CA根证书文件地址,将"SSLCACertificatePath"和"SSLCACertificateFile"两项配置内容做如下修改。
去掉首字符#,并将路径设置为上述地址(注意路径分隔符为/),修改结果如下:
SSLCACertificatePath "C:/Program Files/CollabNet/Subversion Server/httpd/bin/ca_cert"
SSLCACertificateFile "C:/Program Files/CollabNet/Subversion Server/httpd/bin/ca_cert/ca.crt"
搜索"SSLVerifyClient"和"SSLVerifyDepth",如下图黄色标记部分,该配置项表示要求进行客户端身份鉴别,以及鉴别的深度(身份信息匹配之类的深度),将两行内容做如下修改:
去掉首字符#
修改完成后内容如下:
SSLVerifyClient require
SSLVerifyDepth 10
搜索"SSLRequire",如下图黄色标记部分,该配置项指定在访问相关目录时客户端身份鉴别通过的条件。
去掉这段配置项的首字符#,并设置通过条件,修改完成后内容如下:
SSLRequire ( %{SSL_CLIENT_S_DN_O} eq "orifound" \
and %{SSL_CLIENT_S_DN_OU} eq "orifound_svn_client" )
上述配置表示客户端在访问任意版本库目录时都必须通过客户端身份鉴别,鉴别通过的条件是其证书身份信息中Organization Name 为"orifound" ,并且Organizational Unit Name 为"orifound_svn_client" 。
在配置上述验证通过的条件时,如果分多行配置,那么每行的末尾要以 \ 结束,最后一行末尾不要有 \,也可以将上述多个条件配置在一行,把括号去掉也可以,如下:
SSLRequire ( %{SSL_CLIENT_S_DN_O} eq "orifound" and %{SSL_CLIENT_S_DN_OU} eq "orifound_svn_client" )
注意:这个条件有严格的语法格式要求,如果配置不合法,会导致Apache服务启动失败。
搜索"",如下图黄色标记部分,在其下方增加如下配置内容(注意:是追加配置内容,不是替换)。
SSLRequire %{SSL_CLIENT_VERIFY} eq "SUCCESS"
追加上述配置内容的作用是要求客户端在访问任何服务器端目录时都必须通过客户端身份鉴别。
追加上述配置内容后的截图如下:
至此,SSL启用客户端身份鉴别功能配置完毕。
SSL功能模块的配置文件内容实例
SSL功能模块的配置文件路径为:
C:\Program Files\CollabNet\Subversion Server\httpd\conf\extra\httpd-ssl.conf
上述所有配置完成后,其完整内容如下:
#
# This is the Apache server configuration file providing SSL support.
# It contains the configuration directives to instruct the server how to
# serve pages over an https connection. For detailing information about these
# directives see
#
# Do NOT simply read the instructions in here without understanding
# what they do. They're here only as hints or reminders. If you are unsure
# consult the online docs. You have been warned.
#
#
# Pseudo Random Number Generator (PRNG):
# Configure one or more sources to seed the PRNG of the SSL library.
# The seed data should be of good random quality.
# WARNING! On some platforms /dev/random blocks if not enough entropy
# is available. This means you then cannot use the /dev/random device
# because it would lead to very long connection times (as long as
# it requires to make more entropy available). But usually those
# platforms additionally provide a /dev/urandom device which doesn't
# block. So, if available, use this one instead. Read the mod_ssl User
# Manual for more details.
#
#SSLRandomSeed startup file:/dev/random 512
#SSLRandomSeed startup file:/dev/urandom 512
#SSLRandomSeed connect file:/dev/random 512
#SSLRandomSeed connect file:/dev/urandom 512
#
# When we also provide SSL we have to listen to the
# standard HTTP port (see above) and to the HTTPS port
#
# Note: Configurations that use IPv6 but not IPv4-mapped addresses need two
# Listen directives: "Listen [::]:443" and "Listen 0.0.0.0:443"
#
Listen 443
##
## SSL Global Context
##
## All SSL configuration in this context applies both to
## the main server and all SSL-enabled virtual hosts.
##
#
# Some MIME-types for downloading Certificates and CRLs
#
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl
# Pass Phrase Dialog:
# Configure the pass phrase gathering process.
# The filtering dialog program (`builtin' is a internal
# terminal dialog) has to provide the pass phrase on stdout.
SSLPassPhraseDialog builtin
# Inter-Process Session Cache:
# Configure the SSL Session Cache: First the mechanism
# to use and second the expiring timeout (in seconds).
#SSLSessionCache "dbm:C:/Program Files/CollabNet/Subversion Server/httpd/logs/ssl_scache"
SSLSessionCache "shmcb:C:/Program Files/CollabNet/Subversion Server/httpd/logs/ssl_scache(512000)"
SSLSessionCacheTimeout 300
# Semaphore:
# Configure the path to the mutual exclusion semaphore the
# SSL engine uses internally for inter-process synchronization.
SSLMutex default
##
## SSL Virtual Host Context
##
# General setup for the virtual host
DocumentRoot "C:/Program Files/CollabNet/Subversion Server/httpd/htdocs"
ServerName www.example.com:443
ServerAdmin [email protected]
ErrorLog "C:/Program Files/CollabNet/Subversion Server/httpd/logs/error.log"
TransferLog "C:/Program Files/CollabNet/Subversion Server/httpd/logs/access.log"
# SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on
# SSL Cipher Suite:
# List the ciphers that the client is permitted to negotiate.
# See the mod_ssl documentation for a complete list.
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
# Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate. If
# the certificate is encrypted, then you will be prompted for a
# pass phrase. Note that a kill -HUP will prompt again. Keep
# in mind that if you have both an RSA and a DSA certificate you
# can configure both in parallel (to also allow the use of DSA
# ciphers, etc.)
SSLCertificateFile "C:/Program Files/CollabNet/Subversion Server/httpd/bin/svn_server_cert/svn_server.crt"
#SSLCertificateFile "C:/Program Files/CollabNet/Subversion Server/httpd/conf/server-dsa.crt"
# Server Private Key:
# If the key is not combined with the certificate, use this
# directive to point at the key file. Keep in mind that if
# you've both a RSA and a DSA private key you can configure
# both in parallel (to also allow the use of DSA ciphers, etc.)
SSLCertificateKeyFile "C:/Program Files/CollabNet/Subversion Server/httpd/bin/svn_server_cert/svn_server_privkey.key"
#SSLCertificateKeyFile "C:/Program Files/CollabNet/Subversion Server/httpd/conf/server-dsa.key"
# Server Certificate Chain:
# Point SSLCertificateChainFile at a file containing the
# concatenation of PEM encoded CA certificates which form the
# certificate chain for the server certificate. Alternatively
# the referenced file can be the same as SSLCertificateFile
# when the CA certificates are directly appended to the server
# certificate for convinience.
#SSLCertificateChainFile "C:/Program Files/CollabNet/Subversion Server/httpd/conf/server-ca.crt"
# Certificate Authority (CA):
# Set the CA certificate verification path where to find CA
# certificates for client authentication or alternatively one
# huge file containing all of them (file must be PEM encoded)
# Note: Inside SSLCACertificatePath you need hash symlinks
# to point to the certificate files. Use the provided
# Makefile to update the hash symlinks after changes.
SSLCACertificatePath "C:/Program Files/CollabNet/Subversion Server/httpd/bin/ca_cert"
SSLCACertificateFile "C:/Program Files/CollabNet/Subversion Server/httpd/bin/ca_cert/ca.crt"
# Certificate Revocation Lists (CRL):
# Set the CA revocation path where to find CA CRLs for client
# authentication or alternatively one huge file containing all
# of them (file must be PEM encoded)
# Note: Inside SSLCARevocationPath you need hash symlinks
# to point to the certificate files. Use the provided
# Makefile to update the hash symlinks after changes.
#SSLCARevocationPath "C:/Program Files/CollabNet/Subversion Server/httpd/conf/ssl.crl"
#SSLCARevocationFile "C:/Program Files/CollabNet/Subversion Server/httpd/conf/ssl.crl/ca-bundle.crl"
# Client Authentication (Type):
# Client certificate verification type and depth. Types are
# none, optional, require and optional_no_ca. Depth is a
# number which specifies how deeply to verify the certificate
# issuer chain before deciding the certificate is not valid.
SSLVerifyClient require
SSLVerifyDepth 10
# Access Control:
# With SSLRequire you can do per-directory access control based
# on arbitrary complex boolean expressions containing server
# variable checks and other lookup directives. The syntax is a
# mixture between C and Perl. See the mod_ssl documentation
# for more details.
#
#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \
# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \
# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
#
SSLRequire ( %{SSL_CLIENT_S_DN_O} eq "orifound" \
and %{SSL_CLIENT_S_DN_OU} eq "orifound_svn_client" )
# SSL Engine Options:
# Set various options for the SSL engine.
# o FakeBasicAuth:
# Translate the client X.509 into a Basic Authorisation. This means that
# the standard Auth/DBMAuth methods can be used for access control. The
# user name is the `one line' version of the client's X.509 certificate.
# Note that no password is obtained from the user. Every entry in the user
# file needs this password: `xxj31ZMTZzkVA'.
# o ExportCertData:
# This exports two additional environment variables: SSL_CLIENT_CERT and
# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
# server (always existing) and the client (only existing when client
# authentication is used). This can be used to import the certificates
# into CGI scripts.
# o StdEnvVars:
# This exports the standard SSL/TLS related `SSL_*' environment variables.
# Per default this exportation is switched off for performance reasons,
# because the extraction step is an expensive operation and is usually
# useless for serving static content. So one usually enables the
# exportation for CGI and SSI requests only.
# o StrictRequire:
# This denies access when "SSLRequireSSL" or "SSLRequire" applied even
# under a "Satisfy any" situation, i.e. when it applies access is denied
# and no other module can change it.
# o OptRenegotiate:
# This enables optimized SSL connection renegotiation handling when SSL
# directives are used in per-directory context.
#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
SSLOptions +StdEnvVars
SSLOptions +StdEnvVars
#要求任何目录访问都必须进行客户端身份鉴别
SSLRequire %{SSL_CLIENT_VERIFY} eq "SUCCESS"
# SSL Protocol Adjustments:
# The safe and default but still SSL/TLS standard compliant shutdown
# approach is that mod_ssl sends the close notify alert but doesn't wait for
# the close notify alert from client. When you need a different shutdown
# approach you can use one of the following variables:
# o ssl-unclean-shutdown:
# This forces an unclean shutdown when the connection is closed, i.e. no
# SSL close notify alert is send or allowed to received. This violates
# the SSL/TLS standard but is needed for some brain-dead browsers. Use
# this when you receive I/O errors because of the standard approach where
# mod_ssl sends the close notify alert.
# o ssl-accurate-shutdown:
# This forces an accurate shutdown when the connection is closed, i.e. a
# SSL close notify alert is send and mod_ssl waits for the close notify
# alert of the client. This is 100% SSL/TLS standard compliant, but in
# practice often causes hanging connections with brain-dead browsers. Use
# this only for browsers where you know that their SSL implementation
# works correctly.
# Notice: Most problems of broken clients are also related to the HTTP
# keep-alive facility, so you usually additionally want to disable
# keep-alive for those clients, too. Use variable "nokeepalive" for this.
# Similarly, one has to force some clients to use HTTP/1.0 to workaround
# their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
# "force-response-1.0" for this.
BrowserMatch ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
# Per-Server Logging:
# The home of a custom SSL log file. Use this when you want a
# compact non-error SSL logfile on a virtual host basis.
CustomLog "C:/Program Files/CollabNet/Subversion Server/httpd/logs/ssl_request.log" \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
前面数字证书制作部分,已经将个人专用的客户端数字证书生成了,其存放地址为:
C:\Program Files\CollabNet\Subversion Server\httpd\bin\svn_client_cert\svn_client_xm.p12
如下图:
为了在客户端安装该证书,首先要将该客户端证书文件拷贝至客户端机器的任意位置,我这里是拷贝至客户端机器的 C:\orifound_ca\svn_client_xm.p12
客户端主机上的个人专用的客户端数字证书文件的存放位置截图:
把该客户端证书文件(svn_client_xm.p12)拷贝至客户端机器上后,用鼠标双击可以打开证书导入向导。
点击下一步,选择要导入的证书文件。
点击下一步,要求输入该客户端数字证书中的密钥保护口令。
前面在导出该p12格式的个人客户端数字证书时设置的密钥保护口令为123456,这里当然也输入123456。
点击下一步,选择证书导入后存放的位置,让向导自动选择即可。
点击下一步,完成个人客户端数字证书的安装。
可以通过IE浏览器的“Internet选项”来检查证书的安装情况。
点击上图中的“证书(C)...”按钮,然后选择“个人”标签页,从下图中可以看到xm的个人客户端证书已经安装到了客户端的个人证书列表中。
也可以直接通过上图的“导入(I)…”来进行个人客户端数字证书的安装。
对于SVN客户端,我们同样也需要安装个人客户端数字证书,否则SSL验证会失败。
在Windows资源管理器(或桌面上)任意空白位置,点击右键选择TortoiseSVN菜单“设置(S)”。
打开TortoiseSVN客户端的设置界面后,选择网络节点,然后点击下图中的“编辑”按钮来对Subversion服务器进行设置。
此时将自动打开一个配置文件,在XP下该配置文件的存放位置为:
C:\Documents and Settings\Administrator\Application Data\Subversion\servers
如果是在Win7下,该配置文件的存放位置为路径为:
C:\Users\EAGLE\AppData\Roaming\Subversion\servers
在该配置文件中搜索“ssl-authority-files”,在其下方追加如下配置内容(注意是追加配置内容,而不是替换)。
ssl-client-cert-file = C:\orifound_ca\svn_client_xm.p12
ssl-client-cert-password = 123456
上述配置项的作用是指定SVN客户端进行SSL验证时,要提供的个人客户端数字证书以及在访问证书中的密钥信息时要提供的口令。
为了在客户端安装该证书,前面已经将该客户端证书文件拷贝至客户端机器的 C:\orifound_ca\svn_client_xm.p12
客户端主机上的个人专用的客户端数字证书文件的存放位置截图:
根据该客户机的个人客户端数字证书文件的路径以及导出该个人证书时设置的密钥保护口令,对上述配置项“ssl-client-cert-file”和“ssl-client-cert-password”进行正确配置。
配置完成后的截图如下(黄色标记部分为修改内容):
到此为止,已经完成了要求进行客户端身份鉴别的SSL配置,下面进行测试,在测试之前,需要重启Apache服务。
在IE浏览器中输入如下地址:https://xp 或 https://xp:443,https缺省就是采用443端口进行访问。
测试结果如下图所示,IE浏览器客户端弹出一个客户端证书选择框,在列表中自动列出了最合适的客户端证书信息,这里列出了前面导入的用户xm的个人客户端证书。
选择用户xm的个人客户端数字证书,确定后显示出Apache服务缺省页面
由此证明,要求鉴别客户端身份的SSL功能测试通过!
如果想测试SVN版本库的SSL访问,以我们之前创建的测试版本库TestRepository1为例,可以在IE浏览器中输入如下地址:
https://xp/svn/TestRepository1,同样也是要求提供客户端数字证书,选择客户端证书确定后,客户端要求进行版本库身份认证,这里使用前面创建的版本库用户xm登录。
版本库用户身份认证通过后,显示出了TestRepository1版本库中的目录信息(我们之前创建的project1-3子目录)。
由此说明,客户端采用https:来访问SVN服务测试通过(SSL进行了客户端身份的鉴别)!
对于版本库的SSL访问方式,还可以用SVN客户端来进行测试。
这里还是采用之前安装的TortoiseSVN客户端来完成该测试,你也可以使用别的SVN客户端(例如直接在安装了Subclipse插件的Eclipse IDE中进行测试)。
选择TortoiseSVN菜单“版本库浏览器”,要求输入版本库地址。
输入TestRepository1测试版本库的访问地址:https://xp/svn/TestRepository1,确定后要求进行版本库身份认证。
点击接受继续,SVN客户端弹出版本库用户认证框。
使用前面创建的版本库用户xm登录,用户验证通过后,即可显示出TestRepository1版本库下的子目录信息。
至此,采用SVN客户端测试基于SSL的版本库访问测试通过(SSL完成了客户端身份的鉴别)!
NetBeans6.9.1中集成了Subversion客户端,它的配置文件存放目录:
C:\Users\EAGLE\.netbeans\6.9\config\svn\config
Eclipse或MyEclipse安装了Subclipse插件后,其配置文件存放目录:
C:\Users\EAGLE\AppData\Roaming\Subversion