Při instalaci a konfiguraci Git serveru vyvstává otázka, jak uspořádat přístup několika uživatelů k několika projektům. Provedl jsem výzkum a našel řešení, které splňuje všechny moje požadavky: jednoduché, bezpečné, spolehlivé.
Moje požadavky jsou následující:
- každý uživatel se připojuje se svým vlastním účtem
- na jednom projektu může pracovat několik uživatelů
- tentýž uživatel může pracovat na několika projektech
- každý uživatel má přístup pouze k těm projektům, na kterých pracuje
- měla by být možnost připojení přes příkazový řádek, a ne pouze přes nějaké webové rozhraní
Také by bylo skvělé:
- poskytovat práva pouze pro čtení pro kontrolní osoby
- pohodlné spravování práv přístupu uživatelů v Git
Přehled možných variant přístupu na GIT server
Především je potřeba vědět, z čeho vybírat, a proto stručný přehled protokolů Git.
- ssh — pro přístup na server se používá speciálně zřízený uživatelský účet.
- je divné, že Git nezakazuje používání jednoho účtu pro přístup ke všem repozitářům. To nijak neodpovídá mým požadavkům.
- lze použít několik účtů, ale jak omezit přístup uživatele pouze na určité adresáře?
- Zavření do domácího adresáře nevyhovuje, protože je obtížné zorganizovat k němu přístup pro zápis pro ostatní uživatele
- Použití symbolických odkazů z domácího adresáře je také složité, protože Git je neinterpretuje jako odkazy
- Omezení přístupu k interpretu, no, možné to je, ale není zaručeno, že to vždy bude fungovat
- Možná by se dal pro takové uživatele připojit vlastní příkazový interpret, ale,
- za 1) je to už nějaké složité řešení,
- a za 2) se tomu dá obejít.
- Možná by se dal pro takové uživatele připojit vlastní příkazový interpret, ale,
Ale možná není problém, že uživatel může provádět jakékoli příkazy?.. Každopádně nelze tento způsob vyloučit, pokud se vymyslí, jak ho přesně použít. K tomuto způsobu se vrátíme později, a zatím stručně prozkoumejme ostatní alternativy, možná tam bude něco jednoduššího.
- Protokol git local může být použit v kombinaci s sshfs, lze použít více uživatelů, ale v podstatě je to to samé jako v předchozím případě.
- http — pouze pro čtení.
- git — pouze pro čtení.
- https — obtížná instalace, vyžaduje další software, něco. ovládací panel Pro organizaci přístupu uživatelů… vypadá to realizovatelně, ale je to nějak složité.
Použití protokolu ssh pro organizaci vícero uživatelského přístupu k serveru Git.
Vraťme se k protokolu ssh.
Jelikož se používá přístup přes ssh pro git, je nutné zabezpečit data serveru. Uživatel, který se připojuje přes ssh, používá své vlastní přihlašovací údaje na serveru Linuxu, takže se může připojit prostřednictvím ssh klienta a získat přístup k příkazovému řádku serveru.
Neexistuje žádná úplná ochrana proti takovému přístupu.
Ale uživateli by neměly zajímat soubory Linuxu. Důležité informace jsou uchovávány pouze v repozitáři git. Proto není nutné omezovat přístup přes příkazový řádek, ale pomocí Linuxu zakázat uživateli vidět projekty, kromě těch, na nichž se podílí.
Je zřejmé, že je třeba použít systém oprávnění Linuxu.
Jak již bylo řečeno, je možné používat pouze jeden účet pro ssh přístup. Tato konfigurace je pro více uživatelů nezabezpečená, i když je tento přístup zahrnut v seznamu doporučených git variant.
Pro realizaci požadavků uvedených na začátku článku se vytváří následující struktura adresářů se stanovením oprávnění a vlastníků:
1) adresáře projektů.
dir1(proj1:proj1,0770).
dir2(proj2:proj2,0770).
dir3(proj3:proj3,0770).
…
kde
dir1, dir2, dir3 — adresáře projektů: projekt 1, projekt 2, projekt 3.
proj1:proj1, proj2:proj2, proj3:proj3 — speciálně vytvoření uživatelé Linux, kteří jsou určeni jako vlastníci odpovídajících adresářů projektů.
Oprávnění pro všechny adresáře se nastavují na 0770 — úplný přístup pro vlastníka a jeho skupinu a úplný zákaz pro všechny ostatní.
2) účty vývojářů.
Vývojář 1: dev1:dev1,proj1,proj2.
Vývojář 2: dev2:dev2,proj2,proj3.
Klíčovým bodem je, že vývojářům je přiřazena další skupina systémového uživatele-vlastníka odpovídajícího projektu. To provede administrátor Linux serveru jedním příkazem.
V tomto příkladu "Vývojář 1" pracuje na projektech proj1 a proj2, zatímco "Vývojář 2" pracuje na projektech proj2 a proj3.
Pokud se jakýkoli z vývojářů připojí pomocí ssh přes příkazový řádek, nebudou mít dostatečná práva ani k prohlížení obsahu adresářů projektů, kterých se neúčastní. Nemohou to změnit sami.
Základem tohoto principu je základní bezpečnost práv Linux, což dělá tuto schéma spolehlivou. Kromě toho je schéma velmi snadno spravovatelné.
Přejděme k praxi.
Vytváření Git repozitářů na Linuxovém serveru
Kontrolujeme.
[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
už mě nebaví zadávat ručně…
[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 dev2Ujistíme se, že z příkazového řádku není možné získat přístup k cizím repozitářům a dokonce ani prohlížet jejich obsah.
[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 deniedSpolupráce více vývojářů v Gitu na jednom projektu
Zůstává jedna otázka: pokud jeden vývojář vytvoří nový soubor, ostatní vývojáři jej nemohou měnit, protože je jeho vlastníkem (například dev1), nikoli uživatelským vlastníkem projektu (například proj1). Vzhledem k tomu, že máme serverový repozitář, je nejprve důležité vědět, jak je strukturován adresář „.git“ a zda jsou vytvářeny nové soubory.
Vytvoření místního Git repozitáře a push na Git server
Přejděme na klientský stroj.
Microsoft Windows [Version 6.1.7601]
(c) Microsoft Corporation, 2009. Všechna práva vyhrazena.
C:gittest>git init .
Inicializováno prázdné úložiště Git v C: /gittest/.git/
C:gittest>echo "test dev1 to proj2" > test1.txt
C:gittest>git add .
C:gittest>git status
Na větvi master
Žádné záznamy ještě
Změny k odeslání:
(použijte "git rm --cached <file>..." k odstažení)
nový soubor: test1.txt
C:gittest>git commit -am "nový testovací soubor přidán"
[master (root-commit) a7ac614] nový testovací soubor přidán
1 soubor změněn, 1 vkládání(+)
vytváří režim 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:
Počítání objektů: 3, hotovo.
Zapisování objektů: 100% (3/3), 243 bajtů | 243.00 KiB/s, hotovo.
Celkem 3 (delta 0), opakováno 0 (delta 0)
Do ssh://10.1.1.11/var/gitservertest/proj2
* [nová větev] master -> master
C:gittest>Ve stejném čase se na serveru vytvářejí nové soubory, které patří uživateli, jenž provedl 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 adresářů, 18 souborů
[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]$Při nahrávání změn na server Git vytváří další soubory a adresáře, a jejich vlastníkem skutečně je ten uživatel, který provádí nahrávání. Ale v takovém případě také skupina těchto souborů a adresářů odpovídá hlavní skupině tohoto uživatele, tedy skupina dev1 pro uživatele dev1 a skupina dev2 pro uživatele dev2 (změna hlavní skupiny uživatele-vývojáře nepomůže, protože jak pak pracovat na více projektech?). V takovém případě nebude uživatel dev2 moci měnit soubory, které vytvořil uživatel dev1, což může vést k porušení funkčnosti.
Linux chown — změna vlastníka souboru běžným uživatelským účtem.
Vlastník souboru nemůže měnit jeho příslušnost. Ale může změnit skupinu souboru, kterému patří, a pak může být tento soubor dostupný pro úpravy dalším uživatelům, kteří jsou ve stejné skupině. To je to, co potřebujeme.
Použití Git hook
Pracovní adresář pro hook je kořenový adresář projektu. Hook je spustitelný soubor, který se provádí pod uživatelským účtem, který provádí push. Vědouc to, můžeme realizovat zamýšlené.
[dev1@server proj2]$ mv hooks/post-update{.sample,}
[dev1@server proj2]$ sed -i '2,$ s/^/#/' hooks/post-update
[dev1@server proj2]$ cat <> hooks/post-updatenebo jednoduše
vi hooks/post-updateVraťme se na klientský stroj.
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 -> masterNa Git serveru kontrolujeme po commitu funkčnost skriptu hook post-update.
[dev1@server proj2]$ find . ! -group proj2
— prázdno, vše v pořádku.
Připojení druhého vývojáře v Gitu
Simulujeme práci druhého vývojáře.
Na klientovi
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
A ve stejné době, na serveru…
[dev1@server proj2]$ find . ! -group proj2
— znovu prázdno, vše funguje.
Odstranění projektu Git a stažení projektu z Git serveru
Můžeme se ještě jednou ujistit, že všechny změny se uložily.
C:gittest>rd /S /Q .
Proces nemůže získat přístup k souboru, protože tento soubor je obsazen jiným procesem.— pro odstranění Git projektu jednoduše vymažeme celý adresář. Smíříme se s vydanou chybou, protože není možné odstranit aktuální adresář dle tohoto příkazu, ale právě takové chování potřebujeme.
C:gittest>dir
Obsah složky C:gittest
21.06.2019 08:43 .
21.06.2019 08:43 ..
C:gittest>git clone ssh://dev2@10.1.1.11/var/gitservertest/proj2
Klonování do 'proj2'...
dev2@10.1.1.11's password:
C:gittest>cd proj2
C:gittestproj2>dir
Obsah složky C:gittestproj2
21.06.2019 08:46 .
21.06.2019 08:46 ..
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 more"
"dev1 3rd line"
"!!! dev2 added this"
C:gittestproj2>type test2.txt
"!!! dev2 wrote"Rozdělení přístupu v Gitu
Nyní se ujistíme, že ani přes Git druhý vývojář nemůže přistupovat k projektu Proj1, na kterém nepracuje.
C:gittestproj2>git remote remove origin
C:gittestproj2>git remote add origin "ssh://dev2@10.1.1.11/var/gitservertest/proj1"
C:gittestproj2>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.Nyní povolte přístup
[root@server ~]# usermod -aG proj1 dev2a poté vše funguje.
C:gittestproj2>git push origin master
dev2@10.1.1.11's password:
To ssh://10.1.1.11/var/gitservertest/proj1
* [new branch] master -> masterDalší informace
Navíc, pokud existuje problém s výchozími právy při vytváření souborů a adresářů, v CentOS lze použít příkaz
setfacl -Rd -m o::5 -m g::7 /var/gitservertestTaké v článku můžete narazit na drobné užitečné věci:
- jak v Linuxu vytvořit strom adresářů
- jak v sed předat rozsah adres od určitého řádku do konce souboru, tedy provést v sed nahrazení ve všech řádcích kromě prvního řádku
- Jak v Linuxu inverzovat podmínku hledání pomocí find
- jak v Linuxovém shellu předat do smyčky více řádků přes jednorázový příkaz
- jak v bash správně napsat únik jednoduchých uvozovek
- jak v příkazovém řádku Windows odstranit adresář se vším obsahem
- Jak pomocí bash mv přejmenovat soubor, aniž by ho přepisoval znovu
Děkuji za pozornost.
Zdroj: habr.com
