Durante l'installazione e la configurazione di un server Git, si pone la questione dell'organizzazione dell'accesso di più utenti a più progetti. Ho condotto una ricerca sull'argomento e ho trovato una soluzione che soddisfa tutte le mie esigenze: semplice, sicura, affidabile.
Le mie richieste sono le seguenti:
- ogni utente si connette con il proprio account personale
- 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 la connessione tramite linea di comando, e non solo tramite un'interfaccia web
Sarebbe anche bello:
- fornire diritti di sola lettura per le persone di controllo
- gestire facilmente i diritti di accesso degli utenti in Git
Panoramica delle possibili opzioni di accesso su un server GIT
Prima di tutto, è necessario sapere da cosa scegliere, quindi una breve panoramica dei protocolli Git.
- ssh — per accedere al server si utilizza un account utente specificamente creato.
- È strano che Git non escluda dai suoi suggerimenti l'uso di un singolo account per accedere a tutti i repository. Questo non soddisfa affatto le mie esigenze.
- è possibile utilizzare più account, ma come limitare l'accesso dell'utente solo a determinate directory?
- Limitare alla home directory non funziona, perché è difficile organizzare l'accesso in scrittura per altri utenti
- L'uso di collegamenti simbolici dalla home directory è anch'esso complesso, poiché Git non li interpreta come collegamenti
- Limitare l'accesso all'interprete, bene, si può fare, ma non c'è garanzia che funzioni sempre
- Si potrebbe persino collegare a tali utenti il proprio interprete di comandi, ma,
- in primo luogo, sarebbe già una soluzione complicata,
- e in secondo luogo, potrebbe essere aggirata.
- Si potrebbe persino collegare a tali utenti il proprio interprete di comandi, ma,
Ma forse non è un problema che l'utente possa eseguire qualsiasi comando?... In ogni caso, non possiamo escludere questo metodo, se troviamo un modo preciso per usarlo. Torniamo a questo metodo più tardi, ma per ora diamo un'occhiata alle altre alternative, magari ci sarà qualcosa di più semplice.
- Il protocollo git locale può essere utilizzato in combinazione con sshfs, è possibile utilizzare più utenti, ma in sostanza è lo stesso caso precedente.
- http — solo in lettura
- git — solo in lettura
- https — difficile da impostare, richiede software aggiuntivo, qualcosa del genere. dashboard Per organizzare l'accesso degli utenti... sembra realizzabile, ma è tutto piuttosto complesso.
Utilizzo del 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 utilizza il proprio login su server Linux, quindi può collegarsi tramite un client ssh e accedere alla riga di comando del server.
Non esiste una protezione totale contro tale accesso.
Ma per l'utente non devono essere interessanti i file Linux. Le informazioni significative sono memorizzate solo nel repository git. Pertanto, non è necessario limitare l'accesso tramite la riga di comando, ma attraverso i mezzi di Linux, vietare all'utente di visualizzare i progetti, escludendo quelli in cui partecipa.
È ovvio utilizzare un sistema di diritti di accesso Linux.
Come già detto, è possibile utilizzare solo un account per l'accesso ssh. Questa configurazione non è sicura per più utenti, anche se questo metodo è incluso nell'elenco delle opzioni git raccomandate.
Per soddisfare i requisiti elencati all'inizio dell'articolo, si crea la seguente struttura directory con assegnazione di diritti e proprietari:
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, che vengono nominati come proprietari delle directory dei rispettivi progetti.
I diritti su tutte le directory sono impostati a 0770 — accesso completo per il proprietario e il suo gruppo e completo divieto per tutti gli altri.
2) account degli sviluppatori
Sviluppatore 1: dev1:dev1,proj1,proj2
Sviluppatore 2: dev2:dev2,proj2,proj3
Il punto cruciale è che agli sviluppatori viene assegnato un gruppo aggiuntivo dell'utente di sistema proprietario del rispettivo progetto. Questo viene fatto dall'amministratore del server Linux con un solo comando.
In questo esempio, "Sviluppatore 1" sta lavorando ai progetti proj1 e proj2, mentre "Sviluppatore 2" sta lavorando ai progetti proj2 e proj3.
Se uno qualsiasi degli Sviluppatori si connette tramite ssh da riga di comando, i suoi diritti non saranno sufficienti nemmeno per visualizzare il contenuto delle directory dei progetti a cui non partecipa. Non può modificare questa situazione da solo.
Poiché la base di questo principio è la sicurezza fondamentale dei diritti Linux, questo schema è affidabile. Inoltre, lo schema è molto facile da amministrare.
Passiamo alla pratica.
Creazione di repository Git su un server Linux
Controlliamo.
[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
è noioso inserire 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 di altri e nemmeno visualizzarne il contenuto.
[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 deniedCollaborazione in Git di più sviluppatori su un progetto unico
Rimane una questione: se uno sviluppatore aggiunge un nuovo file, gli altri sviluppatori non possono modificarlo, in quanto lo stesso è 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 [Versione 6.1.7601]
(c) Microsoft Corporation, 2009. Tutti i diritti riservati.
C:gittest>git init .
Repository Git vuoto inizializzato 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 da confermare:
(usa "git rm --cached ..." per rimuovere dalla staging)
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 inserzione(+)
modalità creazione 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 bytes | 243.00 KiB/s, fatto.
Totale 3 (delta 0), riutilizzati 0 (delta 0)
A ssh://10.1.1.11/var/gitservertest/proj2
* [nuova branch] master -> master
C:gittest>Nel frattempo, sul server vengono creati nuovi file, e questi 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 directory, 18 file
[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, vengono creati file e directory aggiuntivi, e il proprietario è effettivamente l'utente che carica. Tuttavia, anche il gruppo di questi file e directory corrisponde al gruppo principale di quell'utente, cioè, il gruppo dev1 per l'utente dev1 e il gruppo dev2 per l'utente dev2 (cambiare il gruppo principale dell'utente sviluppatore non aiuterebbe, poiché come lavorare su più progetti?). In tal caso, l'utente dev2 non potrà modificare i file creati dall'utente dev1, e questo comporterebbe la violazione della funzionalità.
Linux chown — cambia il proprietario di un file da un utente normale
Il proprietario di un file non può modificare la sua appartenenza. Ma può cambiare il gruppo del file di cui è proprietario, e in tal modo questo file può essere reso accessibile alla modifica da parte di altri utenti che appartengono allo stesso gruppo. Questo è ciò di cui abbiamo bisogno.
Utilizzo del Git hook
La directory di lavoro per hook è la directory radice del progetto. hook è un file eseguibile che viene eseguito sotto l'utente che esegue il push. Sapendo questo, possiamo realizzare quanto progettato.
[dev1@server proj2]$ mv hooks/post-update{.sample,}
[dev1@server proj2]$ sed -i '2,$ s/^/#/' hooks/post-update
[dev1@server proj2]$ cat <> hooks/post-updateo semplicemente
vi hooks/post-updateTorniamo sulla macchina 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 -> masterSul server Git, controlliamo dopo il commit il funzionamento dello script hook post-update
[dev1@server proj2]$ find . ! -group proj2
— vuoto, tutto funziona bene.
Collegamento del secondo sviluppatore in Git
Simuliamo il lavoro di un 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 nel frattempo, sul server…
[dev1@server proj2]$ find . ! -group proj2
— di nuovo vuoto, tutto funziona.
Eliminazione del progetto Git e caricamento del progetto dal server Git
Possiamo assicurarci ancora una volta che tutte le modifiche siano state salvate.
C:gittest>rd /S /Q .
Il processo non può accedere al file perché questo file è usato da un altro processo.— per eliminare il progetto Git, basta pulire completamente la directory. Accettiamo l'errore mostrato, poiché non è possibile eliminare la directory attuale con questo comando, ma è proprio questo comportamento che ci serve.
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 added some more"
"dev1 3rd line"
"!!! dev2 added this"
C:gittestproj2>type test2.txt
"!!! dev2 wrote"Separazione degli accessi in Git
Ora assicuriamoci 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 sembra un repository git
fatal: Non è stato possibile leggere dal repository remoto.
Assicurati di avere i diritti di accesso corretti
e che il repository esista.Ora consentiamo l'accesso
[root@server ~]# usermod -aG proj1 dev2e dopo 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 di default nella creazione di file e directory, in CentOS puoi usare il comando
setfacl -Rd -m o::5 -m g::7 /var/gitservertestInoltre, nell'articolo puoi imbattersi in piccole cose utili:
- come costruire una struttura ad albero delle directory in Linux
- come in sed passare un intervallo di indirizzi da una riga specifica fino alla fine del file, ovvero, eseguire una sostituzione in sed in tutte le righe tranne la prima
- Come in Linux invertire la condizione di ricerca con find
- come nel shell di Linux passare più righe a un ciclo tramite una riga singola
- come in bash eseguire l'escape di apici singoli
- come nella riga di comando di windows eliminare una directory con tutto il suo contenuto
- Come rinominare un file usando bash mv, senza scriverlo nuovamente
Grazie per l'attenzione.
Fonte: habr.com
