Libelektra: testes geram agentes gpg ilimitados

Criado em 19 abr. 2018  ·  36Comentários  ·  Fonte: ElektraInitiative/libelektra

Etapas para reproduzir o problema

  • construir elektra, por exemplo, em um contêiner docker ou verificar o servidor v2
  • executar testes make run_nokdbtests
  • ps -ef
  • executar testes make run_nokdbtests
  • ps -ef
  • ????
  • me pergunto para onde foram todos os seus pid

resultado esperado

os testes devem parar os agentes gpg depois de terminados

Resultado atual

cada teste executado gera mais agentes gpg

Informação do sistema

  • Versão Elektra: mestre

Mais arquivos de log e saída

+ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 05:57 pts/0    00:00:00 bash
root     11296     1  0 07:01 pts/0    00:00:00 sh -c /usr/bin/python2 /root/cppcms-1.2.0/tests/http_timeouts_test.py 
root     11297 11296  0 07:01 pts/0    00:00:00 /usr/bin/python2 /root/cppcms-1.2.0/tests/http_timeouts_test.py write 
root     28509     1  0 07:55 ?        00:00:00 gpg-agent --homedir /tmp/elektra-test.NmmZ2I/.gnupg --use-standard-soc
root     28519     1  0 07:55 ?        00:00:00 gpg-agent --homedir /tmp/elektra-test.6mb1t2/.gnupg --use-standard-soc
root     28539     1  0 07:55 ?        00:00:00 gpg-agent --homedir /tmp/elektra-test.5XdxDR/.gnupg --use-standard-soc
root     30656     1  0 08:00 pts/0    00:00:00 ps -ef
+ make run_nokdbtests
+ ps -ef
+ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 05:57 pts/0    00:00:00 bash
root     11296     1  0 07:01 pts/0    00:00:00 sh -c /usr/bin/python2 /root/cppcms-1.2.0/tests/http_timeouts_test.py 
root     11297 11296  0 07:01 pts/0    00:00:00 /usr/bin/python2 /root/cppcms-1.2.0/tests/http_timeouts_test.py write 
root     28509     1  0 07:55 ?        00:00:00 gpg-agent --homedir /tmp/elektra-test.NmmZ2I/.gnupg --use-standard-soc
root     28519     1  0 07:55 ?        00:00:00 gpg-agent --homedir /tmp/elektra-test.6mb1t2/.gnupg --use-standard-soc
root     28539     1  0 07:55 ?        00:00:00 gpg-agent --homedir /tmp/elektra-test.5XdxDR/.gnupg --use-standard-soc
root     30778     1  0 08:02 ?        00:00:00 gpg-agent --homedir /tmp/elektra-test.GZbzqb/.gnupg --use-standard-soc
root     30788     1  0 08:02 ?        00:00:00 gpg-agent --homedir /tmp/elektra-test.PEjcKs/.gnupg --use-standard-soc
root     30808     1  0 08:02 ?        00:00:00 gpg-agent --homedir /tmp/elektra-test.d6yL2g/.gnupg --use-standard-soc
root     30923     1  0 08:02 pts/0    00:00:00 ps -ef
bug work in progress

Comentários muito úteis

tenha em mente que, se você compartilhar seu diretório pessoal, poderá não conseguir executar testes paralelamente.
E você ainda precisaria excluir o GNUPGHOME depois (você não quer um agente pgp persistente atendendo chamadas para o usuário conectado, certo?).

E o que aconteceria se o sistema de destino retransmitisse no GNUPGHOME, então você precisaria salvar o env existente e restaurá-lo manualmente após os testes.

Eu apreciaria se pudéssemos dar um passo para trás e ver como esses testes podem influenciar as máquinas dos usuários, não apenas o ambiente do servidor de teste.

Todos 36 comentários

Obrigado por relatar o problema!

@ petermax2 É possível que os comandos gpg durante os testes gerem agentes gpg?

Opa, pensei que o gpg sempre se conectaria ao mesmo agente. Eu investigarei.

@ markus2330 esta é também a razão pela qual existem tantos agentes gpg na v2 relatados com sua ID de usuário, já que o contêiner do docker é executado com 1000: 1000.

mas o problema não está restrito ao docker: debian-stretch-minimal tem> 250 deles também

alguns nós não são afetados porque estão configurados para gerar um agente gpg para jenkins que é usado pelos testes (provavelmente, tem que confirmar)

Obrigado a ambos por analisar isso!

alguns nós não são afetados porque estão configurados para gerar um agente gpg para jenkins que é usado pelos testes (provavelmente, tem que confirmar)

Se não conseguirmos encontrar uma maneira de matar os agentes que iniciamos, podemos simplesmente exigir que o ambiente já tenha um agente gpg (# 1888).

Talvez o agente gpg não precise ser iniciado e possamos suprimi-lo durante os testes. Mas preciso dar uma olhada à noite.

mh normalmente GPG_AGENT_INFO deve ser definido quando um é iniciado, no passado nós limpávamos as variáveis ​​de ambiente para que isso pudesse explicar os vários inícios no passado. Não faço ideia por que ainda está acontecendo agora ...

@ petermax2 os testes que requerem gpg-agent (encontrado renomeando gpg-agent para gpg-agent.bak;)):

  • testmod_fcrypt
  • testmod_crypto_openssl
  • testmod_crypto_gcrypt

testmod_crypto_botan deve ser executado exatamente como testmod_crypto_gcrypt e testmod_crypto_openssl . O teste de Botan está sendo executado no servidor?

@ petermax2 provavelmente sim. no ambiente onde testei não havia botan instalado. ele está rodando aqui e provavelmente também gerando agentes.

Não é tão simples assim. Tentei invocar gpg com o argumento --no-autostart durante os testes de unidade, mas o gpg ainda inicia o agente. --no-use-agent é engraçado. A página do manual diz:

--no-use-agent 
              This is dummy option. gpg2 always requires the agent.

Se não conseguirmos encontrar uma maneira de matar os agentes que iniciamos, podemos simplesmente exigir que o ambiente já tenha um agente gpg (# 1888).

Podemos dar uma chance a isso?

Ou tenha um cron-job como

pgrep gpg-agent | xargs -d "\n" kill

ou algo semelhante nos servidores / contêineres de construção?

Eu faria o teste verificar se um agente está disponível, se não iniciá-lo e reter seu pid. no teste de limpeza, pare o agente. tudo o mais é um hack.

Você está certo, a única questão é onde o início e a parada devem acontecer. Fazer isso em nossos agentes / dockers parece ser mais fácil do que em nossos testes de unidade escritos em C.

Aqui está o que aprendi até agora:

É possível suprimir o início automático de gpg-agent com a opção --no-autostart , se usado consistentemente com todas as chamadas gpg . No entanto, sem um gpg-agent gpg2 não pode realizar nenhuma operação que requeira a chave privada (ou seja, descriptografia, assinaturas).

Também é possível fazer um fork de gpg-agent --server mas gpg2 não pode se conectar ao agente. A variável de ambiente GPG_AGENT_INFO está obsoleta e não é mais considerada por gpg2 .

Vou tentar fazer um fork e execv gpg-agent --daemon . Eu só preciso descobrir o PID dos gpg-agent iniciados para que eu possa SIGTERM quando os testes forem concluídos.

Fazer isso em nossos agentes / dockers parece ser mais fácil do que em nossos testes de unidade escritos em C.

Muito mais fácil, eu acho :-)

Acho que sua decisão foi certa ao simplesmente usar o gpg padrão para se conectar aos agentes.

Como alternativa para iniciar / interromper o gpg-agent, também podemos desativar o "use-agent" em .gnupg / gpg.conf

não tenho problemas com a inicialização automática de um agente (e até mesmo em execução). Eu tenho um problema com os testes subsequentes iniciando um novo

Acho que sua decisão foi certa ao simplesmente usar o gpg padrão para se conectar aos agentes.

Em um ambiente de produção, é a melhor opção. Na minha máquina crypto e fcrypt sempre se conectam ao mesmo agente e a integração com meu Yubikey funciona muito bem.

em nossos ambientes de teste, devemos manter uma única instância do agente ativa e em execução antes de iniciar os testes. Acho que o problema é que limpamos o ambiente, como

Acho que o problema é que limpamos o ambiente

não devemos mais. mas o problema persiste

Se o gpg-agent tentar se comunicar por meio do ambiente, obviamente não funcionará, o próximo teste executado nunca teria o ambiente definido por um teste executado antes.

Eu gosto mais de seguir duas opções:

  1. iniciamos / interrompemos adequadamente um agente gpg dentro dos contêineres e documentamos em TESTING.md que o agente gpg precisa estar em execução (consulte # 1888).
  2. desabilitamos a inicialização dos agentes gpg (desabilitamos o "use-agent" em .gnupg / gpg.conf deve funcionar, mas não o testamos) e documentamos isso em TESTING.md (consulte # 1888).

Uma configuração, onde os daemons são iniciados sob demanda sem uma forma global de saber se o daemon já foi iniciado (e os env vars não são globais, mas específicos do processo), parece estar quebrada. Não devemos tentar consertar isso nos testes.

https://stackoverflow.com/questions/27459869/how-to-stop-gpg-2-1-spawning-many-agents-for-unit-testing

A razão pela qual você está gerando muitos agentes é o diretório inicial diferente usando a opção --homedir, caso contrário, um único teria sido usado. A partir do GnuPG 2.1, toda a comunicação com o agente é realizada por meio de um soquete no diretório inicial do GnuPG.

Não usamos a opção homedir. E https://dev.gnupg.org/T3218 descreve a solução alternativa do stackoverflow como "uma solução alternativa (muito estranha)".

Talvez simplesmente iniciar o gpg-agent seja a variante mais preparada para o futuro (de uma forma controlada em nosso ambiente). Parece que nas versões recentes a inicialização do gpg-agent não é mais opcional. (o que torna minha opção 2. acima de absurda)

Não usamos a opção homedir.

Sim, eu não encontrei de onde vem, mas corresponde ao problema (ver op), pois todos os agentes geraram com um diferente.

Foi uma boa dica, aprendi que a inicialização do gpg-agent não é mais opcional.

O que deixa muito claro que precisamos começar e parar. E não tente evitar o arranque.

Não usamos a opção homedir.

Sim, não encontrei de onde vem, mas corresponde ao problema (ver op)

Não usamos a opção --home-dir explicitamente, mas ps -ef revelas que gpg alguma forma a define de qualquer maneira.

https://wiki.archlinux.org/index.php/GnuPG

$ GNUPGHOME é usado pelo GnuPG para apontar para o diretório onde seus arquivos de configuração estão armazenados. Por padrão, $ GNUPGHOME não é definido e seu $ HOME é usado em seu lugar; portanto, você encontrará um diretório ~ / .gnupg logo após a instalação.
Para alterar a localização padrão, execute gpg desta forma $ gpg --homedir caminho / para / arquivo ou defina a variável de ambiente GNUPGHOME.
`` `
@ petermax2 você pode verificar se o HOME está disponível em sua suíte de teste?

também interessante https://www.gnupg.org/documentation/manuals/gnupg/Ephemeral-home-directories.html :

Crie um diretório temporário, crie (ou copie) uma configuração que atenda às suas necessidades, faça com que o gpg use este diretório usando a variável de ambiente GNUPGHOME ou a opção --homedir. O GPGME também suporta isso em uma base por contexto, modificando as informações do mecanismo de contextos. Agora execute qualquer operação que desejar, importe e exporte o material da chave conforme necessário. Depois de terminar, você pode excluir o diretório. Todos os serviços de back-end GnuPG que foram iniciados irão detectar isso e desligar

Testei isso no meu contêiner e limpou o processo automaticamente, conforme prometido.

@ petermax2 você pode verificar se o HOME está disponível em sua suíte de teste?

Sim, HOME está disponível:

HOME = /tmp/elektra-test.3vLR4L

OK, então algo no conjunto de testes está substituindo HOME em um diretório tmp (o que é bom). Se ainda estiver disponível durante a limpeza, deve ser removido apenas para interromper o agente. Essa seria uma solução ideal.

Se simplesmente definirmos GNUPGHOME apenas uma instância de gpg-agent é gerada. GNUPGHOME não é sobrescrito antes do início do teste.

Com GNUPGHOME definido, apenas um único gpg-agent está sendo executado após várias execuções de teste.

Acho que essa é a solução mais simples.

tenha em mente que, se você compartilhar seu diretório pessoal, poderá não conseguir executar testes paralelamente.
E você ainda precisaria excluir o GNUPGHOME depois (você não quer um agente pgp persistente atendendo chamadas para o usuário conectado, certo?).

E o que aconteceria se o sistema de destino retransmitisse no GNUPGHOME, então você precisaria salvar o env existente e restaurá-lo manualmente após os testes.

Eu apreciaria se pudéssemos dar um passo para trás e ver como esses testes podem influenciar as máquinas dos usuários, não apenas o ambiente do servidor de teste.

você pode não conseguir executar os testes paralelamente.

Eu executei o script:

#!/bin/bash
mkdir /tmp/x
export GNUPGHOME=/tmp/x
for run in {1..1000000}
do
    ctest -R crypto_openssl &
done

sem quaisquer problemas. GPG deve lidar com travamento, etc.

você não quer um agente pgp persistente atendendo chamadas para o usuário conectado, certo?

Este é o modo gpg-agent foi projetado: ele está em execução para sempre até que a sessão do usuário termine. Ele não grava seu PID em algum lugar, não há comandos para encerrá-lo. Ele reage apenas a SIGTERM .

Eu tentei fork the gpg-agent de dentro do teste de unidade com a opção --server , então teríamos um PID para kill depois. Mas então gpg-agent não abre os soquetes necessários em $GNUPGHOME e os testes de unidade reabrem outra instância do agente (que está sendo executado no modo --daemon ). Além disso, não há como fazer gpg-agent abrindo qualquer sockets no modo --server (eu verifiquei isso com o código-fonte de gpg-agent ).

gpg-agent é difícil de controlar e dificilmente documentado. Eu estava até lendo o código-fonte de gpg-agent . Nosso caso de uso não é coberto. A única opção é SIGTERM .

paralelismo

Eu estava pensando mais em você querer separar os agentes gpg que não deveriam influenciar uns aos outros. ou seja, você só deseja que o agente a tenha a chave do teste a e que o agente b tenha a chave do teste b. Se isso não for necessário, uma página inicial tmp codificada está ok.

matando agente gpg

Quando investiguei o problema pela primeira vez, encontrei um site (link acima) que afirmava que a maneira esperada de encerrar um agente temporário do gpg é excluir seu diretório inicial do gpg.

Portanto, se você definir GNUPGHOME como /tmp/elektra_tests/gpg e, durante a limpeza de teste, excluir este diretório tmp, não haverá problema.

Portanto, se você definir GNUPGHOME para / tmp / elektra_tests / gpg e durante a limpeza de teste excluir este diretório tmp, não haverá problema.

Funciona! Vou integrar esta correção nos casos de teste crypto e fcrypt . Obrigado pela dica!

Eu tenho um protótipo funcionando. PR está chegando amanhã.

Deve ser corrigido com # 2056. Abra novamente se o problema persistir.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

mpranj picture mpranj  ·  3Comentários

markus2330 picture markus2330  ·  4Comentários

dominicjaeger picture dominicjaeger  ·  3Comentários

mpranj picture mpranj  ·  3Comentários

mpranj picture mpranj  ·  3Comentários