本文字档正在编写中,内容可能随时变更,可能无法准确描述任何已发布版本的 Apache™ Subversion® 软件。 收藏或以其他方式将他人引导至本页可能不是一个好主意。 请访问 https://svnbook.subversion.org.cn/ 获取本书的稳定版本。
svnserve 程序是一个轻量级服务器,能够使用自定义的、有状态的协议通过 TCP/IP 与客户端通信。 客户端通过以 svn://
或 svn+ssh://
开头的 URL 联系 svnserve 服务器。 本节将解释运行 svnserve 的不同方法,客户端如何向服务器进行身份验证,以及如何为您的代码库配置适当的访问控制。
运行 svnserve 作为独立守护进程,监听请求。
让 Unix inetd 守护进程在特定端口收到请求时临时生成 svnserve。
让 SSH 通过加密隧道调用一个临时的 svnserve。
运行 svnserve 作为 Microsoft Windows 服务。
运行 svnserve 作为 launchd 作业。
以下各节将详细介绍这些针对 svnserve 的各种部署选项。
最简单的选择是将 svnserve 作为独立的 “守护进程” 进程运行。 使用 -d
选项来实现这一点
$ svnserve -d $ # svnserve is now running, listening on port 3690
在守护进程模式下运行 svnserve 时,可以使用 --listen-port
和 --listen-host
选项来定制要 “绑定” 的确切端口和主机名。
当我们如前所述成功启动 svnserve 后,它会使系统上的每个代码库都可供网络访问。 客户端需要在代码库 URL 中指定一个 绝对 路径。 例如,如果一个代码库位于 /var/svn/project1
,客户端可以通过 svn://host.example.com/var/svn/project1
访问它。 为了提高安全性,可以将 -r
选项传递给 svnserve,它会将 svnserve 限制为仅导出该路径下的代码库。 例如
$ svnserve -d -r /var/svn …
使用 -r
选项实际上修改了程序视为远程文件系统空间根目录的位置。 客户端随后会使用已从中删除了该路径部分的 URL,从而得到更短(并且更不明显)的 URL
$ svn checkout svn://host.example.com/project1 …
如果你希望 inetd 启动该进程,你需要传递 -i
(--inetd
) 选项。 在下面的例子中,我们展示了在命令行运行 svnserve -i
的输出,但请注意,这不是你实际启动守护进程的方式;有关如何配置 inetd 以启动 svnserve,请参阅示例后面的段落。
$ svnserve -i ( success ( 2 2 ( ) ( edit-pipeline svndiff1 absent-entries commit-revprops d\ epth log-revprops atomic-revprops partial-replay ) ) )
当使用 --inetd
选项调用时,svnserve 会尝试通过 stdin
和 stdout
使用自定义协议与 Subversion 客户端通信。 这是通过 inetd 运行的程序的标准行为。 IANA 为 Subversion 协议预留了端口 3690,因此在类 Unix 系统上,你可以向 /etc/services
添加类似下面的行(如果不存在的话)
svn 3690/tcp # Subversion svn 3690/udp # Subversion
如果您的系统使用的是经典的类 Unix inetd 守护进程,您可以在 /etc/inetd.conf
中添加以下行
svn stream tcp nowait svnowner /usr/bin/svnserve svnserve -i
确保 “svnowner” 是一个具有访问代码库的适当权限的用户。 现在,当客户端连接在端口 3690 上进入您的服务器时,inetd 将生成一个 svnserve 进程来为其提供服务。 当然,您可能也希望向配置行添加 -r
,以限制导出哪些代码库。
一些操作系统提供了 xinetd 守护进程作为 inetd 的替代方案。 幸运的是,您也可以将 svnserve 配置为与 xinetd 一起使用。 为此,您需要创建一个配置文件 /etc/xinetd.d/svn
,其内容如下
# default: on
# description: Subversion server for the svn protocol
service svn
{
disabled = no
port = 3690
socket_type = stream
protocol = tcp
wait = no
user = subversion
server = /usr/local/bin/svnserve
server_args = -i -r /path/to/repositories
}
请确保您的 /etc/services
配置文件包含用于 svn
协议的端口的定义(如 名为“svnserve 通过 inetd”的部分所述),否则守护进程将无法正确启动。
在基于 Redhat 的发行版中,您需要使用 chkconfig --add svn 激活新服务。 完成此操作后,您将能够使用图形配置工具启用和禁用服务器。
调用 svnserve 的另一种方法是使用 -t
选项以隧道模式。 此模式假设远程服务程序(例如 rsh 或 ssh)已成功验证用户,并且现在正在 以该用户身份 调用一个私有的 svnserve 进程。(请注意,您作为用户,很少(如果有的话)会在命令行上使用 -t
调用 svnserve;相反,SSH 守护进程会为您执行此操作。)svnserve 程序的行为是正常的(通过 stdin
和 stdout
进行通信),并假设流量正在自动通过某种隧道重定向回客户端。 当 svnserve 被像这样的隧道代理调用时,请确保已验证的用户对代码库数据库文件具有完全的读写权限。 这与本地用户通过 file://
URL 访问代码库本质上相同。
本选项将在本章后面 名为“通过 SSH 建立隧道”的部分 中进行更详细的描述。
如果您的 Windows 系统是 Windows NT(Windows 2000 或更高版本)的派生系统,您可以将 svnserve 作为标准的 Windows 服务运行。 这通常比使用 --daemon
(-d
) 选项将其作为独立守护进程运行要好得多。 使用守护进程模式需要启动一个控制台,输入一个命令,然后让控制台窗口无限期地运行。 然而,Windows 服务在后台运行,可以在启动时自动启动,并且可以使用与其他 Windows 服务相同的管理界面来启动和停止。
您需要使用命令行工具 SC.EXE 定义新的服务。 与 inetd 配置行类似,您必须指定 svnserve 的确切调用方式,以便 Windows 在启动时运行
C:\> sc create svn binpath= "C:\svn\bin\svnserve.exe --service -r C:\repos" displayname= "Subversion Server" depend= Tcpip start= auto
这定义了一个名为 svn
的新 Windows 服务,它在启动时执行特定的 svnserve.exe 命令(在本例中,它以 C:\repos
为根目录)。 然而,前面的示例中有一些注意事项。
首先,请注意,svnserve.exe 程序必须始终使用 --service
选项调用。 然后,可以将 svnserve 的任何其他选项指定在同一行上,但您不能添加冲突的选项,例如 --daemon
(-d
)、--tunnel
或 --inetd
(-i
)。 但是,-r
或 --listen-port
之类的选项是可以的。 其次,在调用 SC.EXE 命令时要小心空格:key= value
模式中 key=
之间不能有空格,并且 value
之前必须有且只有一个空格。 最后,要小心要调用的命令行中的空格。 如果目录名包含空格(或其他需要转义的字符),请将 binpath
的整个内部值放在双引号中,并进行转义
C:\> sc create svn binpath= "\"C:\program files\svn\bin\svnserve.exe\" --service -r C:\repos" displayname= "Subversion Server" depend= Tcpip start= auto
还要注意,binpath
这个词具有一定的误导性——它的值是一个 命令行,而不是可执行文件的路径。 这就是为什么如果它包含嵌入的空格,你需要用引号将其括起来的原因。
定义服务后,可以使用标准的 GUI 工具(服务管理控制面板)或在命令行中停止、启动或查询服务
C:\> net stop svn C:\> net start svn
也可以通过删除服务的定义来卸载(即取消定义)服务:sc delete svn
。 确保先停止服务! SC.EXE 程序还有许多其他子命令和选项;运行 sc /?
以了解更多信息。
Mac OS X(10.4 及更高版本)使用 launchd 来管理进程(包括守护进程),包括系统范围的进程和每个用户的进程。 launchd 作业由 XML 属性列表文件中的参数指定,而 launchctl 命令用于管理这些作业的生命周期。
当配置为作为 launchd 作业运行时,svnserve 会在需要处理传入 Subversion svn://
网络流量时自动按需启动。 这比需要您手动调用 svnserve 作为长时间运行的后台进程的配置要方便得多。
要将 svnserve 配置为 launchd 作业,请首先创建一个名为 /Library/LaunchDaemons/org.apache.subversion.svnserve.plist
的作业定义文件。 示例 6.1,“一个 svnserve launchd 作业定义示例” 提供了这样一个文件的示例。
示例 6.1. 一个 svnserve launchd 作业定义示例
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>org.apache.subversion.svnserve</string> <key>ServiceDescription</key> <string>Host Subversion repositories using svn:// scheme</string> <key>ProgramArguments</key> <array> <string>/usr/bin/svnserve</string> <string>--inetd</string> <string>--root=/var/svn</string> </array> <key>UserName</key> <string>svn</string> <key>GroupName</key> <string>svn</string> <key>inetdCompatibility</key> <dict> <key>Wait</key> <false/> </dict> <key>Sockets</key> <dict> <key>Listeners</key> <array> <dict> <key>SockServiceName</key> <string>svn</string> <key>Bonjour</key> <true/> </dict> </array> </dict> </dict> </plist>
警告 | |
---|---|
launchd 系统可能有点难以学习。 幸运的是,有关本节中描述的命令的文档是存在的。 例如,在命令行中运行 |
创建作业定义文件后,可以使用 launchctl load 激活作业
$ sudo launchctl load \ -w /Library/LaunchDaemons/org.apache.subversion.svnserve.plist
明确地说,此操作实际上不会启动 svnserve。 它只是告诉 launchd 如何在 svn
网络端口上收到传入的网络流量时启动 svnserve;它将在流量处理完毕后终止 svnserve。
注意 | |
---|---|
因为我们希望 svnserve 成为系统范围的守护进程,我们需要使用 sudo 以管理员身份管理此任务。还要注意,定义文件中的 |
停用该任务同样简单 - 使用 launchctl unload
$ sudo launchctl unload \ -w /Library/LaunchDaemons/org.apache.subversion.svnserve.plist
launchctl 还提供了一种查询任务状态的方法。如果该任务已加载,则将有一行与作业定义文件中指定的 Label
匹配
$ sudo launchctl list | grep org.apache.subversion.svnserve - 0 org.apache.subversion.svnserve $
客户端选择一个特定的存储库。
服务器处理存储库的 conf/svnserve.conf
文件,并开始执行其中描述的任何身份验证和授权策略。
根据定义的策略,可能会发生以下情况之一
客户端可以被允许匿名发出请求,而无需接收身份验证质询。
客户端可以在任何时候被质询身份验证。
如果在隧道模式下操作,客户端将声明自己已被外部身份验证(通常通过 SSH)。
默认情况下,svnserve 服务器只知道如何发送 CRAM-MD5[61] 身份验证质询。本质上,服务器向客户端发送少量数据。客户端使用 MD5 哈希算法对数据和密码的组合创建指纹,然后将指纹作为响应发送。服务器使用存储的密码执行相同的计算,以验证结果是否相同。实际密码不会在网络上传输。
如果您的 svnserve 服务器是使用 SASL 支持构建的,它不仅知道如何发送 CRAM-MD5 质询,而且还可能知道许多其他身份验证机制。请参阅本章后面的 名为“使用 SASL 的 svnserve”的部分,了解如何配置 SASL 身份验证和加密。
当然,客户端也可以通过隧道代理(如 ssh)进行外部身份验证。在这种情况下,服务器只需检查它运行的用户,并将此名称用作已验证的用户名。有关此内容的更多信息,请参阅后面的部分,名为“通过 SSH 建立隧道”的部分.
如您所料,存储库的 svnserve.conf
文件是控制对存储库访问的中心机制。当与本节中描述的其他辅助文件结合使用时,此配置文件为管理员提供了管理用户身份验证和授权策略的完整解决方案。我们将讨论的每个文件都使用其他配置文件通用的格式(请参阅 名为“运行时配置区域”的部分):节名称用方括号 ([
和 ]
) 标记,注释以井号 (#
) 开头,每个节都包含可以设置的特定变量 (variable = value
)。现在让我们逐步了解这些文件,并学习如何使用它们。
目前,svnserve.conf
的 [general]
节包含您所需的所有变量。首先更改这些变量的值:为包含用户名和密码的文件选择一个名称,并选择一个身份验证领域
[general] password-db = userfile realm = example realm
realm
是您定义的名称。它告诉客户端他们连接到哪种 “身份验证命名空间”;Subversion 客户端在身份验证提示中显示它,并将其用作密钥(与服务器的主机名和端口一起)在磁盘上缓存凭据(请参阅 名为“缓存凭据”的部分)。password-db
变量指向包含用户名和密码列表的单独文件,使用相同的熟悉格式。例如
[users] harry = foopassword sally = barpassword
password-db
的值可以是用户文件的绝对路径或相对路径。对于许多管理员来说,将文件保存在存储库的 conf/
区域中,与 svnserve.conf
相邻,很容易。另一方面,您可能希望两个或多个存储库共享同一个用户文件;在这种情况下,该文件可能应该位于更公开的位置。共享用户文件的存储库也应该配置为具有相同的领域,因为用户列表实际上定义了身份验证领域。无论该文件位于何处,请务必适当地设置该文件的读写权限。如果您知道 svnserve 将以哪个用户身份运行,请根据需要限制对用户文件的读访问权限。
在 svnserve.conf
文件中还有两个变量需要设置:它们决定未经身份验证(匿名)用户和已验证用户可以执行的操作。变量 anon-access
和 auth-access
可以设置为 none
、read
或 write
。将值设置为 none
禁止读取和写入;read
允许只读访问存储库,而 write
允许完全读写访问存储库。例如
[general] password-db = userfile realm = example realm # anonymous users can only read the repository anon-access = read # authenticated users can both read and write auth-access = write
实际上,示例设置是这些变量的默认值,如果您忘记定义它们。如果您想更加保守,可以完全阻止匿名访问
[general] password-db = userfile realm = example realm # anonymous users aren't allowed anon-access = none # authenticated users can both read and write auth-access = write
服务器进程不仅理解对存储库的这些 “全局” 访问控制,而且还理解对存储库中特定文件和目录的更细粒度的访问限制。要使用此功能,您需要定义一个包含更详细规则的文件,然后将 authz-db
变量设置为指向它
[general] password-db = userfile realm = example realm # Specific access rules for specific locations authz-db = authzfile
我们将在本章后面的 名为“基于路径的授权”的部分 中详细讨论 authzfile
文件的语法。请注意,authz-db
变量不是与 anon-access
和 auth-access
变量相互排斥的;如果所有变量都同时定义,则必须满足所有规则才能允许访问。
对于许多团队来说,内置的 CRAM-MD5 身份验证是他们从 svnserve 中所需的一切。但是,如果您的服务器(和您的 Subversion 客户端)是使用 Cyrus 简单身份验证和安全层 (SASL) 库构建的,那么您将可以使用许多身份验证和加密选项。
通常,当 subversion 客户端连接到 svnserve 时,服务器会发送一个问候语,宣传其支持的功能列表,而客户端会以类似的功能列表进行响应。如果服务器配置为要求身份验证,则它会发送一个质询,列出可用的身份验证机制;客户端通过选择其中一种机制进行响应,然后身份验证通过一定数量的往返消息完成。即使没有 SASL 功能,客户端和服务器也天生知道如何使用 CRAM-MD5 和 ANONYMOUS 机制(请参阅 名为“内置身份验证和授权”的部分)。如果服务器和客户端链接到 SASL,则许多其他身份验证机制也可能可用。但是,您需要在服务器端显式配置 SASL 才能宣传它们。
要在服务器上激活特定的 SASL 机制,您需要做两件事。首先,在存储库的 svnserve.conf
文件中创建一个 [sasl]
节,其中包含一个初始键值对
[sasl] use-sasl = true
其次,在 SASL 库可以找到它的地方创建一个名为 svn.conf
的主 SASL 配置文件 - 通常位于 SASL 插件所在的目录中。您需要在您的特定系统上找到插件目录,例如 /usr/lib/sasl2/
或 /etc/sasl2/
。(请注意,这不是存储库中的 svnserve.conf
文件!)
在 Windows 服务器上,您还需要编辑系统注册表(使用 regedit 等工具)以告诉 SASL 在哪里找到东西。创建一个名为 [HKEY_LOCAL_MACHINE\SOFTWARE\Carnegie Mellon\Project Cyrus\SASL Library]
的注册表项,并在其中放置两个项:一个名为 SearchPath
的项(其值为包含 SASL sasl*.dll
插件库的目录的路径)和一个名为 ConfFile
的项(其值为包含您创建的 svn.conf
文件的父目录的路径)。
由于 SASL 提供了如此多种身份验证机制,因此尝试描述每种可能的服务器端配置将是愚蠢的(并且远远超出本书的范围)。相反,我们建议您阅读 SASL 源代码 doc/
子目录中提供的文档。它详细介绍了每种机制以及如何为每种机制适当地配置服务器。为了讨论的目的,我们只演示配置 DIGEST-MD5 机制的简单示例。例如,如果您的 svn.conf
文件包含以下内容
pwcheck_method: auxprop auxprop_plugin: sasldb sasldb_path: /etc/my_sasldb mech_list: DIGEST-MD5
您已告诉 SASL 向客户端宣传 DIGEST-MD5 机制,并检查用户密码是否与位于 /etc/my_sasldb
的私有密码数据库匹配。然后,系统管理员可以使用 saslpasswd2 程序在数据库中添加或修改用户名和密码
$ saslpasswd2 -c -f /etc/my_sasldb -u realm username
一些警告:首先,确保saslpasswd2的“realm”参数与您在存储库的svnserve.conf
文件中定义的 realm 相匹配;如果它们不匹配,身份验证将失败。此外,由于 SASL 的缺陷,公共 realm 必须是一个不包含空格的字符串。最后,如果您决定使用标准的 SASL 密码数据库,请确保svnserve程序对该文件具有读取权限(如果使用 OTP 等机制,可能还需要写入权限)。
这只是配置 SASL 的一种简单方法。还有许多其他身份验证机制可用,密码可以存储在其他地方,例如 LDAP 或 SQL 数据库中。有关详细信息,请参阅完整的 SASL 文档。
请记住,如果您将服务器配置为仅允许某些 SASL 身份验证机制,那么这将强制所有连接的客户端也支持 SASL。任何没有 SASL 支持的 Subversion 客户端(包括所有 1.5 之前的客户端)都无法进行身份验证。一方面,这种限制可能正是您想要的(“我的客户端必须全部使用 Kerberos!””)。但是,如果您仍然希望非 SASL 客户端能够进行身份验证,请确保将 CRAM-MD5 机制作为选项进行宣传。所有客户端都可以使用 CRAM-MD5,无论它们是否具有 SASL 功能。
如果特定的机制支持,SASL 也可以执行数据加密。内置的 CRAM-MD5 机制不支持加密,但 DIGEST-MD5 支持,而 SRP 等机制实际上需要使用 OpenSSL 库。要启用或禁用不同级别的加密,您可以在存储库的svnserve.conf
文件中设置两个值
[sasl] use-sasl = true min-encryption = 128 max-encryption = 256
min-encryption
和 max-encryption
变量控制服务器要求的加密级别。要完全禁用加密,请将这两个值都设置为 0。要启用数据的简单校验和(即,防止篡改并保证数据完整性,但没有加密),请将这两个值都设置为 1。如果您希望允许(但不要求)加密,请将最小值设置为 0,并将最大值设置为某个比特长度。要无条件地要求加密,请将这两个值都设置为大于 1 的数字。在我们之前的示例中,我们要求客户端至少进行 128 位加密,但不能超过 256 位加密。
svnserve 的内置身份验证(和 SASL 支持)非常方便,因为它避免了创建真实系统帐户的需要。另一方面,一些管理员已经拥有完善的 SSH 身份验证框架。在这些情况下,所有项目用户已经拥有系统帐户,并且能够“SSH 到” 服务器机器。
将 SSH 与svnserve一起使用非常容易。客户端只需使用svn+ssh://
URL 方案连接
$ whoami harry $ svn list svn+ssh://host.example.com/repos/project [email protected]'s password: ***** foo bar baz …
在这个例子中,Subversion 客户端正在调用一个本地ssh进程,连接到host.example.com
,以用户harryssh
的身份进行身份验证(根据 SSH 用户配置),然后在远程机器上以用户harryssh
的身份启动一个私有的svnserve进程。该svnserve命令在隧道模式(-t
)下被调用,并且它的网络协议被“隧道” 通过加密连接由ssh,即隧道代理。如果客户端执行提交操作,则经过身份验证的用户名harryssh
将用作新修订版本的作者。
这里需要理解的重要一点是,Subversion 客户端没有连接到正在运行的svnserve守护进程。这种访问方式不需要守护进程,也不会在存在守护进程的情况下注意到它。它完全依赖于ssh启动一个临时的svnserve进程的能力,该进程会在网络连接关闭时终止。
当使用svn+ssh://
URL 访问存储库时,请记住,是ssh程序提示进行身份验证,而不是 svn 客户端程序。这意味着没有自动密码缓存(参见名为“缓存凭据”的部分)。Subversion 客户端通常会与存储库建立多个连接,虽然用户通常不会注意到这一点,因为密码缓存功能。但是,当使用svn+ssh://
URL 时,用户可能会因ssh对每个出站连接反复询问密码而感到困扰。解决方案是在类 Unix 系统上使用单独的 SSH 密码缓存工具,如ssh-agent,或在 Windows 上使用pageant。
在通过隧道运行时,授权主要由对存储库数据库文件的操作系统权限控制;这与 Harry 直接通过file://
URL 访问存储库的情况非常相似。如果多个系统用户将直接访问存储库,您可能希望将它们放入一个公共组中,并且您需要小心 umask(请务必阅读本章后面名为“支持多种存储库访问方法”的部分)。但是,即使在隧道情况下,您仍然可以使用svnserve.conf
文件阻止访问,只需将auth-access = read
或auth-access = none
设置为[62]
您可能会认为 SSH 隧道的故事到此结束,但事实并非如此。Subversion 允许您在运行时config
文件中创建自定义隧道行为(参见名为“运行时配置区域”的部分)。例如,假设您想使用 RSH 而不是 SSH。[63]在您的config
文件的[tunnels]
部分,只需将其定义如下
[tunnels] rsh = rsh --
现在,您可以使用与新变量名称匹配的 URL 方案来使用这个新的隧道定义:svn+rsh://host/path
。当使用新的 URL 方案时,Subversion 客户端实际上会在后台运行命令rsh -- host svnserve -t
。如果您在 URL 中包含用户名(例如,svn+rsh://username@host/path
),客户端也会将其包含在命令中(rsh -- username@host svnserve -t
)。
警告 | |
---|---|
请注意,在定义基于 RSH 的隧道时,我们在隧道命令行中添加了 |
但是,您可以定义新的隧道方案,使其比这更智能
[tunnels] joessh = $JOESSH /opt/alternate/ssh -p 29934 --
此示例演示了几个方面。首先,它展示了如何使 Subversion 客户端启动一个非常特定的隧道二进制文件(位于/opt/alternate/ssh
)并带有特定的选项。在这种情况下,访问svn+joessh://
URL 将调用特定的 SSH 二进制文件,其参数为-p 29934
,这在您希望隧道程序连接到非标准端口时非常有用。
其次,它展示了如何定义一个自定义环境变量,该变量可以覆盖隧道程序的名称。设置SVN_SSH
环境变量是一种方便的方式来覆盖默认的 SSH 隧道代理。但是,如果您需要为不同的服务器设置多个不同的覆盖,每个覆盖可能都会联系不同的端口或将不同的选项传递给 SSH,那么您可以使用此示例中演示的机制。现在,如果我们要设置JOESSH
环境变量,它的值将覆盖隧道变量的整个值,$JOESSH将被执行,而不是/opt/alternate/ssh -p 29934
。
您不仅可以控制客户端调用ssh的方式,还可以控制服务器机器上sshd的行为。在本节中,我们将展示如何控制由sshd执行的精确svnserve命令,以及如何让多个用户共享一个系统帐户。
首先,找到您将用来启动svnserve的帐户的主目录。确保该帐户安装了 SSH 公钥/私钥对,并且用户可以通过公钥身份验证登录。密码身份验证将不起作用,因为以下所有 SSH 技巧都围绕着使用 SSHauthorized_keys
文件。
如果它不存在,请创建authorized_keys
文件(在 Unix 上,通常为~/.ssh/authorized_keys
)。该文件中的每一行都描述一个允许连接的公钥。这些行通常采用以下格式
ssh-dsa AAAABtce9euch… [email protected]
第一个字段描述密钥类型,第二个字段是 base64 编码的密钥本身,第三个字段是注释。但是,鲜为人知的是,整个行可以以command
字段开头
command="program" ssh-dsa AAAABtce9euch… [email protected]
当设置command
字段时,SSH 守护进程将运行指定的程序,而不是 Subversion 客户端要求的典型的隧道模式svnserve调用。这为许多服务器端技巧打开了大门。在以下示例中,我们将文件中的行缩写为
command="program" TYPE KEY COMMENT
由于我们可以指定执行的服务器端命令,因此可以轻松地命名要运行的特定svnserve二进制文件并向其传递额外的参数
command="/path/to/svnserve -t -r /virtual/root" TYPE KEY COMMENT
在这个例子中,/path/to/svnserve
可能是一个围绕svnserve的自定义包装脚本,它设置了 umask(参见名为“支持多种存储库访问方法”的部分)。它还展示了如何在虚拟根目录中锚定svnserve,就像人们在以守护进程方式运行svnserve时通常做的那样。这样做可能是为了限制对系统部分的访问,或者仅仅是为了让用户不必在svn+ssh://
URL 中键入绝对路径。
也可以让多个用户共享一个帐户。与其为每个用户创建一个单独的系统帐户,不如为每个人生成一个公钥/私钥对。然后将每个公钥放入authorized_keys
文件中,每行一个,并使用--tunnel-user
选项
command="svnserve -t --tunnel-user=harry" TYPE1 KEY1 [email protected] command="svnserve -t --tunnel-user=sally" TYPE2 KEY2 [email protected]
此示例允许 Harry 和 Sally 通过公钥认证连接到同一个帐户。他们每个人都有一个自定义命令会被执行;--tunnel-user
选项告诉 svnserve 假设命名参数是经过身份验证的用户。没有 --tunnel-user
,所有提交看起来都像是来自同一个共享系统帐户。
最后要提醒一句:在共享帐户中通过公钥授予用户对服务器的访问权限,可能仍然允许其他形式的 SSH 访问,即使您已在 authorized_keys
中设置了 command
值。例如,用户可能仍然可以通过 SSH 获取 shell 访问权限,或者能够通过您的服务器执行 X11 或通用端口转发。为了尽可能减少用户权限,您可能希望在 command
后立即指定一些限制性选项。
command="svnserve -t --tunnel-user=harry",no-port-forwarding,no-agent-forw arding,no-X11-forwarding,no-pty TYPE1 KEY1 [email protected]
请注意,所有这些都必须在一行上 - 确实在一行上 - 因为 SSH authorized_keys
文件甚至不允许使用传统的反斜杠字符 (\
) 来续行。我们之所以用换行符来显示它,只是为了适应书本的物理页面。
在前面的部分中,我们提到了管理员可以在他们的 svnserve.conf
文件中使用许多配置选项来配置 Subversion 通过 Subversion 的 svnserve 服务器选项访问时的行为。在本节中,我们将快速总结 所有 此服务器支持的配置选项。
svnserve.conf
配置文件使用典型的 INI 风格格式,将名称/值对选项分组到命名部分中。(这与 Subversion 在网络客户端使用的运行时配置区域使用的格式相同,这很方便。)我们将在此描述每个命名部分以及在其中可用的选项。
默认情况下,svnserve 会在存储库的物理目录结构内的 conf/svnserve.conf
中查找每个存储库的配置文件。要使用单个配置文件,其值适用于通过 svnserve 实例提供的所有存储库,请在启动服务器时使用 --config-file
选项。
注意 | |
---|---|
在以下各节中,我们将使用其规范名称 |
[general]
部分包含最常用且范围最广的 svnserve 配置选项。
anon-access
控制授予未经身份验证(匿名)用户的访问级别。有效值为 write
、read
和 none
,默认值为 read
。
auth-access
控制授予已认证用户的访问级别。有效值为 write
、read
和 none
,默认值为 write
。
authz-db
指定存储库访问文件的路径,如 “基于路径的访问控制入门”部分 所述。如果使用常规本地路径,则除非该路径以正斜杠字符 (/
) 开头,否则它将被解释为相对于包含 svnserve.conf
配置文件的目录的路径。如果未指定路径,则基于路径的访问控制将被禁用。
作为一项特殊考虑,您还可以指定已在 Subversion 存储库中进行版本控制的访问文件的路径。使用本地 URL(以 file://
开头的 URL)来引用绝对 Subversion 版本控制的访问文件。或者,使用存储库相对 URL(以 ^/
开头的 URL)来使 svnserve 为每个存储库查询存储在该存储库中指定相对 URL 处的访问文件。
force-username-case
指定在将用户名与访问文件(由 authz-db
选项指定)中的规则进行比较之前应用于用户名的案例规范化。有效值为 upper
(将用户名转换为大写)、lower
(将用户名转换为小写)和 none
(不执行任何规范化)。默认情况下,svnserve 不会对用户名执行任何大小写规范化。
groups-db
指定组文件的路径。如果使用常规本地路径,则除非该路径以正斜杠字符 (/
) 开头,否则它将被解释为相对于包含 svnserve.conf
配置文件的目录的路径。
您还可以指定已在 Subversion 存储库中进行版本控制的组文件的路径。使用本地 URL(以 file://
开头的 URL)来引用绝对 Subversion 版本控制的文件。或者,使用存储库相对 URL(以 ^/
开头的 URL)来使 svnserve 为每个存储库查询存储在该存储库中指定相对 URL 处的组文件。
hooks-env
指定钩子脚本环境配置文件的路径。此选项将覆盖此文件的每个存储库默认位置,并且可以用于在单个文件中为多个存储库配置钩子脚本环境,前提是指定了绝对路径。除非您指定绝对路径,否则文件的路径将被解释为相对于包含 svnserve.conf
配置文件的目录的路径。
有关钩子脚本环境配置文件的详细信息,请参见 “钩子脚本环境配置”部分。
password-db
指定密码数据库文件的路径。除非指定的路径以正斜杠字符 (/
) 开头,否则它将被解释为相对于包含 svnserve.conf
配置文件的目录的路径。请注意,如果使用 SASL 功能,则此选项将被忽略。
realm
指定存储库的身份验证域。这主要由客户端用于将缓存的身份验证凭据与特定存储库或一组存储库关联。因此,最好使指定的域在您的存储库中是唯一的,除非这些存储库共享同一个密码数据库。默认情况下,存储库的 UUID 用作其身份验证域。
[sasl]
部分包含特定于 svnserve 的可选 Cyrus 简单身份验证和安全层 (SASL) 集成功能的配置。有关此功能及其提供的优势的更详细说明,请参见 “将 svnserve 与 SASL 配合使用”部分。
max-encryption
指定安全层的加密算法的所需最大强度(以整数位宽表示)。特殊值 0
表示“无加密”,特殊值 1
表示“仅完整性检查”。此选项的默认值为 256
(256 位加密)。
min-encryption
指定安全层的加密算法的所需最小强度(以整数位宽表示)。特殊值 0
表示“无加密”,特殊值 1
表示“仅完整性检查”。此选项的默认值为 0
(无加密)。
use-sasl
指定(作为 true
或 false
值)是否启用 Cyrus SASL 功能。请注意,此功能仅在 svnserve 构建时支持该功能才可用。默认情况下,此功能处于禁用状态。
[61] 请参阅 RFC 2195。
[62] 请注意,只有在用户无法绕过它并使用其他工具(如 cd 和 vi)直接访问存储库目录的情况下,使用任何形式的 svnserve 强制访问控制才有意义;“控制调用的命令”部分 描述了如何实施此类限制。
[63] 我们实际上不推荐这样做,因为 RSH 的安全性明显低于 SSH。