Organisation de l'accĂšs multi-utilisateurs au serveur GIT

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

Mes souhaits sont les suivants:

  • 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 n'a accĂšs qu'aux projets sur lesquels il travaille
  • devrait ĂȘtre en mesure de se connecter via la ligne de commande, et pas seulement via une sorte d'interface Web

Ce serait aussi formidable:

  • accorder des droits en lecture seule aux personnes dĂ©tenant le contrĂŽle
  • administrer facilement les autorisations des utilisateurs dans Git

Présentation des options d'accÚs au serveur GIT


Tout d'abord, vous devez savoir quoi choisir, 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 des recommandations l'utilisation d'un seul compte pour accĂ©der Ă  tous les rĂ©fĂ©rentiels. Cela ne correspond pas Ă  mes exigences.
    • Vous pouvez utiliser plusieurs comptes, mais comment restreindre l'accĂšs des utilisateurs Ă  certains rĂ©pertoires uniquement?

      • La fermeture du rĂ©pertoire personnel ne convient pas, car il est difficile d'organiser l'accĂšs en Ă©criture pour les autres utilisateurs
      • L'utilisation de liens symboliques depuis le 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 rien ne garantit que cela fonctionnera toujours

        • Vous pouvez mĂȘme connecter votre propre interprĂ©teur de commandes pour ces utilisateurs, mais,

          • premiĂšrement, c'est dĂ©jĂ  une sorte de dĂ©cision difficile,
          • et en 2, cela peut ĂȘtre contournĂ©.

    Mais peut-ĂȘtre que ce n'est pas un problĂšme que l'utilisateur sera en mesure d'exĂ©cuter des commandes? .. En gĂ©nĂ©ral, cette mĂ©thode ne peut pas ĂȘtre exclue si vous trouvez comment l'utiliser. Nous reviendrons sur cette mĂ©thode plus tard, mais pour l'instant, considĂ©rons briĂšvement les autres alternatives, peut-ĂȘtre que quelque chose y sera plus facile.
  • Le protocole local git peut ĂȘtre utilisĂ© en combinaison avec sshfs, plusieurs utilisateurs peuvent ĂȘtre utilisĂ©s, mais en substance, c'est le mĂȘme que le cas prĂ©cĂ©dent
  • http - lecture seule
  • git est en lecture seule
  • https - il est difficile Ă  installer, vous avez besoin de logiciels supplĂ©mentaires, d'une sorte de panneau de contrĂŽle pour organiser l'accĂšs des utilisateurs ... cela semble faisable, mais en quelque sorte c'est compliquĂ©.

Utilisation du protocole ssh pour organiser l'accĂšs multi-utilisateur au serveur Git


Revenons au protocole ssh.

L'accÚs ssh étant utilisé pour git, vous devez sécuriser les données du serveur. L'utilisateur qui se connecte via ssh utilise sa propre connexion sur le serveur Linux, il peut donc se connecter via le client ssh et accéder à la ligne de commande du serveur.
Il n'y a pas de protection complĂšte contre l'obtention d'un tel accĂšs.

Mais l'utilisateur ne devrait pas ĂȘtre intĂ©ressĂ© par les fichiers Linux. Les informations importantes sont stockĂ©es uniquement dans le rĂ©fĂ©rentiel git. Par consĂ©quent, vous ne pouvez pas restreindre l'accĂšs via la ligne de commande, mais Linux peut empĂȘcher l'utilisateur de regarder des projets, Ă  l'exclusion de ceux auxquels il participe.
Évidemment, en utilisant le systùme d'autorisations Linux.

Comme déjà mentionné, il est possible d'utiliser un seul compte pour l'accÚs ssh. Cette configuration n'est pas sûre pour plusieurs utilisateurs, bien que cette méthode soit incluse dans la liste des options git recommandées.

Pour implémenter 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

dir1 (proj1: proj1,0770)
dir2 (proj2: proj2,0770)
dir3 (proj3: proj3,0770)
...
oĂč
dir1, dir2, dir3 - répertoires du projet: projet 1, projet 2, projet 3.

proj1: proj1, proj2: proj2, proj3: proj3 - des utilisateurs Linux spécialement créés qui sont désignés comme les propriétaires des répertoires des projets respectifs.

les droits sur tous les répertoires sont définis en 0770 - un accÚs complet pour le propriétaire et son groupe et une interdiction complÚte pour tout le monde.

2) comptes de développeur

Développeur 1: dev1: dev1, proj1, proj2
Développeur 2: dev2: dev2, proj2, proj3

Le point clé est que les développeurs se voient attribuer un groupe supplémentaire de l'utilisateur systÚme propriétaire du projet correspondant. Cette opération est effectuée par l'administrateur du serveur Linux en tant que commande unique.

Dans cet exemple, «Developer 1» fonctionne sur les projets proj1 et proj2 et «Developer 2» fonctionne sur les projets proj2 et proj3.

Si l'un des dĂ©veloppeurs se connecte via ssh via la ligne de commande, ses droits ne seront mĂȘme pas suffisants pour afficher le contenu des rĂ©pertoires de projet dans lesquels il n'est pas impliquĂ©. Lui-mĂȘme ne peut rien changer Ă  cela.

Puisque la base de ce principe est la sécurité de base des droits Linux, ce schéma est fiable. De plus, le régime est trÚs facile à administrer.

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 

fatigué de taper avec mes mains ...

 [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 nous assurons qu'il est impossible d'accĂ©der aux rĂ©fĂ©rentiels d'autres personnes Ă  partir de la ligne de commande et mĂȘme de voir 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 

Collaboration dans Git de plusieurs dĂ©veloppeurs sur un mĂȘme projet


Une question demeure, si un dĂ©veloppeur introduit un nouveau fichier, le reste des dĂ©veloppeurs ne peut pas le modifier, car il le possĂšde lui-mĂȘme (par exemple, dev1), et non l'utilisateur propriĂ©taire du projet (par exemple, proj1). Étant donnĂ© que nous avons un rĂ©fĂ©rentiel de serveur, vous devez tout d'abord savoir comment le rĂ©pertoire ".git" est organisĂ© et si de nouveaux fichiers sont créés.

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


Passons Ă  la machine cliente.

 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> 

Dans le mĂȘme temps, de nouveaux fichiers se forment sur le serveur, et ils 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 les modifications sont tĂ©lĂ©chargĂ©es sur le serveur Git, des fichiers et des rĂ©pertoires supplĂ©mentaires sont créés et, en mĂȘme temps, l'utilisateur qui effectue le tĂ©lĂ©chargement est le propriĂ©taire. 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 de dĂ©veloppement n'aidera pas, car alors comment travailler sur plusieurs projets?). Dans ce cas, l'utilisateur dev2 ne pourra pas modifier les fichiers créés par l'utilisateur dev1, ce qui est lourd de violation de fonctionnalitĂ©.

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



Le propriĂ©taire du fichier ne peut pas modifier sa propriĂ©tĂ©. Mais il peut modifier le groupe du fichier qui lui appartient, puis ce fichier peut ĂȘtre disponible pour ĂȘtre modifiĂ© par d'autres utilisateurs du mĂȘme groupe. VoilĂ  ce dont nous avons besoin.

Utilisation de git hook


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 qui pousse. sachant cela, nous pouvons réaliser notre plan.

 [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 

Retour Ă  la machine cliente.

 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 

Sur le serveur Git, on vérifie aprÚs le commit l'opération du script hook post-mise à jour

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

- vide, tout va bien.

Connecter un deuxiÚme développeur à Git


Nous imiterons le travail du deuxiÚme développeur.

Sur le 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 

Et en mĂȘme temps, sur le serveur ...

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

- vide Ă  nouveau, tout fonctionne.

Suppression d'un projet Git et téléchargement d'un projet à partir d'un serveur Git


Eh bien, vous pouvez à nouveau vous assurer que toutes les modifications sont conservées.

 C:\gittest>rd /S /Q .       ,       . 

- Pour supprimer un projet Git, effacez complÚtement le répertoire. Nous allons supporter l'erreur générée, car il est impossible de supprimer le répertoire en cours pour cette commande, mais nous avons juste besoin de ce comportement.

 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" 

Partage d'accĂšs dans Git


Maintenant, assurons-nous 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:\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. 

Autorisez maintenant l'accĂšs

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

et aprĂšs cela, tout fonctionne.

 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 

Information additionnelle


De plus, en cas de 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 -mo::5 -mg::7 /var/gitservertest 

Dans l'article, vous pouvez également tomber sur de petites choses utiles:

  • comment construire une arborescence de rĂ©pertoires sous Linux
  • comment sed pour transfĂ©rer une plage d'adresses d'une certaine ligne Ă  la fin du fichier, c'est-Ă -dire pour faire un remplacement dans sed dans toutes les lignes sauf la premiĂšre ligne
  • Comment trouver sur Linux pour inverser un terme de recherche
  • comment dans le shell Linux pour boucler plusieurs lignes sur une seule ligne
  • comment Ă©chapper aux guillemets simples dans bash
  • comment supprimer le rĂ©pertoire avec tout le contenu sur la ligne de commande Windows
  • Comment utiliser bash mv pour renommer un fichier sans le réécrire

Merci de votre attention.

Source: https://habr.com/ru/post/fr457056/


All Articles