Organização do acesso multiusuário ao servidor GIT

Ao instalar e configurar um servidor Git, surge a questão de organizar o acesso de vários usuários a vários projetos. Realizei um estudo do problema e encontrei uma solução que satisfaz todos os meus requisitos: simples, seguro e confiável.

Meus desejos são os seguintes:

  • cada usuário se conecta com sua própria conta
  • vários usuários podem trabalhar em um projeto
  • o mesmo usuário pode trabalhar em vários projetos
  • cada usuário tem acesso apenas aos projetos em que trabalha
  • deve poder se conectar via linha de comando, e não apenas através de algum tipo de interface da web

Também seria ótimo:

  • conceder direitos somente leitura às pessoas controladoras
  • administrar convenientemente permissões de usuário no Git

Visão geral das opções para acessar o servidor GIT


Primeiro de tudo, você precisa saber o que escolher, para uma breve visão geral dos protocolos Git.

  • ssh - uma conta de usuário criada especialmente é usada para acessar o servidor.
    • É estranho que o Git não exclua das recomendações o uso de uma única conta para acessar todos os repositórios. Isso não atende aos meus requisitos.
    • Você pode usar várias contas, mas como restringir o acesso do usuário apenas a determinados diretórios?

      • Fechar o diretório inicial não é adequado, pois é difícil organizar o acesso de gravação para outros usuários
      • O uso de links simbólicos do diretório inicial também é difícil porque o Git não os interpreta como links
      • É possível restringir o acesso ao intérprete, mas não há garantia total de que isso sempre funcione

        • Você pode até conectar seu próprio interpretador de comandos para esses usuários, mas,

          • primeiro, isso já é algum tipo de decisão difícil,
          • e em 2, isso pode ser contornado.

    Mas talvez não seja um problema que o usuário consiga executar algum comando? .. Em geral, esse método não pode ser excluído se você descobrir como usá-lo. Voltaremos a esse método mais tarde, mas por enquanto consideremos brevemente as outras alternativas, talvez algo seja mais fácil lá.
  • O protocolo local git pode ser usado em conjunto com sshfs, vários usuários podem ser usados, mas, em essência, é o mesmo que no caso anterior
  • http - somente leitura
  • git é somente leitura
  • https - é difícil de instalar, você precisa de software adicional, algum tipo de painel de controle para organizar o acesso do usuário ... parece viável, mas de alguma forma é complicado.

Usando o protocolo ssh para organizar o acesso multiusuário ao servidor Git


De volta ao protocolo ssh.

Como o acesso ssh é usado para o git, você precisa proteger os dados do servidor. Um usuário que se conecta via ssh usa seu próprio logon no servidor Linux, para que possa se conectar através do cliente ssh e obter acesso à linha de comando do servidor.
Não há proteção total contra a obtenção desse acesso.

Mas o usuário não deve estar interessado nos arquivos do Linux. Informações significativas são armazenadas apenas no repositório git. Portanto, você não pode restringir o acesso através da linha de comando, mas o Linux pode impedir que o usuário assista a projetos, excluindo aqueles nos quais ele participa.
Obviamente, usando o sistema de permissões do Linux.

Como já mencionado, é possível usar apenas uma conta para acesso ssh. Essa configuração é insegura para vários usuários, embora esse método esteja incluído na lista de opções recomendadas do git.

Para implementar os requisitos fornecidos no início do artigo, a seguinte estrutura de diretórios é criada com a atribuição de direitos e proprietários:

1) diretórios do projeto

dir1 (proj1: proj1,0770)
dir2 (proj2: proj2,0770)
dir3 (proj3: proj3,0770)
...
onde
dir1, dir2, dir3 - diretórios do projeto: projeto 1, projeto 2, projeto 3.

proj1: proj1, proj2: proj2, proj3: proj3 - usuários Linux criados especialmente e nomeados como diretores dos respectivos diretórios de projetos.

os direitos para todos os diretórios são definidos em 0770 - acesso total para o proprietário e seu grupo e uma proibição completa para todos os outros.

2) contas de desenvolvedor

Desenvolvedor 1: dev1: dev1, proj1, proj2
Desenvolvedor 2: dev2: dev2, proj2, proj3

O ponto principal é que os desenvolvedores recebem um grupo adicional do usuário do sistema que possui o projeto correspondente. Isso é feito pelo administrador do servidor Linux como um único comando.

Neste exemplo, o “Desenvolvedor 1” está trabalhando nos projetos proj1 e proj2 e o “Desenvolvedor 2” está trabalhando nos projetos proj2 e proj3.

Se algum dos Desenvolvedores se conectar via ssh através da linha de comando, seus direitos não serão suficientes nem para exibir o conteúdo dos diretórios do projeto nos quais ele não está envolvido. Ele próprio não pode mudar isso de forma alguma.

Como a base desse princípio é a segurança básica dos direitos do Linux, esse esquema é confiável. Além disso, o esquema é muito fácil de administrar.

Vamos seguir praticando.

Criando repositórios Git em um servidor Linux


Nós verificamos.

[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 

cansado de digitar com as mãos ...

 [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 

Garantimos que é impossível acessar os repositórios de outras pessoas a partir da linha de comando e até mesmo ver seu conteúdo.

 [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ção no Git de vários desenvolvedores em um projeto


Uma pergunta permanece: se um desenvolvedor introduz um novo arquivo, o restante dos desenvolvedores não pode alterá-lo, porque ele é o proprietário (por exemplo, dev1) e não o usuário que é o proprietário do projeto (por exemplo, proj1). Como temos um repositório de servidores, primeiro você precisa saber como o diretório ".git" é organizado e se novos arquivos são criados.

Criando um repositório Git local e enviando para um servidor Git


Vamos para a máquina do 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://dev1@10.1.1.11/var/gitservertest/proj2" C:\gittest>git push origin master dev1:dev1@10.1.1.11'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, novos arquivos são formados no servidor e pertencem ao usuário que executou 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]$ 

Quando as alterações são carregadas no servidor Git, arquivos e diretórios adicionais são criados e, ao mesmo tempo, o usuário que faz o upload é o proprietário. Mas o grupo desses arquivos e diretórios também corresponde ao grupo principal desse usuário, ou seja, o grupo dev1 para o usuário dev1 e o grupo dev2 para o usuário dev2 (alterar o grupo principal do usuário de desenvolvimento não ajudará, desde então, como trabalhar em vários projetos?). Nesse caso, o usuário dev2 não poderá modificar os arquivos criados pelo usuário dev1, e isso está repleto de uma violação da funcionalidade.

Linux chown - alterando o proprietário de um arquivo por um usuário comum



O proprietário do arquivo não pode alterar sua propriedade. Mas ele pode alterar o grupo do arquivo que pertence a ele e esse arquivo pode estar disponível para alteração para outros usuários que estão no mesmo grupo. É disso que precisamos.

Usando o gancho git


O diretório de trabalho do gancho é o diretório raiz do projeto. hook é um executável executado sob o usuário que faz o push. sabendo disso, podemos cumprir nosso plano.

 [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 apenas

 vi hooks/post-update 

Voltar para a 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:dev1@10.1.1.11's password: d22c66e..b045e22 master -> master 

No servidor Git, após a confirmação, verificamos o script pós-atualização do gancho

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

- vazio, está tudo bem.

Conectando um segundo desenvolvedor ao Git


Vamos imitar o trabalho do segundo desenvolvedor.

No cliente

 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, ao mesmo tempo, no servidor ...

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

- vazio de novo, tudo funciona.

Removendo um projeto Git e baixando um projeto de um servidor Git


Bem, você pode novamente garantir que todas as alterações sejam preservadas.

 C:\gittest>rd /S /Q .       ,       . 

- Para remover um projeto Git, limpe o diretório completamente. Vamos tolerar o erro gerado, pois é impossível excluir o diretório atual para este comando, mas precisamos apenas desse comportamento.

 C:\gittest>dir   C:\gittest 21.06.2019 08:43 <DIR> . 21.06.2019 08:43 <DIR> .. C:\gittest>git clone ssh://dev2@10.1.1.11/var/gitservertest/proj2 Cloning into 'proj2'... dev2@10.1.1.11's password: C:\gittest>cd proj2 C:\gittest\proj2>dir   C:\gittest\proj2 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:\gittest\proj2>type test1.txt "test dev1 to proj2" "dev1 added some omre" "dev1 3rd line" "!!! dev2 added this" C:\gittest\proj2>type test2.txt "!!! dev2 wrote" 

Compartilhando acesso no Git


Agora, verifique se, mesmo através do Git, o segundo desenvolvedor não pode ter acesso ao projeto Proj1, no qual ele não trabalha.

 C:\gittest\proj2>git remote remove origin C:\gittest\proj2>git remote add origin "ssh://dev2@10.1.1.11/var/gitservertest/proj1" C:\gittest\proj2>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. 

Agora permita acesso

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

e depois disso tudo funciona.

 C:\gittest\proj2>git push origin master dev2@10.1.1.11's password: To ssh://10.1.1.11/var/gitservertest/proj1 * [new branch] master -> master 

Informações Adicionais


Além disso, se houver um problema com as permissões padrão ao criar arquivos e diretórios, no CentOS você poderá usar o comando

 setfacl -Rd -mo::5 -mg::7 /var/gitservertest 

Também neste artigo, você pode encontrar pequenas coisas úteis:

  • como construir uma árvore de diretórios no Linux
  • como sed para transferir um intervalo de endereços de uma determinada linha para o final do arquivo, ou seja, para fazer uma substituição no sed em todas as linhas, exceto na primeira linha
  • Como o Linux encontra para inverter um termo de pesquisa
  • como no shell linux para repetir várias linhas através de uma única linha
  • como escapar de aspas simples no bash
  • como excluir o diretório com todo o conteúdo na linha de comando do Windows
  • Como usar o bash mv para renomear um arquivo sem reescrevê-lo novamente

Obrigado pela atenção.

Source: https://habr.com/ru/post/pt457056/


All Articles