Durante l'installazione e la configurazione del server Git, sorge la questione di come organizzare l'accesso per più utenti a più progetti. Ho condotto una ricerca sull'argomento e ho trovato una soluzione che soddisfa tutti i miei requisiti: semplice, sicura e affidabile.
Le mie richieste sono le seguenti:
- ogni utente si connette con il proprio account
- più utenti possono lavorare su un progetto
- lo stesso utente può lavorare su più progetti
- ogni utente ha accesso solo ai progetti su cui sta lavorando
- deve essere possibile connettersi tramite terminale, e non solo tramite qualche interfaccia web
Sarebbe anche fantastico:
- fornire diritti di sola lettura per i supervisor
- gestire facilmente i diritti di accesso degli utenti in Git
Panoramica delle possibili opzioni di accesso al server GIT
Prima di tutto, è necessario sapere quali opzioni si hanno a disposizione, quindi una breve panoramica dei protocolli Git.
- ssh — per accedere al server si utilizza un'apposita account utente creato ad hoc.
- È strano che Git non escluda dalla sua documentazione l'uso di un unico account per accedere a tutti i repository. Questo non soddisfa le mie esigenze.
- Si possono usare più account, ma come limitare l'accesso di un utente solo a determinate directory?
- Limitare l'accesso alla home directory non è pratico, perché è difficile organizzare l'accesso in scrittura per altri utenti.
- L'utilizzo di link simbolici dalla home directory è complicato poiché Git non li interpreta come collegamenti.
- Limitare l'accesso all'interprete è possibile, ma non c'è garanzia che funzioni sempre.
- Si può anche configurare un interprete di comandi specifico per quegli utenti, ma,
- innanzitutto, si tratta di una soluzione piuttosto complessa,
- e in secondo luogo, è possibile aggirarla.
- Si può anche configurare un interprete di comandi specifico per quegli utenti, ma,
Tuttavia, forse non è un problema che l'utente possa eseguire qualsiasi comando?.. In ogni caso, non possiamo escludere questo metodo, se riusciamo a capire come utilizzarlo correttamente. Torniamo a questa soluzione dopo, per ora esaminiamo le altre alternative; potrebbe esserci qualcosa di più semplice.
- Il protocollo git local può essere utilizzato insieme a sshfs, consentendo più utenti, ma in sostanza è come il caso precedente.
- http — solo in lettura.
- git — solo in lettura.
- https — difficile da impostare, richiede software aggiuntivo. pannello di controllo Per organizzare l'accesso degli utenti... sembra realizzabile, ma è piuttosto complicato.
Utilizzare il protocollo ssh per organizzare l'accesso multiutente al server Git.
Torniamo al protocollo ssh.
Poiché si utilizza l'accesso ssh per git, è necessario garantire la sicurezza dei dati del server. L'utente che si connette tramite ssh usa il proprio login su server Linux, quindi può connettersi tramite client ssh e accedere al terminale del server.
Non esiste una protezione totale contro questo tipo di accesso.
Tuttavia, per l'utente, i file Linux non dovrebbero essere di interesse. Le informazioni significative sono memorizzate solo nel repository git. Pertanto, si può non limitare l'accesso tramite terminale, ma vietare all'utente di visualizzare i progetti tramite gli strumenti di Linux, ad eccezione di quelli a cui partecipa.
È evidente l'utilizzo del sistema di permessi di Linux.
Come già detto, è possibile utilizzare solo un account per l'accesso SSH. Questa configurazione è insicura per più utenti, anche se è inclusa tra le opzioni git consigliate.
Per realizzare i requisiti elencati all'inizio dell'articolo, viene creata la seguente struttura di directory con i diritti e i proprietari assegnati:
1) directory dei progetti
dir1(proj1:proj1,0770)
dir2(proj2:proj2,0770)
dir3(proj3:proj3,0770)
…
dove
dir1, dir2, dir3 — directory dei progetti: progetto 1, progetto 2, progetto 3.
proj1:proj1, proj2:proj2, proj3:proj3 — utenti Linux appositamente creati, designati come proprietari delle directory corrispondenti ai progetti.
I diritti su tutte le directory sono impostati a 0770 — accesso completo per il proprietario e il suo gruppo, e divieto totale per tutti gli altri.
2) account degli sviluppatori
Sviluppatore 1: dev1:dev1,proj1,proj2
Sviluppatore 2: dev2:dev2,proj2,proj3
Il punto chiave è che agli sviluppatori viene assegnato un gruppo aggiuntivo dell'utente di sistema proprietario del progetto corrispondente. Questo viene eseguito dall'amministratore del server Linux con un solo comando.
In questo esempio, «Sviluppatore 1» lavora sui progetti proj1 e proj2, mentre «Sviluppatore 2» lavora sui progetti proj2 e proj3.
Se uno qualsiasi degli Sviluppatori si connette tramite ssh dalla riga di comando, i suoi diritti non saranno sufficienti neanche per visualizzare il contenuto delle directory dei progetti a cui non partecipa. Non può modificarli in alcun modo.
Poiché la base di questo principio è la sicurezza fondamentale dei permessi Linux, questo schema è affidabile. Inoltre, è molto facile da amministrare.
Passiamo alla pratica.
Creazione di repository Git su un server Linux
Verifichiamo.
[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
è stanco di digitare manualmente...
[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 dev2Ci assicuriamo che dalla riga di comando non sia possibile accedere ai repository altrui o anche solo visualizzarne il contenuto.
[dev1@server ~]$ cd /var/gitservertest/proj3
-bash: cd: /var/gitservertest/proj3: Permesso negato
[dev1@server ~]$ ls /var/gitservertest/proj3
ls: impossibile aprire la directory /var/gitservertest/proj3: Permesso negatoCollaborazione in Git tra diversi sviluppatori su un unico progetto
Rimane un'unica domanda: se un sviluppatore aggiunge un nuovo file, gli altri sviluppatori non possono modificarlo perché è proprio lui il proprietario (ad esempio, dev1), e non l'utente proprietario del progetto (ad esempio, proj1). Poiché abbiamo un repository server, è fondamentale comprendere come è strutturata la directory «.git» e se vengono creati nuovi file.
Creazione di un repository Git locale e push su un server Git
Passiamo alla macchina client.
Microsoft Windows [Version 6.1.7601]
(c) Microsoft Corp., 2009. Tutti i diritti riservati.
C:gittest>git init .
Inizializzato un repository Git vuoto in C:/gittest/.git/
C:gittest>echo "test dev1 to proj2" > test1.txt
C:gittest>git add .
C:gittest>git status
Sulla branch master
Nessun commit ancora
Modifiche pronte per essere impegnate:
(usa "git rm --cached <file>..." per annullare)
nuovo file: test1.txt
C:gittest>git commit -am "nuovo file di test aggiunto"
[master (root-commit) a7ac614] nuovo file di test aggiunto
1 file cambiato, 1 inserimento(+)
modalità creata 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:
Conteggio oggetti: 3, fatto.
Scrittura oggetti: 100% (3/3), 243 byte | 243.00 KiB/s, fatto.
Totale 3 (delta 0), riutilizzati 0 (delta 0)
Per ssh://10.1.1.11/var/gitservertest/proj2
* [nuova branch] master -> master
C:gittest>Nel frattempo, nuovi file vengono creati sul server, e appartengono all'utente che ha effettuato il 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]$Quando si caricano modifiche sul server, Git crea file e directory aggiuntivi, e il proprietario è effettivamente l'utente che esegue il caricamento. Pertanto, anche il gruppo di questi file e directory corrisponde al gruppo principale di quell'utente, ossia il gruppo dev1 per l'utente dev1 e il gruppo dev2 per l'utente dev2 (cambiare il gruppo principale dell'utente sviluppatore non aiuta, poiché come si lavora su più progetti?). In questo caso, l'utente dev2 non potrà modificare i file creati dall'utente dev1, il che può compromettere la funzionalità.
Linux chown — modifica del proprietario del file da parte di un utente normale
Il proprietario del file non può modificarne la proprietà. Tuttavia, può cambiare il gruppo del file a lui appartenente, rendendolo accessibile ad altri utenti che appartengono allo stesso gruppo. Questo è ciò di cui abbiamo bisogno.
Utilizzo di Git hook
La directory di lavoro per il hook è la directory principale del progetto. Il hook è un file eseguibile che viene eseguito sotto l'utente che effettua il push. Sapendo questo, possiamo realizzare quanto previsto.
[dev1@server proj2]$ mv hooks/post-update{.sample,}
[dev1@server proj2]$ sed -i '2,$ s/^/#/' hooks/post-update
[dev1@server proj2]$ cat <<> hooks/post-updateoppure semplicemente
vi hooks/post-updateTorniamo sulla macchina del 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:dev1@10.1.1.11's password:
d22c66e..b045e22 master -> masterSul server Git controlliamo che il lavoro dello script hook post-update funzioni dopo il commit
[dev1@server proj2]$ find . ! -group proj2
— vuoto, tutto a posto.
Collegare un secondo sviluppatore in Git
Simuliamo il lavoro del secondo sviluppatore.
Sul 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
E allo stesso tempo, sul server…
[dev1@server proj2]$ find . ! -group proj2
— di nuovo vuoto, tutto funziona.
Rimozione del progetto Git e caricamento del progetto dal server Git
Possiamo ancora assicurarci che tutte le modifiche siano state salvate.
C:gittest>rd /S /Q .
Il processo non può accedere al file perché è occupato da un altro processo.— per rimuovere un progetto Git, basta pulire completamente la directory. Accettiamo l'errore restituito, poiché non è possibile eliminare la directory corrente con questo comando, ma questo comportamento è esattamente ciò di cui abbiamo bisogno.
C:gittest>dir
Contenuto della cartella 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
Clonazione in 'proj2'...
dev2@10.1.1.11's password:
C:gittest>cd proj2
C:gittestproj2>dir
Contenuto della cartella 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 ha aggiunto qualche omre"
"dev1 3a riga"
"!!! dev2 ha aggiunto questo"
C:gittestproj2>type test2.txt
"!!! dev2 ha scritto"Separazione degli accessi in Git
Ora verifichiamo che anche tramite Git il secondo sviluppatore non possa accedere al progetto Proj1, di cui non sta lavorando.
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' non appare come un repository git
fatal: Impossibile leggere dal repository remoto.
Assicurati di avere i diritti di accesso corretti
e che il repository esista.Adesso consentiamo l'accesso
[root@server ~]# usermod -aG proj1 dev2e dopo questo tutto funziona.
C:gittestproj2>git push origin master
dev2@10.1.1.11's password:
Per ssh://10.1.1.11/var/gitservertest/proj1
* [nuova branch] master -> masterUlteriori informazioni
In aggiunta, se ci sono problemi con i diritti predefiniti durante la creazione di file e directory, su CentOS si può utilizzare il comando
setfacl -Rd -m o::5 -m g::7 /var/gitservertestNell'articolo puoi anche imbatterti in piccole informazioni utili:
- come costruire una struttura ad albero delle directory in Linux
- come in sed passare un intervallo di indirizzi da una certa riga fino alla fine del file, cioè, fare una sostituzione in sed in tutte le righe tranne la prima
- Come in Linux invertire la condizione di ricerca con find
- come in Linux shell passare al ciclo più righe tramite un one-liner
- come in bash eseguire l'escape delle virgolette singole
- come nella riga di comando di Windows eliminare una directory con tutto il suo contenuto
- Come rinominare un file usando mv in bash senza riscriverlo da zero
Grazie per l'attenzione.
Fonte: habr.com
