Organisation des accès multi-utilisateurs au serveur GIT

Lors de l'installation et de la configuration d'un serveur Git, la question se pose de l'organisation de l'accès de plusieurs utilisateurs à plusieurs projets. J'ai étudié le problème et trouvé une solution qui répondait à toutes mes exigences : simple, sûre, fiable.

Mes souhaits sont :

  • chaque utilisateur se connecte avec son propre compte
  • Plusieurs utilisateurs peuvent travailler sur un même projet
  • le même utilisateur peut travailler sur plusieurs projets
  • chaque utilisateur a accès uniquement aux projets sur lesquels il travaille
  • Il devrait être possible de se connecter via la ligne de commande, et pas seulement via une sorte d'interface Web.

Ce serait aussi génial :

  • accorder des autorisations en lecture seule aux personnes contrôlantes
  • Gérez facilement les droits d'accès des utilisateurs dans Git

Aperçu des options possibles pour accéder au serveur GIT

Tout d’abord, vous devez savoir quoi choisir, voici donc un bref aperçu des protocoles Git.

  • ssh - un compte utilisateur spécialement créé est utilisé pour accéder au serveur.
    • Il est étrange que Git n'exclue pas de ses recommandations l'utilisation d'un seul compte pour accéder à tous les référentiels. Cela ne répond pas du tout à mes exigences.
    • Vous pouvez utiliser plusieurs comptes, mais comment limiter l’accès des utilisateurs à certains répertoires uniquement ?
      • La fermeture dans le répertoire personnel n'est pas adaptée, car il est difficile d'y organiser l'accès en écriture pour les autres utilisateurs
      • Utiliser des liens symboliques depuis votre répertoire personnel est également difficile car Git ne les interprète pas comme des liens
      • Il est possible de restreindre l'accès à l'interprète, mais il n'y a aucune garantie totale que cela fonctionnera toujours
        • Vous pouvez généralement connecter votre propre interpréteur de commandes pour ces utilisateurs, mais
          • premièrement, c'est déjà une sorte de décision difficile,
          • et deuxièmement, cela peut être contourné.

    Mais peut-être que ce n'est pas un problème que l'utilisateur puisse exécuter n'importe quelle commande ?.. En général, cette méthode ne peut pas être exclue si vous comprenez exactement comment l'utiliser. Nous reviendrons sur cette méthode plus tard, mais pour l’instant nous examinerons brièvement les autres alternatives, il y aura peut-être quelque chose de plus simple.

  • Le protocole local git peut être utilisé en combinaison avec sshfs, plusieurs utilisateurs peuvent être utilisés, mais essentiellement le même que dans le cas précédent
  • http - lecture seule
  • git est en lecture seule
  • https - difficile à installer, vous avez besoin d'un logiciel supplémentaire, d'une sorte de panneau de contrôle pour organiser l'accès des utilisateurs... cela semble faisable, mais d'une manière ou d'une autre, tout est compliqué.

Utiliser le protocole ssh pour organiser l'accès multi-utilisateurs au serveur Git

Revenons au protocole ssh.

Puisque vous utilisez l'accès ssh pour git, vous devez assurer la sécurité des données du serveur. L'utilisateur qui se connecte via ssh utilise son propre identifiant sur le serveur Linux, afin de pouvoir se connecter via le client ssh et accéder à la ligne de commande du serveur.
Il n’existe pas de protection complète contre un tel accès.

Mais l'utilisateur ne devrait pas s'intéresser aux fichiers Linux. Les informations importantes sont stockées uniquement dans le référentiel git. Il est donc possible non pas de restreindre l'accès via la ligne de commande, mais d'utiliser des outils Linux pour interdire à l'utilisateur de visualiser les projets, à l'exclusion de ceux auxquels il participe.
Le choix évident est d'utiliser le système de permissions Linux.

Comme déjà mentionné, il est possible d'utiliser un seul compte pour l'accès ssh. Cette configuration est dangereuse pour plusieurs utilisateurs, bien qu'elle soit incluse dans la liste des options git recommandées.

Pour mettre en œuvre les exigences données au début de l'article, la structure de répertoires suivante est créée avec l'attribution des droits et des propriétaires :

1) répertoires de projets

rép1(proj1:proj1,0770)
rép2(proj2:proj2,0770)
rép3(proj3:proj3,0770)
...

dir1, dir2, dir3 - répertoires de projets : projet 1, projet 2, projet 3.

proj1:proj1, proj2:proj2, proj3:proj3 sont des utilisateurs Linux spécialement créés qui sont désignés comme propriétaires des répertoires de projet correspondants.

les autorisations pour tous les répertoires sont définies sur 0770 - accès complet pour le propriétaire et son groupe et interdiction complète pour tous les autres.

2) comptes de développeurs

Разработчик 1: dev1:dev1,proj1,proj2
Разработчик 2: dev2:dev2,proj2,proj3

Le point clé est que les développeurs se voient attribuer un groupe supplémentaire d'utilisateurs système propriétaire du projet correspondant. Ceci est effectué par l'administrateur du serveur Linux avec une seule commande.

Dans cet exemple, le « Développeur 1 » travaille sur les projets proj1 et proj2, et le « Développeur 2 » travaille sur les projets proj2 et proj3.

Si l'un des développeurs se connecte via ssh via la ligne de commande, alors ses droits ne seront pas suffisants même pour visualiser le contenu des répertoires de projets auxquels il ne participe pas. Il ne peut pas changer cela lui-même.

Puisque la base de ce principe est la sécurité fondamentale des droits Linux, ce système est fiable. De plus, le système est très simple à gérer.

Passons à la pratique.

Création de référentiels Git sur un serveur Linux

Nous vérifions.

[root@server ~]# cd /var/
[root@server var]# useradd gitowner
[root@server var]# mkdir gitservertest
[root@server var]# chown gitowner:gitowner gitservertest
[root@server var]# adduser proj1
[root@server var]# adduser proj2
[root@server var]# adduser proj3
[root@server var]# adduser dev1
[root@server var]# adduser dev2
[root@server var]# passwd dev1
[root@server var]# passwd dev2

J'en ai marre de taper à la main...

[root@server gitservertest]# sed "s/ /n/g" <<< "proj1 proj2 proj3" | while read u; do mkdir $u; chown $u:$u $u; chmod 0770 $u; done

[root@server gitservertest]# usermod -aG proj1 dev1
[root@server gitservertest]# usermod -aG proj2 dev1
[root@server gitservertest]# usermod -aG proj2 dev2
[root@server gitservertest]# usermod -aG proj3 dev2

Nous sommes convaincus qu'il est impossible d'accéder aux référentiels d'autres personnes depuis la ligne de commande et même de visualiser leur contenu.

[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

Collaborer avec plusieurs développeurs sur le même projet dans Git

Une question demeure, si un développeur introduit un nouveau fichier, les autres développeurs ne peuvent pas le modifier, car il en est lui-même le propriétaire (par exemple, dev1), et non l'utilisateur propriétaire du projet (par exemple, proj1). Puisque nous avons un référentiel côté serveur, nous devons tout d’abord savoir comment le répertoire « .git » est structuré et si de nouveaux fichiers sont créés.

Création d'un référentiel Git local et transfert vers le serveur Git

Passons à la machine client.

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://[email protected]/var/gitservertest/proj2"

C:gittest>git push origin master
dev1:[email protected]'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>

Parallèlement, de nouveaux fichiers sont créés sur le serveur et appartiennent à l'utilisateur qui a effectué le push.

[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]$

Lorsque vous téléchargez des modifications sur le serveur Git, des fichiers et des répertoires supplémentaires sont créés et leur propriétaire est en fait l'utilisateur qui effectue le téléchargement. Mais alors le groupe de ces fichiers et répertoires correspond également au groupe principal de cet utilisateur, c'est-à-dire le groupe dev1 pour l'utilisateur dev1 et le groupe dev2 pour l'utilisateur dev2 (changer le groupe principal de l'utilisateur développeur n'aidera pas, car alors comment peut-on travailler sur plusieurs projets ?). Dans ce cas, l'utilisateur dev2 ne pourra pas modifier les fichiers créés par l'utilisateur dev1, ce qui pourrait entraîner une panne de fonctionnalité.

Linux chown - changer le propriétaire d'un fichier par un utilisateur régulier

Le propriétaire d'un fichier ne peut pas changer sa propriété. Mais il peut changer le groupe d'un fichier qui lui appartient, et ce fichier peut alors être modifié par d'autres utilisateurs qui sont dans le même groupe. C'est ce dont nous avons besoin.

Utiliser le crochet Git

Le répertoire de travail du hook est le répertoire racine du projet. hook est un exécutable qui s'exécute sous l'utilisateur effectuant le push. Sachant cela, nous pouvons mettre en œuvre nos 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

soit juste

vi hooks/post-update

Revenons à la machine client.

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:[email protected]'s password:
   d22c66e..b045e22  master -> master

Sur le serveur Git, on vérifie le fonctionnement du script hook post-update après le commit

[dev1@server proj2]$ find . ! -group proj2

- vide, tout va bien.

Connecter un deuxième développeur dans Git

Simulons le travail du deuxième développeur.

Sur le client

C:gittest>git remote remove origin

C:gittest>git remote add origin "ssh://[email protected]/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
[email protected]'s password:
   b045e22..55d49a6  master -> master

Et en même temps, sur le serveur...

[dev1@server proj2]$ find . ! -group proj2

— à nouveau vide, tout fonctionne.

Supprimer un projet Git et télécharger le projet depuis le serveur Git

Eh bien, vous pouvez à nouveau vous assurer que toutes les modifications ont été enregistrées.

C:gittest>rd /S /Q .
Процесс не может получить доступ к файлу, так как этот файл занят другим процессом.

— pour supprimer un projet Git, effacez simplement complètement le répertoire. Acceptons l'erreur générée, car il est impossible de supprimer le répertoire courant à l'aide de cette commande, mais c'est exactement le comportement dont nous avons besoin.

C:gittest>dir
 Содержимое папки C:gittest

21.06.2019  08:43    <DIR>          .
21.06.2019  08:43    <DIR>          ..

C:gittest>git clone ssh://[email protected]/var/gitservertest/proj2
Cloning into 'proj2'...
[email protected]'s password:

C:gittest>cd proj2

C:gittestproj2>dir
 Содержимое папки C:gittestproj2

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:gittestproj2>type test1.txt
"test dev1 to proj2"
"dev1 added some omre"
"dev1 3rd line"
"!!! dev2 added this"

C:gittestproj2>type test2.txt
"!!! dev2 wrote"

Partager l'accès dans Git

Assurons-nous maintenant que même via Git, le deuxième développeur ne peut pas accéder au projet Proj1 sur lequel il ne travaille pas.

C:gittestproj2>git remote remove origin

C:gittestproj2>git remote add origin "ssh://[email protected]/var/gitservertest/proj1"

C:gittestproj2>git push origin master
[email protected]'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.

Maintenant, nous autorisons l'accès

[root@server ~]# usermod -aG proj1 dev2

et après tout fonctionne.

C:gittestproj2>git push origin master
[email protected]'s password:
To ssh://10.1.1.11/var/gitservertest/proj1
 * [new branch]      master -> master

Pour plus d'informations,

De plus, s'il y a un problème avec les autorisations par défaut lors de la création de fichiers et de répertoires, dans CentOS, vous pouvez utiliser la commande

setfacl -Rd -m o::5 -m g::7 /var/gitservertest

Également dans l'article, vous pouvez tomber sur de petites choses utiles :

  • comment créer une arborescence de répertoires sous Linux
  • comment transmettre une plage d'adresses dans sed d'une certaine ligne à la fin du fichier, c'est-à-dire effectuer un remplacement dans sed dans toutes les lignes sauf la première ligne
  • Comment inverser une condition de recherche dans Linux Find
  • Comment passer plusieurs lignes dans une boucle à l'aide d'une seule ligne dans le shell Linux
  • Comment échapper aux guillemets simples dans bash
  • comment supprimer un répertoire avec tout son contenu dans la ligne de commande Windows
  • Comment utiliser bash mv pour renommer un fichier sans le réécrire

Je vous remercie de votre attention.

Source: habr.com

Ajouter un commentaire