为了确保一切正常,我在 ubuntu 14.04 服务器(用于托管)上使用 Subversion 命令行客户端、版本 1.8.8 和 ubuntu 16.04 笔记本电脑(用于使用 SVN)按照这些确切的说明进行操作。 [很久以后,我用 Ubuntu 18.04.3 LTS 服务器和客户端测试/确认了这一点(即两台计算机具有相同的当前操作系统)。]
第 1 步:定义用户。
假设我们有两个不同的用户将使用 SVN。我们必须在机器上为这些用户定义本地帐户,以便能够将他们放入一个公共组中。这是授予组对存储库的写访问权限所必需的,否则提交不起作用。我们还将了解如何阻止这些用户登录服务器(因为我们只希望他们作为 SVN 用户;本地帐户只是为此目的不可避免的手段)。
由于 svn+ssh 需要 SSH 登录,我们需要一个额外的用户来连接机器。所以,我们有:
USER-1 (to access SVN)
USER-2 (to access SVN)
SSH-USER (to connect to the server)
SVN-GROUP (a group with members USER-1 and USER-2)
在命令中,即:
adduser USER-1
adduser USER-2
adduser SSH-USER
groupadd SVN-GROUP
sudo usermod -aG SVN-GROUP USER-1
sudo usermod -aG SVN-GROUP USER-2
要检查一切是否正确,您可以通过以下方式列出群组及其成员(如 How to list all users in a Linux group? 中所述 - 如果您觉得有用,请选择该答案/回复):
awk -F: '/^SVN-GROUP/ {print $4;}' /etc/group
第 2 步:创建 SVN 并填充内容。
首先,我们使用用于登录服务器的用户 SSH-USER 登录服务器。然后,我们为 SVN 创建一个空文件夹,然后用一个空的 SVN 填充它,然后设置权限,使组中的每个人都有完全访问权限。
mkdir /home/SSH-USER/SVN
svnadmin create /home/SSH-USER/SVN
chgrp -R SVN-GROUP /home/SSH-USER/SVN
chown -R SSH-USER /home/SSH-USER/SVN
chmod -R 770 /home/SSH-USER/SVN
最后两个命令从“其他人”那里获得所有权限,并赋予所有者(SSH-USER)和组(SVN-GROUP)读/写/执行权限。我已经测试过了:仅使用读/写权限是不够的。但是,我们可以给所有者 0(无权限),因为我们只需要他登录,而不需要提交或读取或任何其他内容。但是,如果我们要删除该用户的整个 SVN,我们不应该窃取他的权限。
尽管还没有配置访问控制,我们现在已经可以用内容填充它了。原因是本地用户 SSH-USER 可以直接提交更改,即使 SVN 访问配置(我们还没有触及)确实禁止它。我们只添加了两个空文件夹:
svn mkdir file:///home/SSH-USER/SVN/folder1
svn mkdir file:///home/SSH-USER/SVN/folder2
第 3 步:配置 SVN 访问控制。
首先,我们编辑SVN的“主配置文件”:/home/SSH-USER/SVN/conf/svnserve.conf。在这里,请确保该文件包含以下三行:
anon-access = none
auth-access = write
authz-db = authz
一些注意事项:所有三行都已存在于文件中,但已被注释掉。然而,第一行默认授予匿名就绪访问权限,因此我们将其从“read”更改为“none”。此外,在大多数指令中,要求取消注释“# password-db = passwd”这一行。但是我们不需要这个,因为我们只授予 SVN+SSH 访问权限,所以没有使用密码。
激活身份验证文件 authz 后,我们现在使用它来设置哪个用户可以访问哪个文件夹。因此,请确保文件 authz 包含以下几行:
[groups]
SVN-GROUP = USER-1,USER-2
[/]
* =
@SVN-GROUP = rw
首先,请注意,为了保持一致性,authz 文件中使用的组名的选择方式与我们在服务器上的组相同。您可以选择任何您想要的组名。另一方面,用户必须与服务器上的本地用户相同。根据上面的定义,两个用户都拥有对整个存储库的完全访问权限,而其他用户没有任何访问权限。可以通过简单地添加更多内容来添加更具体的权利,例如:
[/folder1]
USER-1 = rw
USER-2 =
[/folder2]
USER-1 =
USER-2 = rw
第 4 步:设置对服务器的访问权限。
首先,我们需要创建一个文件夹“.ssh”,然后为所有想要访问 SVN 的用户添加公共 SSH 密钥。但是,个人用户不会使用他们的个人帐户登录,而是使用用户 SSH-USER 的帐户。这样,我们就有一个文件来管理访问。当其中一个用户登录(使用 SSH-USER 的帐户)时,ssh 访问文件会将该用户更改为相应的本地用户。
mkdir /home/SSH-USER/.ssh
touch /home/SSH-USER/.ssh/authorized_keys
nano /home/SSH-USER/.ssh/authorized_keys
现在用以下内容填充authorized_keys:
command="svnserve -t -r /home/SSH-USER --log-file=/home/SSH-USER/SVN/svnlog.txt --tunnel-user=USER-1 --config-file=/home/SSH-USER/SVN/conf/svnserve.conf" ssh-rsa PUBLIC-KEY-OF-USER-1 local-username-on@client-pc-of-USER-1
command="svnserve -t -r /home/SSH-USER --log-file=/home/SSH-USER/SVN/svnlog.txt --tunnel-user=USER-2 --config-file=/home/SSH-USER/SVN/conf/svnserve.conf" ssh-rsa PUBLIC-KEY-OF-USER-2 local-username-on@client-pc-of-USER-2
对于不熟悉 authorized_keys 文件的用户,请注意 local-username-on@client-pc-of-USER-i 只是一个标签来管理/标记不同的条目(即用户名和机器),所以放在这里的“信息”不能错。此外,PUBLIC-KEY-OF-USER-i 是实际密钥,即在该用户的相应公钥文件中找到的非常长的字符串。
现在,两个用户都可以使用以下命令访问 SVN:“svn checkout svn+ssh://SSH-USER@SERVER-URL/SVN .”。注意,由于之前设置的限制,USER-1只能访问folder1,USER-2只能访问folder2。此外,由于 svnserve 命令将 /home/SSH-USER 定义为 SVN 的根目录,因此 checkout 命令不需要(或被允许)使用完整路径,而只是 /home/SSH-USER 之后的所有内容(即,该文件夹需要以 /SVN 开头)。
第 5 步:微调(可选)。
有一些可选但方便的事情仍然想做:
(1) 减少对 USER-1 和 USER-2 的权限。
(2) 不允许 USER-1 和 USER-2 在服务器上通过 SSH 登录。
(3) 允许 SSH-USER 进行 SSH 登录(用于配置目的)。
(1)
对于大多数教程/等。我发现,建议在访问控制中添加“no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty”以限制各自的权限。请自行搜索,他们有什么限制。然后,authorized_keys 文件将如下所示:
command="svnserve -t -r /home/SSH-USER --log-file=/home/SSH-USER/SVN/svnlog.txt --tunnel-user=USER-1 --config-file=/home/SSH-USER/SVN/conf/svnserve.conf",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-rsa PUBLIC-KEY-OF-USER-1 local-username-on@client-pc-of-USER-1
command="svnserve -t -r /home/SSH-USER --log-file=/home/SSH-USER/SVN/svnlog.txt --tunnel-user=USER-2 --config-file=/home/SSH-USER/SVN/conf/svnserve.conf",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-rsa PUBLIC-KEY-OF-USER-2 local-username-on@client-pc-of-USER-2
(2)
我们必须创建本地用户 USER-1 和 USER-2,以便他们能够获得对存储库的写入权限。但是,我们不希望它们能够连接到服务器(运行程序等)。当然,我们不能告诉他们他们的密码,但显然似乎有更好的方法。为此,请考虑问题https://serverfault.com/questions/538915/prevent-user-access-to-console-but-still-allow-svnssh-access-to-svn-repos。
(3)
在 authorized_keys 文件中使用的所有 SSH 密钥都不能再通过 SSH 以 SSH-USER 身份登录,因为登录时会执行 svnserve 命令,这会阻止使用控制台。因此,如果仍然希望能够以 SSH-USER 身份登录,则需要依靠不同的 SSH 密钥登录(并仅使用表达式“ssh-rsa PUBLIC-KEY local-username”将其放入 authorized_keys 文件中-on@client-pc”)。如果 PUBLIC-KEY 已在该文件中使用(例如,因为想以 USER-1 或 USER-2(使用存储库)和 SSH-USER 身份登录以进行配置),则需要创建第二个SSH 密钥并告诉控制台应该将这个用于 SSH 而不是另一个已用于 SVN+SSH 的控制台(用于重定向到 USER-1 或 USER-2)。这里给出了一个很好的解决方案:how to login via ssh if "svnserve -t" is given in authorized_keys?