在安装和配置Git服务器时,出现了组织多个用户对多个项目进行访问的问题。 我对该问题进行了研究,发现了一个可以满足我所有要求的解决方案:简单,安全,可靠。
我的愿望如下:
- 每个用户都使用自己的帐户进行连接
- 多个用户可以从事一个项目
- 同一用户可以从事多个项目
- 每个用户只能访问他所从事的那些项目
- 应该能够通过命令行进行连接,而不仅仅是通过某种Web界面进行连接
这也很棒:
访问GIT服务器的选项概述
首先,您需要知道从中选择什么,因此简要概述了Git协议。
- ssh-专门创建的用户帐户用于访问服务器。
- 奇怪的是,Git没有从建议中排除使用单个帐户访问所有存储库的建议。 这不符合我的要求。
- 您可以使用多个帐户,但是如何限制用户仅访问某些目录?
- 不适合关闭主目录,因为在此难以组织其他用户的写访问权限
- 使用主目录中的符号链接也很困难,因为Git不会将它们解释为链接
- 可以限制对口译员的访问,但不能完全保证这将始终有效
- 您甚至可以为此类用户连接自己的命令解释器,但是,
- 首先,这已经是某种困难的决定,
- 而在2中,可以避免这种情况。
但是,也许这不是用户将能够执行任何命令的问题吗?..通常,如果您想出如何使用该方法,则不能排除该方法。 稍后我们将返回此方法,但现在暂时简要考虑其他替代方法,可能会更容易一些。
- git local协议可以与sshfs结合使用,可以使用多个用户,但从本质上讲,这与前面的情况相同
- http-只读
- git是只读的
- https-安装困难,您需要其他软件,以及用于组织用户访问权限的某种控制面板...看起来可行,但是有点复杂。
使用ssh协议来组织对Git服务器的多用户访问
返回ssh协议。
由于ssh访问用于git,因此您需要保护服务器数据。 通过ssh连接的用户在Linux服务器上使用自己的登录名,因此他可以通过ssh客户端连接并访问服务器命令行。
没有全面的保护措施来防止获得这种访问权限。
但是用户不应对Linux文件感兴趣。 重要信息仅存储在git存储库中。 因此,您不能限制通过命令行的访问,但是Linux可以阻止用户观看项目,但不包括参与的项目。
显然使用Linux权限系统。
如前所述,可以仅使用一个帐户进行ssh访问。 尽管此方法包含在推荐的git选项列表中,但此配置对多个用户而言是不安全的。
为了实现本文开头给出的要求,将创建以下目录结构并分配权限和所有者:
1)项目目录
dir1(proj1:proj1,0770)
dir2(proj2:proj2,0770)
dir3(proj3:proj3,0770)
...
在哪里
dir1,dir2,dir3-项目目录:项目1,项目2,项目3。
proj1:proj1,proj2:proj2,proj3:proj3-专门创建的Linux用户,被指定为各个项目的目录的所有者。
在0770中设置了对所有目录的权限-所有者及其所属组具有完全访问权限,而其他所有人则完全禁止访问。
2)开发人员帐户
开发人员1:dev1:dev1,proj1,proj2
开发人员2:dev2:dev2,proj2,proj3
关键是要为开发人员分配拥有相应项目的系统用户的其他组。 这是由Linux服务器管理员作为单个命令完成的。
在此示例中,“开发人员1”处理proj1和proj2项目,“开发人员2”处理proj2和proj3项目。
如果任何开发人员通过命令行通过ssh连接,那么即使查看他不参与的项目目录的内容,他的权限也不够。 他本人无法以任何方式改变这一点。
由于此原则的基础是Linux权限的基本安全性,因此该方案是可靠的。 此外,该方案非常易于管理。
让我们继续练习。
在Linux服务器上创建Git存储库
我们检查。
[root@server ~]
厌倦了用手打字...
[root@server gitservertest]
我们确保不可能从命令行访问其他人的存储库,甚至看不到他们的内容。
[dev1@server ~]$ cd /var/gitservertest/proj3 -bash: cd: /var/gitservertest/proj3: Permission denied [dev1@server ~]$ ls /var/gitservertest/proj3 ls: cannot open directory /var/gitservertest/proj3: Permission denied
Git中多个开发人员在一个项目上的协作
还有一个问题,如果一个开发人员引入了一个新文件,那么其他开发人员就无法更改它,因为他本人拥有该文件(例如dev1),而不是拥有项目的用户(例如proj1)。 由于我们有服务器存储库,因此首先,您需要知道“ .git”目录的排列方式以及是否创建了新文件。
创建本地Git存储库并推送到Git服务器
让我们继续到客户端计算机。
Microsoft Windows [Version 6.1.7601] (c) (Microsoft Corp.), 2009. . C:\gittest>git init . Initialized empty Git repository in C:/gittest/.git/ C:\gittest>echo "test dev1 to proj2" > test1.txt C:\gittest>git add . C:\gittest>git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: test1.txt C:\gittest>git commit -am "new test file added" [master (root-commit) a7ac614] new test file added 1 file changed, 1 insertion(+) create mode 100644 test1.txt C:\gittest>git remote add origin "ssh://dev1@10.1.1.11/var/gitservertest/proj2" C:\gittest>git push origin master dev1:dev1@10.1.1.11's password: Counting objects: 3, done. Writing objects: 100% (3/3), 243 bytes | 243.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) To ssh://10.1.1.11/var/gitservertest/proj2 * [new branch] master -> master C:\gittest>
同时,新文件在服务器上形成,它们属于执行推送的用户
[dev1@server proj2]$ tree . ├── 1.txt ├── branches ├── config ├── description ├── HEAD ├── hooks │ ├── applypatch-msg.sample │ ├── commit-msg.sample │ ├── post-update.sample │ ├── pre-applypatch.sample │ ├── pre-commit.sample │ ├── prepare-commit-msg.sample │ ├── pre-push.sample │ ├── pre-rebase.sample │ └── update.sample ├── info │ └── exclude ├── objects │ ├── 75 │ │ └── dcd269e04852ce2f683b9eb41ecd6030c8c841 │ ├── a7 │ │ └── ac6148611e69b9a074f59a80f356e1e0c8be67 │ ├── f0 │ │ └── 82ea1186a491cd063925d0c2c4f1c056e32ac3 │ ├── info │ └── pack └── refs ├── heads │ └── master └── tags 12 directories, 18 files [dev1@server proj2]$ ls -l objects/75/dcd269e04852ce2f683b9eb41ecd6030c8c841 -r--r--r--. 1 dev1 dev1 54 Jun 20 14:34 objects/75/dcd269e04852ce2f683b9eb41ecd6030c8c841 [dev1@server proj2]$
将更改上传到Git服务器时,将创建其他文件和目录,同时,执行上传的用户是所有者。 但是这些文件和目录的组也对应于该用户的主要组,即用户dev1的组dev1和用户dev2的组dev2(更改开发用户的主要组无济于事,因为从那以后如何处理多个项目?) 在这种情况下,用户dev2将无法修改用户dev1创建的文件,这会导致功能遭到破坏。
Linux chown-普通用户更改文件的所有者
文件的所有者无法更改其所有权。 但是他可以更改属于他的文件的组,然后此文件可用于更改同一组中的其他用户。 这就是我们所需要的。
使用git hook
挂钩的工作目录是项目的根目录。 hook是在执行推送的用户下运行的可执行文件。 知道这一点,我们就可以实现我们的计划。
[dev1@server proj2]$ mv hooks/post-update{.sample,} [dev1@server proj2]$ sed -i '2,$ s/^/#/' hooks/post-update [dev1@server proj2]$ cat <<< 'find . -group $(whoami) -exec chgrp proj2 '"'"'{}'"'"' \;' >> hooks/post-update
要么只是
vi hooks/post-update
回到客户端计算机。
C:\gittest>echo "dev1 3rd line" >> test1.txt C:\gittest>git commit -am "3rd from dev1, testing server hook" [master b045e22] 3rd from dev1, testing server hook 1 file changed, 1 insertion(+) C:\gittest>git push origin master dev1:dev1@10.1.1.11's password: d22c66e..b045e22 master -> master
在Git服务器上,我们在提交后检查钩子更新后脚本的操作
[dev1@server proj2]$ find . ! -group proj2
-空的,一切都很好。
将第二个开发人员连接到Git
我们将模仿第二个开发人员的工作。
在客户端上
C:\gittest>git remote remove origin C:\gittest>git remote add origin "ssh://dev2@10.1.1.11/var/gitservertest/proj2" C:\gittest>echo "!!! dev2 added this" >> test1.txt C:\gittest>echo "!!! dev2 wrote" > test2.txt C:\gittest>git add test2.txt C:\gittest>git commit -am "dev2 added to test1 and created test2" [master 55d49a6] dev2 added to test1 and created test2 2 files changed, 2 insertions(+) create mode 100644 test2.txt C:\gittest>git push origin master dev2@10.1.1.11's password: b045e22..55d49a6 master -> master
同时,在服务器上
[dev1@server proj2]$ find . ! -group proj2
-再次清空,一切正常。
删除Git项目并从Git服务器下载项目
好了,您可以再次确保保留所有更改。
C:\gittest>rd /S /Q . , .
-要删除Git项目,只需完全清除目录即可。 我们将忍受所产生的错误,因为无法删除此命令的当前目录,但是我们只需要这种行为。
C:\gittest>dir C:\gittest 21.06.2019 08:43 <DIR> . 21.06.2019 08:43 <DIR> .. C:\gittest>git clone ssh://dev2@10.1.1.11/var/gitservertest/proj2 Cloning into 'proj2'... dev2@10.1.1.11's password: C:\gittest>cd proj2 C:\gittest\proj2>dir C:\gittest\proj2 21.06.2019 08:46 <DIR> . 21.06.2019 08:46 <DIR> .. 21.06.2019 08:46 114 test1.txt 21.06.2019 08:46 19 test2.txt C:\gittest\proj2>type test1.txt "test dev1 to proj2" "dev1 added some omre" "dev1 3rd line" "!!! dev2 added this" C:\gittest\proj2>type test2.txt "!!! dev2 wrote"
在Git中共享访问
现在,请确保即使通过Git,第二位开发人员也无法访问他不从事的Proj1项目。
C:\gittest\proj2>git remote remove origin C:\gittest\proj2>git remote add origin "ssh://dev2@10.1.1.11/var/gitservertest/proj1" C:\gittest\proj2>git push origin master dev2@10.1.1.11's password: fatal: '/var/gitservertest/proj1' does not appear to be a git repository fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.
现在允许访问
[root@server ~]
之后一切正常。
C:\gittest\proj2>git push origin master dev2@10.1.1.11's password: To ssh://10.1.1.11/var/gitservertest/proj1 * [new branch] master -> master
附加信息
另外,如果在创建文件和目录时默认权限存在问题,在CentOS中,您可以使用以下命令
setfacl -Rd -mo::5 -mg::7 /var/gitservertest
同样在本文中,您可以偶然发现一些有用的东西:
- 如何在Linux上建立目录树
- sed如何将某一范围的地址从某一行传输到文件的末尾,即在第一行以外的所有行中对sed进行替换
- 在Linux上如何找到反转搜索词的方法
- 如何在linux shell中通过单行循环几行
- 如何在bash中转义单引号
- 如何删除Windows命令行上所有内容的目录
- 如何使用bash mv重命名文件而无需再次重写
谢谢您的关注。