Organisatie van toegang voor meerdere gebruikers tot de GIT-server

Bij het installeren en configureren van een Git-server rijst de vraag over het organiseren van de toegang voor meerdere gebruikers tot meerdere projecten. Ik heb het probleem onderzocht en een oplossing gevonden die aan al mijn eisen voldeed: eenvoudig, veilig en betrouwbaar.

Mijn wensen zijn:

  • elke gebruiker maakt verbinding met zijn eigen account
  • Meerdere gebruikers kunnen aan één project werken
  • dezelfde gebruiker kan aan meerdere projecten werken
  • elke gebruiker heeft alleen toegang tot de projecten waaraan hij werkt
  • Het zou mogelijk moeten zijn om verbinding te maken via de opdrachtregel, en niet alleen via een soort webinterface

Het zou ook geweldig zijn:

  • geef alleen-lezen machtigingen aan controlerende personen
  • Beheer eenvoudig gebruikerstoegangsrechten in Git

Overzicht van mogelijke opties voor toegang tot de GIT-server

Allereerst moet je weten waar je uit moet kiezen, dus hier is een kort overzicht van Git-protocollen.

  • ssh - een speciaal aangemaakt gebruikersaccount wordt gebruikt om toegang te krijgen tot de server.
    • Het is vreemd dat Git het gebruik van één account voor toegang tot alle repository's niet uitsluit van zijn aanbevelingen. Dit voldoet totaal niet aan mijn eisen.
    • U kunt meerdere accounts gebruiken, maar hoe kunt u de gebruikerstoegang beperken tot slechts bepaalde mappen?
      • Sluiten in de homedirectory is niet geschikt, omdat het moeilijk is om daar schrijftoegang voor andere gebruikers te organiseren
      • Het gebruik van symlinks vanuit je homedirectory is ook moeilijk omdat Git ze niet als links interpreteert
      • Het is mogelijk om de toegang tot de tolk te beperken, maar er is geen volledige garantie dat dit altijd zal werken
        • Voor dergelijke gebruikers kunt u over het algemeen uw eigen opdrachtinterpreter aansluiten, maar
          • ten eerste is dit al een moeilijke beslissing,
          • en ten tweede kan dit worden omzeild.

    Maar misschien is het geen probleem dat de gebruiker alle opdrachten kan uitvoeren? Over het algemeen kan deze methode niet worden uitgesloten als u precies weet hoe u deze moet gebruiken. We komen later op deze methode terug, maar voor nu zullen we kort de andere alternatieven overwegen, misschien is er iets eenvoudigers.

  • Het git local protocol kan gebruikt worden in combinatie met sshfs, er kunnen meerdere gebruikers gebruikt worden, maar in wezen hetzelfde als het vorige geval
  • http - alleen-lezen
  • git is alleen-lezen
  • https - moeilijk te installeren, je hebt extra software nodig, een soort controlepaneel om gebruikerstoegang te organiseren... het lijkt haalbaar, maar op de een of andere manier is alles ingewikkeld.

Het ssh-protocol gebruiken om toegang voor meerdere gebruikers tot de Git-server te organiseren

Laten we terugkeren naar het ssh-protocol.

Omdat je ssh-toegang voor git gebruikt, moet je de veiligheid van de servergegevens garanderen. De gebruiker die verbinding maakt via ssh gebruikt zijn eigen login op de Linux-server, zodat hij verbinding kan maken via de ssh-client en toegang kan krijgen tot de opdrachtregel van de server.
Er bestaat geen volledige bescherming tegen dergelijke toegang.

Maar de gebruiker zou niet geïnteresseerd moeten zijn in Linux-bestanden. Significante informatie wordt alleen in de git-repository opgeslagen. Daarom is het mogelijk om de toegang niet te beperken via de opdrachtregel, maar om Linux-tools te gebruiken om de gebruiker te verbieden projecten te bekijken, met uitzondering van de projecten waaraan hij deelneemt.
De voor de hand liggende keuze is om het Linux-machtigingensysteem te gebruiken.

Zoals reeds vermeld is het mogelijk om slechts één account te gebruiken voor ssh-toegang. Deze configuratie is voor verschillende gebruikers onveilig, hoewel deze wel is opgenomen in de lijst met aanbevolen git-opties.

Om de vereisten aan het begin van het artikel te implementeren, wordt de volgende directorystructuur gemaakt met de toewijzing van rechten en eigenaren:

1) projectmappen

map1(proj1:proj1,0770)
map2(proj2:proj2,0770)
map3(proj3:proj3,0770)
...
waar
dir1, dir2, dir3 - projectmappen: project 1, project 2, project 3.

proj1:proj1, proj2:proj2, proj3:proj3 zijn speciaal aangemaakte Linux-gebruikers die zijn toegewezen als eigenaren van de overeenkomstige projectmappen.

machtigingen voor alle mappen zijn ingesteld op 0770 - volledige toegang voor de eigenaar en zijn groep en een volledige verbanning voor alle anderen.

2) ontwikkelaarsaccounts

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

Het belangrijkste punt is dat ontwikkelaars een extra groep van de systeemgebruiker-eigenaar van het overeenkomstige project krijgen toegewezen. Dit wordt gedaan door de Linux-serverbeheerder met één commando.

In dit voorbeeld werkt "Ontwikkelaar 1" aan de projecten proj1 en proj2, en "Ontwikkelaar 2" aan de projecten proj2 en proj3.

Als een van de ontwikkelaars verbinding maakt via ssh via de opdrachtregel, zijn hun rechten niet voldoende, zelfs niet om de inhoud van projectmappen te bekijken waaraan ze niet deelnemen. Hij kan dit zelf niet veranderen.

Omdat de basis van dit principe de basisveiligheid van Linux-rechten is, is dit schema betrouwbaar. Bovendien is de regeling zeer eenvoudig uit te voeren.

Laten we gaan oefenen.

Git-repository's maken op een Linux-server

Laten we het controleren.

[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

Ik ben het beu om het met de hand te typen...

[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

Wij zijn ervan overtuigd dat het onmogelijk is om vanaf de opdrachtregel toegang te krijgen tot de repository's van anderen en zelfs de inhoud ervan te bekijken.

[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

Werk samen met meerdere ontwikkelaars aan hetzelfde project in Git

Er blijft één vraag over: als een ontwikkelaar een nieuw bestand introduceert, kunnen andere ontwikkelaars dit niet wijzigen, omdat hij zelf de eigenaar is (bijvoorbeeld dev1) en niet de gebruikerseigenaar van het project (bijvoorbeeld proj1). Omdat we een repository aan de serverzijde hebben, moeten we allereerst weten hoe de map “.git” is gestructureerd en of er nieuwe bestanden zijn gemaakt.

Een lokale Git-repository maken en naar de Git-server pushen

Laten we verder gaan naar de clientmachine.

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>

Tegelijkertijd worden er nieuwe bestanden op de server aangemaakt en deze zijn eigendom van de gebruiker die de push heeft uitgevoerd

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

Wanneer je wijzigingen uploadt naar de Git-server, worden er extra bestanden en mappen aangemaakt, en hun eigenaar is feitelijk de gebruiker die de upload maakt. Maar dan komt de groep van deze bestanden en mappen ook overeen met de hoofdgroep van deze gebruiker, dat wil zeggen de dev1-groep voor de dev1-gebruiker en de dev2-groep voor de dev2-gebruiker (het veranderen van de hoofdgroep van de ontwikkelaar-gebruiker zal niet helpen, want hoe kun je dan aan meerdere projecten werken?). In dit geval kan gebruiker dev2 geen bestanden wijzigen die zijn gemaakt door gebruiker dev1, wat zou kunnen leiden tot een storing in de functionaliteit.

Linux chown - het wijzigen van de eigenaar van een bestand door een gewone gebruiker

De eigenaar van een bestand kan het eigendom ervan niet veranderen. Maar hij kan de groep wijzigen van een bestand dat bij hem hoort, en vervolgens kan dit bestand worden gewijzigd door andere gebruikers die zich in dezelfde groep bevinden. Dat is wat we nodig hebben.

Git-hook gebruiken

De werkmap voor hook is de hoofdmap van het project. hook is een uitvoerbaar bestand dat draait onder de gebruiker die de push uitvoert. Als we dit weten, kunnen we onze plannen uitvoeren.

[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

of gewoon

vi hooks/post-update

Laten we terugkeren naar de clientmachine.

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

Op de Git-server controleren we de werking van het hook-post-update-script na de commit

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

- leeg, alles is in orde.

Een tweede ontwikkelaar koppelen in Git

Laten we het werk van de tweede ontwikkelaar simuleren.

Op de cliënt

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

En tegelijkertijd op de server...

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

— weer leeg, alles werkt.

Een Git-project verwijderen en het project downloaden van de Git-server

Welnu, u kunt er nogmaals voor zorgen dat alle wijzigingen zijn opgeslagen.

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

— om een ​​Git-project te verwijderen, maakt u eenvoudigweg de map volledig leeg. Laten we de gegenereerde fout accepteren, aangezien het onmogelijk is om de huidige map te verwijderen met deze opdracht, maar dit is precies het gedrag dat we nodig hebben.

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"

Toegang delen in Git

Laten we er nu voor zorgen dat zelfs via Git de tweede ontwikkelaar geen toegang kan krijgen tot het Proj1-project, waaraan hij niet werkt.

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.

Nu geven we toegang

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

en daarna werkt alles.

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

Voor meer informatie,

Als er bovendien een probleem is met de standaardrechten bij het maken van bestanden en mappen, kunt u in CentOS de opdracht gebruiken

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

Ook in het artikel kun je kleine nuttige dingen tegenkomen:

  • hoe je een mappenboom bouwt in Linux
  • hoe je een reeks adressen in sed doorgeeft van een bepaalde regel naar het einde van het bestand, dat wil zeggen, een vervanging in sed maakt in alle regels behalve de eerste regel
  • Hoe een zoekvoorwaarde in Linux find om te keren
  • Hoe je meerdere regels in een lus kunt doorgeven met behulp van een one-liner in de Linux-shell
  • Hoe je kunt ontsnappen aan enkele aanhalingstekens in bash
  • hoe u een map met de volledige inhoud ervan op de Windows-opdrachtregel verwijdert
  • Hoe bash mv te gebruiken om een ​​bestand te hernoemen zonder het opnieuw te schrijven

Dank u voor uw aandacht.

Bron: www.habr.com

Voeg een reactie