Organización do acceso multiusuario ao servidor GIT

Ao instalar e configurar un servidor Git, xorde a cuestión de organizar o acceso de varios usuarios a varios proxectos. Investiguei sobre o problema e atopei unha solución que cumpre todos os meus requisitos: sinxela, segura e fiable.

Os meus desexos son:

  • cada usuario conéctase coa súa propia conta
  • Varios usuarios poden traballar no mesmo proxecto
  • un mesmo usuario pode traballar en varios proxectos
  • cada usuario só ten acceso a aqueles proxectos nos que traballa
  • debería ser posible conectarse a través da liña de comandos, e non só a través dalgún tipo de interface web

Tamén sería xenial:

  • conceder dereitos de só lectura ás persoas controladoras
  • Administre convenientemente os permisos dos usuarios en Git

Visión xeral das opcións posibles para acceder ao servidor GIT

Primeiro de todo, cómpre saber de que escoller, así que unha breve visión xeral dos protocolos de Git.

  • ssh: úsase unha conta de usuario creada especialmente para acceder ao servidor.
    • é estraño que Git non recomende usar unha conta para acceder a todos os repositorios. Isto non cumpre os meus requisitos en absoluto.
    • Podes usar varias contas, pero como podes limitar o acceso dun usuario só a certos directorios?
      • Pechar o directorio de inicio non é adecuado, porque é difícil organizar alí o acceso de escritura para outros usuarios
      • Usar ligazóns simbólicas do directorio de inicio tamén é complicado porque Git non as interpreta como ligazóns.
      • Restrinxa o acceso ao intérprete, ben, podes, pero non hai garantía total de que isto sempre funcione
        • Xeralmente pode conectar o seu propio intérprete de comandos para estes usuarios, pero,
          • en primeiro lugar, esta xa é unha especie de decisión difícil,
          • e 2, pódese ignorar.

    Pero quizais non sexa un problema que o usuario poida executar calquera comando?... En xeral, este método non se pode descartar se se descubre exactamente como usalo. Volveremos a este método máis adiante, pero polo momento consideraremos brevemente as alternativas restantes, quizais haxa algo máis sinxelo.

  • O protocolo local git pódese usar en combinación con sshfs, pódense usar varios usuarios, pero é esencialmente o mesmo que o caso anterior
  • http - só lectura
  • git é só de lectura
  • https é difícil de instalar, necesitas software adicional, algún tipo de panel de control para organizar o acceso dos usuarios... parece factible, pero de algunha maneira todo é complicado.

Usando o protocolo ssh para organizar o acceso multiusuario ao servidor Git

Volvamos ao protocolo ssh.

Dado que o acceso ssh se usa para git, os datos do servidor deben estar seguros. O usuario que se conecta a través de ssh usa o seu propio inicio de sesión no servidor Linux, polo que pode conectarse a través do cliente ssh e acceder á liña de comandos do servidor.
Non existe unha protección completa contra este acceso.

Pero o usuario non debería estar interesado nos ficheiros de Linux. A información significativa só se almacena no repositorio git. Polo tanto, non se pode restrinxir o acceso a través da liña de comandos, pero mediante Linux, prohibirlle ao usuario a visualización de proxectos, excluíndo aqueles nos que participa.
É obvio usar o sistema de permisos de Linux.

Como xa se mencionou, é posible usar só unha conta para o acceso ssh. Esta configuración non é segura para varios usuarios, aínda que está incluída na lista de opcións recomendadas de git.

Para implementar os requisitos indicados ao comezo do artigo, créase a seguinte estrutura de directorio coa cesión de dereitos e propietarios:

1) directorios de proxectos

dir1(prox1:prox1,0770)
dir2(prox2:prox2,0770)
dir3(prox3:prox3,0770)
...
onde
dir1, dir2, dir3 - directorios do proxecto: proxecto 1, proxecto 2, proxecto 3.

proj1:proj1, proj2:proj2, proj3:proj3 son usuarios de Linux especialmente creados que son asignados como propietarios dos respectivos directorios do proxecto.

os dereitos de todos os directorios están configurados en 0770: acceso total para o propietario e o seu grupo, e prohibición total para todos os demais.

2) contas de desenvolvedores

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

O punto clave é que os desenvolvedores teñen asignado un grupo adicional do usuario do sistema que posúe o proxecto correspondente. Isto faise polo administrador do servidor Linux cun só comando.

Neste exemplo, o programador 1 está a traballar nos proxectos proj1 e proj2, e o programador 2 traballa nos proxectos proj2 e proj3.

Se algún dos desenvolvedores se conecta a través de ssh a través da liña de comandos, os seus dereitos non serán suficientes nin para ver o contido dos directorios dos proxectos nos que non participa. Non pode cambialo el mesmo.

Dado que a base deste principio é a seguridade básica dos dereitos de Linux, este esquema é fiable. Ademais, o esquema é moi sinxelo de administrar.

Imos practicar.

Creando repositorios Git nun servidor Linux

Comprobamos.

[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

canso de escribir...

[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

Estamos convencidos de que é imposible acceder aos repositorios doutras persoas desde a liña de comandos e mesmo ver o seu contido.

[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

Colaboración en Git de varios desenvolvedores nun mesmo proxecto

Queda unha pregunta: se un programador introduce un ficheiro novo, outros desenvolvedores non poden cambialo, porque el mesmo é o propietario do mesmo (por exemplo, dev1) e non o usuario propietario do proxecto (por exemplo, proj1). Xa que temos un repositorio de servidor, en primeiro lugar, necesitamos saber como está disposto o directorio ".git" e se se crean novos ficheiros.

Crea un repositorio Git local e empúxao a un servidor Git

Pasemos á máquina cliente.

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>

Ao mesmo tempo, xéranse novos ficheiros no servidor e pertencen ao usuario que realizou o 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]$

Cando se cargan os cambios no servidor Git, créanse ficheiros e directorios adicionais que son propiedade do cargador. Pero entón o grupo destes ficheiros e directorios tamén corresponde ao grupo principal deste usuario, é dicir, o grupo dev1 para o usuario dev1 e o grupo dev2 para o usuario dev2 (cambiar o grupo principal do usuario desenvolvedor non axudará, porque entón como traballar en varios proxectos?). Neste caso, o usuario dev2 non poderá modificar os ficheiros creados polo usuario dev1, e isto está cheo dunha violación da funcionalidade.

Linux chown: un usuario normal cambia o propietario dun ficheiro

O propietario dun ficheiro non pode cambiar a súa propiedade. Pero pode cambiar o grupo dun ficheiro que lle pertence, e despois este ficheiro pode ser cambiado por outros usuarios que estean no mesmo grupo. Iso é o que necesitamos.

Usando o Git Hook

O directorio de traballo para hook é o directorio raíz do proxecto. hook é un executable que se executa baixo o usuario que está a facer o push. sabendo isto, podemos levar a cabo os nosos plans.

[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

ou só

vi hooks/post-update

Volvamos á máquina 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:[email protected]'s password:
   d22c66e..b045e22  master -> master

No servidor Git, comprobe o traballo do script posterior á actualización do gancho despois da confirmación

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

- baleiro, todo está ben.

Conectando un segundo programador a Git

Imos simular o traballo do segundo desenvolvedor.

Sobre o cliente

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

E ao mesmo tempo, no servidor...

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

- de novo baleiro, todo funciona.

Eliminar un proxecto Git e cargar un proxecto desde un servidor Git

Ben, unha vez máis podes asegurarte de que se gardaron todos os cambios.

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

- para eliminar un proxecto Git, basta con limpar o directorio por completo. Imos soportar o erro dado, xa que é imposible eliminar o directorio actual con este comando, pero este é exactamente o comportamento que necesitamos.

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"

Compartir acceso en Git

Agora asegurémonos de que o segundo desenvolvedor non poida acceder ao proxecto Proj1 a través de Git, no que non está a traballar.

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.

Agora permite o acceso

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

e despois todo funciona.

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

Para máis información,

Ademais, se hai algún problema cos permisos predeterminados ao crear ficheiros e directorios, en CentOS podes usar o comando

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

Tamén no artigo podes tropezar con pequenas cousas útiles:

  • como construír unha árbore de directorios en linux
  • como pasar un rango de enderezos desde unha determinada liña ata o final do ficheiro en sed, é dicir, facer unha substitución en sed en todas as liñas excepto na primeira liña
  • Como inverter a condición de busca en Linux find
  • como pasar varias liñas a través dunha única liña nun shell de Linux
  • como escapar de comiñas simples en bash
  • como eliminar un directorio con todo o contido na liña de comandos de Windows
  • Como cambiar o nome dun ficheiro usando bash mv sen reescribilo

Grazas pola súa atención.

Fonte: www.habr.com

Engadir un comentario