When installing and configuring a Git-server, the question arises about the organization of access of several users to several projects. I conducted a research question and found a solution that meets all my requirements: simple, safe, reliable.
My wishes are as follows:
- each user connects with his own account
- several users can work on one project
- the same user can work on multiple projects
- each user has access only to the projects he is working on
- should be able to connect through the command line, and not just through some kind of web interface
It would also be great:
')
- grant read-only rights to supervisors
- convenient to administer user access rights in git
Overview of access options on the GIT server
First of all, you need to know what to choose from, so a quick overview of the Git protocols.
- ssh - a specially created user account is used to access the server.
- strange that Git does not exclude from the recommendations of the use of a single account to access all repositories. It does not meet my requirements.
- You can use multiple accounts, but how to restrict user access to only certain directories?
- Closing the home directory is not suitable, because it is difficult to organize access to the record for other users
- Using symbolic links from the home directory is also difficult due to the fact that Git does not interpret them as links
- Restrict access to the interpreter, well, you can, but there is no full guarantee that this will always work
- You can even connect for these users your command interpreter, but,
- in the 1st, this is already some kind of difficult decision,
- and in 2, it can be bypassed.
But maybe this is not a problem, that the user will be able to execute any commands? .. In general, this method cannot be excluded if we figure out exactly how to use it. Let's come back to this method later, but for now let's take a quick look at the other alternatives, maybe there will be something easier.
- The git local protocol can be used in combination with sshfs, you can use multiple users, but in essence, this is the same as the previous case.
- http - read only
- git is read only
- https is difficult to install, you need additional software, some kind of control panel for organizing user access ... it looks realizable, but somehow everything is difficult.
Using ssh for multi-user access to a Git server
Let's go back to the ssh protocol.
Since ssh access is used for git, you need to ensure the security of the server data. A user who connects via ssh uses his own login on the Linux server, so he can connect via the ssh client and access the server command line.
There is no complete protection against such access.
But the user should not be interested in Linux files. Relevant information is stored only in the git repository. Therefore, it is possible not to restrict access via the command line, but using Linux tools to prevent the user from watching projects, excluding those in which he participates.
Obviously use the Linux permissions system.
As already mentioned, it is possible to use only one account for ssh access. This configuration is unsafe for several users, although this method is included in the list of recommended git options.
To implement the requirements listed at the beginning of the article, the following directory structure is created with assignment of rights and owners:
1) project directories
dir1 (proj1: proj1,0770)
dir2 (proj2: proj2,0770)
dir3 (proj3: proj3,0770)
...
Where
dir1, dir2, dir3 - project directories: project 1, project 2, project 3.
proj1: proj1, proj2: proj2, proj3: proj3 are specially created Linux users who are appointed by the owners of the directories of the respective projects.
The rights to all directories are set at 0770 - full access for the owner and his group and total ban for all others.
2) developer accounts
Developer 1: dev1: dev1, proj1, proj2
Developer 2: dev2: dev2, proj2, proj3
The key point is that developers are assigned an additional group of the system user who owns the corresponding project. This is done by the Linux server administrator with a single command.
In this example, Developer 1 is working on project proj1 and proj2, and Developer 2 is working on projects proj2 and proj3.
If any of the Developers connects via ssh via the command line, then its rights will not be enough even to view the contents of the directories of projects in which it does not participate. He cannot change it himself.
Since the basis of this principle is basic security of Linux rights, this scheme is reliable. In addition, the scheme is very easy to administer.
Let's go to practice.
Creating Git repositories on a Linux server
We are checking.
[root@server ~]
tired of typing hands ...
[root@server gitservertest]
We are convinced that from the command line it is impossible to access other repositories and even to see their contents.
[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 collaboration of several developers on one project
One question remains, if one developer enters a new file, the other developers cannot change it, because he himself owns it (for example, dev1), and not the user who owns the project (for example, proj1). Since we have a server repository, first of all, you need to know how the ".git" directory is organized and whether new files are created.
Creating a local Git repository and push to the Git server
Let's go to the client machine.
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>
At the same time, new files are generated on the server, and they belong to the user who pushed.
[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]$
When changes are uploaded to the Git server, additional files and directories are created, and they are actually owned by the user who is uploading. But then the group of these files and directories also corresponds to the main group of this user, that is, the group dev1 for the user dev1 and the group dev2 for the user dev2 (changing the main group of the user developer does not help, because then how to work on several projects?). In this case, the user dev2 will not be able to change the files created by the user dev1, and this is fraught with a violation of functionality.
Linux chown - change the owner of the file as a regular user
The owner of the file cannot change its ownership. But he can change the group of the file that belongs to him, and then this file can be available for changing to other users who are in the same group. That's what we need.
Using git hook
The working directory for the hook is the project root directory. A hook is an executable file that runs under the user who pushes. Knowing this, we can carry out our plans.
[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
either just
vi hooks/post-update
Let's go back to the client machine.
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
On the Git server, after the commit, we check the work of the post-update script hook
[dev1@server proj2]$ find . ! -group proj2
- empty, everything is fine.
Connection of the second developer in Git
Let's simulate the work of the second developer.
On the client
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
And at the same time, on the server ...
[dev1@server proj2]$ find . ! -group proj2
- again empty, everything works.
Deleting a Git project and loading a project from a Git server
Well, you can once again make sure that all changes are preserved.
C:\gittest>rd /S /Q . , .
- to delete a Git project, simply clear the directory completely. Let us put up with the error, since it is impossible to delete the current directory on this command, but we just need this behavior.
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 access sharing
Now let's make sure that the second developer cannot access the Proj1 project, which he doesnβt work with, through Git.
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.
Now allow access
[root@server ~]
and after that everything works.
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
additional information
In addition, if there is a problem with the default permissions when creating files and directories, you can use the command in CentOS
setfacl -Rd -mo::5 -mg::7 /var/gitservertest
Also in the article you may stumble upon small useful things:
- how to build a directory tree in linux
- how in sed to transfer a range of addresses from a certain line to the end of the file, that is, to make a replacement in sed in all lines except the first line
- How to find a search term in Linux
- How to transfer a few lines to a loop through a single linux shell
- how to bash single quotes in bash
- how to delete the directory with all its contents in the windows command line
- How to rename a file using bash mv, without overwriting it again
Thanks for attention.