Auditoria de confirmação do Git

16

Eu tenho um servidor git executando o ssh e cada usuário tem uma conta unix no sistema.

Como dois usuários têm acesso a um repositório, como posso ter certeza de qual usuário executou qual confirmação, já que o nome do usuário e o email da confirmação são enviados e controlados pelo cliente git.

Estou preocupado que um usuário possa tentar se passar por outro, mesmo se ele tiver os mesmos direitos de autorização.

yannisf
fonte
Estou confuso. Você diz na pergunta que cada usuário tem sua própria conta shell, mas em um comentário diz que todos compartilham uma única conta e usam chaves separadas para autenticação. Qual é, ou são os dois?
Scott pacote de
Poderia ser. A configuração atual é a descrita na pergunta (uma conta ssh por usuário), mas isso não se adapta bem e talvez eu queira usar um único usuário / muitas chaves no futuro. Estou apenas procurando a solução mais versátil que não me prenda a um ou outro método de autenticação.
yannisf
11
Vale ressaltar que "a pessoa que faz o commit" e "a pessoa que envia alguns commit a esse repositório" não são necessariamente as mesmas no caso geral. Eu poderia retirar seus commits do seu repositório e depois enviá-los (como eu) para um repositório de terceiros.
nickgrim

Respostas:

13

Se você está preocupado com isso, existem algumas maneiras de resolver o problema.

  1. Faça com que seus usuários assinem seus commits, há suporte para assinatura GPG.
  2. Não dê aos usuários o direito de se comprometerem com o repositório principal, faça com que eles se comprometam com seu próprio sub-repositório e, em seguida, peça a um usuário confiável que traga as alterações para o repositório principal. É por isso que, se você observar as mensagens de log de alguns projetos git (como o próprio git), verá que os campos são separados para "Autor" - a pessoa que criou a alteração. e "Committer" - a pessoa que comprometeu a alteração no repositório.
Abizern
fonte
1. Essa sugestão parece ser a mais adequada para meus propósitos. Ainda assim, existe um mecanismo para rejeitar confirmações não assinadas no lado do servidor? 2. No que diz respeito a esta solução, o usuário retirado do repositório subordinado precisará verificar novamente se o comunicador não usou nome de usuário / email forjado. Verdade?
yannisf
Porém, tenha cuidado, você pode assinar um commit com qualquer identidade de autor e autor que você escolher. Obviamente, você poderá ver quem fez a falsificação (ou não cuidou da chave privada).
perfil completo de CB Bailey
Daí a minha ressalva sobre ter apenas usuários confiáveis ​​comprometidos com o repositório principal.
Abizern
@ Abizern: Justo. Enquanto eu lia, seus (1) e (2) pareciam descrever opções alternativas.
CB Bailey
11
@yannisf Em relação à sua primeira pergunta, o gancho de atualização (executado no lado do servidor) pode verificar as assinaturas e rejeitar a atualização das respectivas referências. Dê uma olhada no .git/hooks/update.samplepara inspiração. Por favor @ notificar-me se você perguntar a uma pergunta sobre isso em SO, seria interessante para mim, também
Tobias KIENZLER
9

Vejo duas boas maneiras de obter esse tipo de informação. Uma é aumentar o registro do próprio sshd e a outra, fazer um monitoramento mais profundo do repositório git no disco. Como nenhum dos dois individualmente fornece as informações desejadas, você pode fazer as duas coisas e correlacionar os dados do log usando um mecanismo de análise de log externo ou sob demanda usando olhos humanos e registros de data e hora.

Modificações sshd

Por padrão, como você sem dúvida viu, é possível ver quando um usuário efetuou login e de onde, usando os logs de autenticação ssh. O que você quer fazer é alterar o nível em que você está desconectando do sshd. Então edite seu /etc/ssh/sshd_confige encontre a linha que se parece

#LogLevel INFO

e mude isso para

LogLevel VERBOSE

em seguida, reinicie o serviço sshd. Isso aumenta o nível de log do sshd em 1 etapa, o que fornece muito mais informações. Confira este trecho de log do meu acesso remoto depois de fazer essa alteração.

Nov  2 08:37:09 node1 sshd[4859]: Connection from 10.10.10.5 port 50445
Nov  2 08:37:10 node1 sshd[4859]: Found matching RSA key: f2:9e:a1:ca:0c:33:02:37:9b:de:e7:63:d5:f4:25:06
Nov  2 08:37:10 node1 sshd[4860]: Postponed publickey for scott from 10.10.10.5 port 50445 ssh2
Nov  2 08:37:10 node1 sshd[4859]: Found matching RSA key: f2:9e:a1:ca:0c:33:02:37:9b:de:e7:63:d5:f4:25:06
Nov  2 08:37:10 node1 sshd[4859]: Accepted publickey for scott from 10.10.10.5 port 50445 ssh2
Nov  2 08:37:10 node1 sshd[4859]: pam_unix(sshd:session): session opened for user scott by (uid=0)
Nov  2 08:37:10 node1 sshd[4859]: User child is on pid 4862
Nov  2 08:40:27 node1 sshd[4862]: Connection closed by 10.10.10.5
Nov  2 08:40:27 node1 sshd[4862]: Transferred: sent 30632, received 7024 bytes
Nov  2 08:40:27 node1 sshd[4862]: Closing connection to 10.10.10.5 port 50445
Nov  2 08:40:27 node1 sshd[4859]: pam_unix(sshd:session): session closed for user scott 

As coisas importantes a serem observadas aqui são duas

  1. Vemos a impressão digital da chave pública usada para me autenticar
  2. Vemos o carimbo de data e hora do meu logoff

O uso do sshd LogLevel (INFO) padrão não registra nenhum desses itens. Obter a impressão digital de uma chave é um passo extra. Você precisa processar o authorized_keysarquivo apropriado com o ssh-keygen como tal.

[root@node1 ssh]# ssh-keygen -l -f /home/scott/.ssh/authorized_keys
4096 f2:9e:a1:ca:0c:33:02:37:9b:de:e7:63:d5:f4:25:06 /home/scott/.ssh/authorized_keys (RSA)

Então agora você conhece as seguintes informações:

  1. Nome de usuário que efetuou logon
  2. Hora em que o usuário fez logon
  3. Qual chave pública foi usada para autenticação
  4. Hora em que o usuário fez logoff

Agora que temos uma maneira de atribuir a ação do usuário em um horário específico, supondo que os dois usuários não tenham efetuado login ao mesmo tempo, podemos começar a analisar as alterações feitas no repositório.

Monitoramento de Diretório com Auditd

Como o sysadmin1138 disse, esse poderia ser um excelente caso de uso para o subsistema auditd. Se você não estiver usando uma distribuição baseada em RedHat, provavelmente existe um analógico, mas será necessário encontrá-lo. A configuração do auditd é bastante intensa e possui um número redonkulous de opções de configuração. Para ter uma idéia de algumas das opções, consulte esta pergunta em nosso site irmão para Profissionais de Segurança da Informação .

No mínimo, eu recomendaria configurar o que é chamado de "watch" no diretório em disco que contém seu repositório git em questão. O que isso faz é instruir o módulo do kernel a relatar tentativas de realizar chamadas de acesso a arquivos, como open()ou creat(), em identificadores de arquivos apontando para os arquivos ou diretórios listados.

Aqui está um exemplo de configuração que faria isso, e somente isso. Portanto, tenha cuidado para ler e entender a sua existência /etc/audit/audit.rules, a fim de integrar as mudanças adequadamente.

# This file contains the auditctl rules that are loaded
# whenever the audit daemon is started via the initscripts.
# The rules are simply the parameters that would be passed
# to auditctl.

# First rule - delete all
-D

# Increase the buffers to survive stress events.
# Make this bigger for busy systems
-b 1024

-w /path/to/git/repos-p wa

# Disable adding any additional rules - note that adding *new* rules will require a reboot
-e 2
Scott Pack
fonte
muito obrigado pela sua resposta detalhada! É realmente completo da perspectiva de administradores de sistemas. O que eu estava procurando era uma solução que não precisaria de uma solução para uma auditoria de nível tão baixo e, idealmente, evitará comprometimentos forjados, em vez de resolver a perícia após o fato.
yannisf
2
Bem, você pediu em um site de Administração de Sistemas e eu sou um examinador forense .... :)
Scott pacote de
5

A única abordagem técnica que você pode adotar é confiar na identidade da conexão ssh. Você pode impor que cada usuário envie apenas as confirmações feitas por ele, validando o confirmador de cada nova confirmação enviada.

Para que isso seja confiável, você quase certamente não deseja conceder aos usuários acesso irrestrito ao shell na caixa em que o repositório reside; você gostaria de garantir o uso de algo comogit-shell caso contrário, as restrições são facilmente contornadas.

Os usuários ainda poderiam se passar por autores. Você também pode restringir isso, mas isso perderia fluxos de trabalho comuns, como seleção e rebaseamento de cereja e talvez até ramificação (dependendo da implementação do gancho), para que você não queira fazer isso.

Em algum momento, até certo ponto, você precisa confiar em seus desenvolvedores.

CB Bailey
fonte
3

Muitos daemons ssh fazem uma entrada /var/log/audit.logou algo semelhante quando uma conexão ssh é recebida. A referência cruzada desse log com o commit-log deve fornecer uma idéia de qual ssh-user foi usado para emitir um commit. Esta é uma etapa de auditoria, a ser usada após o fato para verificação.

A aplicação efetiva do usuário ssh correto ao usuário git apropriado é para uma das outras respostas aqui.

sysadmin1138
fonte
Ainda existe a configuração em que os usuários efetuam login com o mesmo usuário ssh, mas usam chaves diferentes (autorizadas). Isso torna a auditoria ainda mais difícil.
Yannisf
@yannisf: Você está certo, isso muda um pouco as coisas. Com alguma sorte, ajudei a suprir sua necessidade extra de lidar com o acesso a contas não atribuíveis.
Scott pacote de
0

Se todos os usuários tiverem contas shell com acesso de gravação ao repositório, você não poderá configurar um log de auditoria confiável: eles ainda podem modificar o repositório sem gravar no log e escrever o que quiserem no log.

Para poder confiar no log de auditoria, seria necessário impedir o acesso direto de gravação no repositório no nível do arquivo, usando algo como gitolite (que é executado em sua própria conta) para mediar o acesso ao repositório.

SamB
fonte