Organizarea accesului multi-utilizator la serverul GIT

La instalarea și configurarea unui server Git apare întrebarea despre organizarea accesului pentru mai mulți utilizatori la mai multe proiecte. Am cercetat problema și am găsit o soluție care răspundea tuturor cerințelor mele: simplă, sigură, fiabilă.

Dorintele mele sunt:

  • fiecare utilizator se conectează cu propriul cont
  • Mai mulți utilizatori pot lucra la un singur proiect
  • același utilizator poate lucra la mai multe proiecte
  • fiecare utilizator are acces doar la acele proiecte la care lucrează
  • Ar trebui să fie posibilă conectarea prin linia de comandă, și nu doar printr-un fel de interfață web

De asemenea, ar fi grozav:

  • acordați permisiuni numai pentru citire persoanelor care controlează
  • Gestionați convenabil drepturile de acces ale utilizatorilor în Git

Prezentare generală a opțiunilor posibile pentru accesarea serverului GIT

În primul rând, trebuie să știți din ce să alegeți, așa că iată o prezentare generală rapidă a protocoalelor Git.

  • ssh - un cont de utilizator special creat este folosit pentru a accesa serverul.
    • Este ciudat că Git nu exclude din recomandările sale utilizarea unui singur cont pentru a accesa toate depozitele. Acest lucru nu corespunde deloc cerințelor mele.
    • Puteți utiliza mai multe conturi, dar cum puteți limita accesul utilizatorilor doar la anumite directoare?
      • Închiderea în directorul principal nu este potrivită, deoarece este dificil să organizezi accesul la scriere acolo pentru alți utilizatori
      • Utilizarea legăturilor simbolice din directorul dvs. de acasă este, de asemenea, dificilă, deoarece Git nu le interpretează ca link-uri
      • Este posibil să restricționați accesul la interpret, dar nu există o garanție completă că acesta va funcționa întotdeauna
        • În general, vă puteți conecta propriul interpret de comandă pentru astfel de utilizatori, dar
          • în primul rând, aceasta este deja un fel de decizie dificilă,
          • și în al doilea rând, acest lucru poate fi ocolit.

    Dar poate că nu este o problemă faptul că utilizatorul va putea executa orice comenzi?... În general, această metodă nu poate fi exclusă dacă vă dați seama exact cum să o utilizați. Vom reveni la această metodă mai târziu, dar deocamdată vom lua în considerare pe scurt celelalte alternative, poate va fi ceva mai simplu.

  • Protocolul local git poate fi folosit în combinație cu sshfs, pot fi utilizați mai mulți utilizatori, dar în esență la fel ca în cazul precedent
  • http - numai pentru citire
  • git este doar pentru citire
  • https - greu de instalat, ai nevoie de software suplimentar, un fel de panou de control pentru a organiza accesul utilizatorilor... pare fezabil, dar cumva totul este complicat.

Folosind protocolul ssh pentru a organiza accesul multi-utilizator la serverul Git

Să revenim la protocolul ssh.

Deoarece accesul ssh este utilizat pentru git, trebuie să asigurați securitatea datelor de pe server. Utilizatorul care se conectează prin ssh își folosește propria autentificare pe serverul Linux, astfel încât să se poată conecta prin clientul ssh și să acceseze linia de comandă a serverului.
Nu există o protecție completă împotriva unui astfel de acces.

Dar utilizatorul nu ar trebui să fie interesat de fișierele Linux. Informațiile semnificative sunt stocate numai în depozitul git. Prin urmare, este posibil să nu restricționați accesul prin linia de comandă, ci folosind instrumente Linux pentru a interzice utilizatorului să vizualizeze proiecte, cu excepția celor la care participă.
Alegerea evidentă este să utilizați sistemul de permisiuni Linux.

După cum am menționat deja, este posibil să utilizați un singur cont pentru acces ssh. Această configurație este nesigură pentru mai mulți utilizatori, deși este inclusă în lista de opțiuni git recomandate.

Pentru a implementa cerințele date la începutul articolului, este creată următoarea structură de director cu atribuirea drepturilor și proprietarilor:

1) directoare de proiecte

dir1(proj1:proj1,0770)
dir2(proj2:proj2,0770)
dir3(proj3:proj3,0770)
...
unde
dir1, dir2, dir3 - directoare de proiect: proiect 1, proiect 2, proiect 3.

proj1:proj1, proj2:proj2, proj3:proj3 sunt utilizatori Linux special creați, care sunt desemnați ca proprietari ai directoarelor de proiect corespunzătoare.

permisiunile pentru toate directoarele sunt setate la 0770 - acces complet pentru proprietar și grupul său și o interdicție completă pentru toți ceilalți.

2) conturi de dezvoltator

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

Punctul cheie este că dezvoltatorilor li se atribuie un grup suplimentar de proprietar al utilizatorului de sistem al proiectului corespunzător. Acest lucru este realizat de administratorul serverului Linux cu o singură comandă.

În acest exemplu, „Dezvoltatorul 1” lucrează la proiectele proj1 și proj2, iar „Dezvoltatorul 2” lucrează la proiectele proj2 și proj3.

Dacă vreunul dintre Dezvoltatori se conectează prin ssh prin linia de comandă, atunci drepturile sale nu vor fi suficiente nici măcar pentru a vizualiza conținutul directoarelor de proiect la care nu participă. El nu poate schimba asta singur.

Deoarece baza acestui principiu este securitatea de bază a drepturilor Linux, această schemă este fiabilă. În plus, schema este foarte ușor de administrat.

Să mergem mai departe să practicăm.

Crearea depozitelor Git pe un server Linux

Verificăm.

[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

M-am saturat sa scriu de mana...

[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

Suntem convinși că este imposibil să accesezi depozitele altor persoane din linia de comandă și chiar să le vizualizezi conținutul.

[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

Colaborați cu mai mulți dezvoltatori la același proiect în Git

Rămâne o întrebare, dacă un dezvoltator introduce un fișier nou, atunci alți dezvoltatori nu îl pot schimba, deoarece el însuși este proprietarul acestuia (de exemplu, dev1) și nu proprietarul utilizatorului proiectului (de exemplu, proj1). Deoarece avem un depozit pe partea serverului, în primul rând, trebuie să știm cum este structurat directorul „.git” și dacă sunt create fișiere noi.

Crearea unui depozit local Git și împingerea către serverul Git

Să trecem la mașina 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>

În același timp, pe server sunt create fișiere noi și aparțin utilizatorului care a efectuat push-ul

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

Când încărcați modificări pe serverul Git, sunt create fișiere și directoare suplimentare, iar proprietarul acestora este de fapt utilizatorul care face încărcarea. Dar apoi grupul acestor fișiere și directoare corespunde și grupului principal al acestui utilizator, adică grupului dev1 pentru utilizatorul dev1 și grupul dev2 pentru utilizatorul dev2 (schimbarea grupului principal al utilizatorului dezvoltator nu va ajuta, pentru că atunci cum poți lucra la mai multe proiecte?). În acest caz, utilizatorul dev2 nu va putea modifica fișierele create de utilizatorul dev1, ceea ce ar putea duce la o defecțiune a funcționalității.

Linux chown - schimbarea proprietarului unui fișier de către un utilizator obișnuit

Proprietarul unui fișier nu își poate schimba calitatea de proprietar. Dar poate schimba grupul unui fișier care îi aparține, iar apoi acest fișier poate fi modificat de alți utilizatori care se află în același grup. De asta avem nevoie.

Folosind cârligul Git

Directorul de lucru pentru hook este directorul rădăcină al proiectului. hook este un executabil care rulează sub utilizatorul care face push. Știind acest lucru, ne putem implementa planurile.

[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

fie doar

vi hooks/post-update

Să revenim la mașina 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

Pe serverul Git, verificăm funcționarea scriptului post-actualizare hook după comitere

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

- gol, totul este bine.

Conectarea unui al doilea dezvoltator în Git

Să simulăm munca celui de-al doilea dezvoltator.

Pe 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

Și, în același timp, pe server...

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

— gol din nou, totul funcționează.

Ștergerea unui proiect Git și descărcarea proiectului de pe serverul Git

Ei bine, vă puteți asigura încă o dată că toate modificările au fost salvate.

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

— pentru a șterge un proiect Git, pur și simplu ștergeți complet directorul. Să suportăm eroarea care este generată, deoarece este imposibil să ștergem directorul curent folosind această comandă, dar acesta este exact comportamentul de care avem nevoie.

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"

Partajarea accesului în Git

Acum să ne asigurăm că nici prin Git al doilea dezvoltator nu poate accesa proiectul Proj1, la care nu lucrează.

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.

Acum permitem accesul

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

si dupa aceea totul merge.

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

Pentru mai multe informații,

În plus, dacă există o problemă cu permisiunile implicite la crearea fișierelor și directoarelor, în CentOS puteți folosi comanda

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

De asemenea, în articol s-ar putea să dai peste lucruri mici utile:

  • cum să construiți un arbore de directoare în Linux
  • cum să treceți o serie de adrese în sed de la o anumită linie la sfârșitul fișierului, adică să faceți o înlocuire în sed în toate liniile, cu excepția primei linii
  • Cum să inversați o condiție de căutare în Linux find
  • Cum să treceți mai multe linii într-o buclă folosind o singură linie în shell-ul Linux
  • Cum să scapi de ghilimele simple în bash
  • cum să ștergeți un director cu tot conținutul său din linia de comandă Windows
  • Cum să utilizați bash mv pentru a redenumi un fișier fără a-l rescrie din nou

Vă mulțumesc pentru atenție.

Sursa: www.habr.com

Adauga un comentariu