Libelektra: las pruebas generan agentes gpg ilimitados

Creado en 19 abr. 2018  ·  36Comentarios  ·  Fuente: ElektraInitiative/libelektra

Pasos para reproducir el problema

  • compile elektra, por ejemplo, en un contenedor docker, o verifique el servidor v2
  • ejecutar pruebas make run_nokdbtests
  • ps -ef
  • ejecutar pruebas make run_nokdbtests
  • ps -ef
  • ????
  • me pregunto a dónde fueron todos tus pid

Resultado Esperado

las pruebas deben detener los agentes gpg después de que hayan terminado

Resultado actual

cada ejecución de prueba genera más agentes gpg

Información del sistema

  • Versión de Elektra: maestro

Más archivos de registro y resultados

+ 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

Comentario más útil

Tenga en cuenta que si comparte su directorio de inicio, es posible que no pueda ejecutar pruebas en paralelo.
Y aún necesitaría eliminar GNUPGHOME después (no quiere que un agente pgp persistente responda a las llamadas del usuario que ha iniciado sesión, ¿verdad?).

Y qué sucedería si el sistema de destino se retransmite en GNUPGHOME, por lo que necesitaría guardar el entorno existente y restaurarlo manualmente después de las pruebas.

Agradecería que pudiéramos dar un paso atrás y ver cómo esas pruebas pueden influir en las máquinas de los usuarios, no solo en el entorno del servidor de pruebas.

Todos 36 comentarios

¡Gracias por informar del problema!

@ petermax2 ¿Es posible que los comandos gpg durante las pruebas generen agentes gpg?

Vaya, pensé que gpg siempre se conectaría al mismo agente. Yo investigaré.

@ markus2330, esta es también la razón por la que hay tantos agentes gpg en v2 informados con su ID de usuario, ya que el contenedor Docker se ejecuta con 1000: 1000.

pero el problema no se limita a docker: debian-stretch-minimal tiene> 250 de ellos también

algunos nodos no se ven afectados porque están configurados para generar un agente gpg para jenkins que se usa en las pruebas (probablemente, tenga que confirmar)

¡Gracias a ambos por investigar esto!

algunos nodos no se ven afectados porque están configurados para generar un agente gpg para jenkins que se usa en las pruebas (probablemente, tenga que confirmar)

Si no podemos encontrar una manera de matar a los agentes que iniciamos, simplemente podemos requerir que el entorno ya tenga un agente gpg (# 1888).

Tal vez no se requiera que el agente gpg se inicie en absoluto y podemos suprimirlo durante las pruebas. Pero tengo que echarle un vistazo por la noche.

mh generalmente GPG_AGENT_INFO debe establecerse cuando se inicia uno, en el pasado limpiamos las variables de entorno para que pudieran haber explicado los múltiples inicios en el pasado. Sin embargo, no tengo idea de por qué todavía está sucediendo en este momento ...

@ petermax2 las pruebas que requieren gpg-agent (que se encuentran al cambiar el nombre de gpg-agent a gpg-agent.bak;)):

  • testmod_fcrypt
  • testmod_crypto_openssl
  • testmod_crypto_gcrypt

testmod_crypto_botan debería ejecutarse exactamente como testmod_crypto_gcrypt y testmod_crypto_openssl . ¿Se está ejecutando la prueba de Botan en el servidor?

@ petermax2 probablemente sí. en el entorno donde probé no había ningún botan instalado. sin embargo, se está ejecutando aquí y probablemente también generando agentes.

No es tan simple. Intenté invocar gpg con el argumento --no-autostart durante las pruebas unitarias, sin embargo, gpg aún inicia el agente. --no-use-agent es divertido. La página de manual dice:

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

Si no podemos encontrar una manera de matar a los agentes que iniciamos, simplemente podemos requerir que el entorno ya tenga un agente gpg (# 1888).

¿Podríamos darle una oportunidad a esto?

O tener un trabajo cron como

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

o algo similar en los servidores / contenedores de compilación?

Haría que la prueba verificara si un agente está disponible, si no, iniciarlo y retener su pid. en la limpieza de prueba, detenga el agente. todo lo demás es un truco.

Tienes razón, la única pregunta es dónde debe ocurrir el inicio y la parada. Hacer esto dentro de nuestros agentes / estibadores parece ser más fácil que en nuestras pruebas unitarias escritas en C.

Esto es lo que aprendí hasta ahora:

Es posible suprimir el inicio automático de gpg-agent con la opción --no-autostart , si se utiliza de forma coherente con todas las llamadas gpg . Sin embargo, sin gpg-agent gpg2 no se pueden realizar operaciones que requieran la clave privada (es decir, descifrado, firmas).

También es posible bifurcar gpg-agent --server pero luego gpg2 no puede conectarse con el agente. La variable de entorno GPG_AGENT_INFO está obsoleta y gpg2 ya no la considera.

Intentaré fork y execv gpg-agent --daemon . Solo necesito una forma de averiguar el PID del gpg-agent iniciado para poder SIGTERM cuando terminen las pruebas.

Hacer esto dentro de nuestros agentes / estibadores parece ser más fácil que en nuestras pruebas unitarias escritas en C.

Mucho más fácil, supongo :-)

Creo que su decisión fue correcta al usar simplemente la forma predeterminada de gpg para conectarse con los agentes.

Como alternativa a iniciar / detener gpg-agent, también podemos deshabilitar el "use-agent" en .gnupg / gpg.conf

No tengo ningún problema con el inicio automático de un agente (e incluso lo tengo en ejecución). Tengo un problema con las pruebas posteriores al iniciar una nueva

Creo que su decisión fue correcta al usar simplemente la forma predeterminada de gpg para conectarse con los agentes.

En un entorno de producción es la mejor opción. En mi máquina crypto y fcrypt siempre se conectan al mismo agente y la integración con mi Yubikey funciona muy bien.

en nuestros entornos de prueba, debemos mantener una instancia única del agente en funcionamiento antes de comenzar las pruebas. Creo que el problema es que limpiamos el entorno, como mencionó antes

Creo que el problema es que limpiamos el ambiente.

ya no deberíamos. pero el problema persiste

Si gpg-agent intenta comunicarse a través del entorno, obviamente no puede funcionar, la siguiente ejecución de prueba nunca obtendría el entorno configurado por una ejecución de prueba anterior.

Me gusta más seguir dos opciones:

  1. iniciamos / detenemos correctamente un agente gpg dentro de los contenedores y documentamos en TESTING.md que el agente gpg debe estar ejecutándose (ver # 1888).
  2. deshabilitamos el inicio de los agentes gpg (deshabilitar el "use-agent" en .gnupg / gpg.conf debería funcionar, aunque no lo probamos) y documentamos esto en TESTING.md (ver # 1888).

Una configuración, donde los demonios se inician bajo demanda sin una forma global de saber si el demonio ya se ha iniciado (y las variables de entorno no son globales sino específicas del proceso), parece estar rota. No deberíamos intentar arreglar esto dentro de las pruebas.

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

La razón por la que está generando muchos agentes es el directorio de inicio diferente que usa la opción --homedir; de lo contrario, se habría usado uno solo. Desde GnuPG 2.1, toda la comunicación con el agente se realiza a través de un socket en el directorio principal de GnuPG.

No usamos la opción homedir. Y https://dev.gnupg.org/T3218 describe la solución de stackoverflow como "una solución (muy incómoda)".

Quizás simplemente iniciar gpg-agent es la variante más preparada para el futuro (de forma controlada dentro de nuestro entorno). Parece que en versiones recientes el inicio de gpg-agent ya no es opcional. (lo que hace que mi opción 2. anterior no tenga sentido)

No usamos la opción homedir.

Sí, no he encontrado de dónde viene, pero coincide con el problema (ver operación) ya que todos los agentes generaron uno diferente.

Fue una buena pista, aprendí que el inicio de gpg-agent ya no es opcional.

Lo que deja muy claro que tenemos que iniciarlo y detenerlo. Y no intente evitar el arranque.

No usamos la opción homedir.

Sí, no he encontrado de dónde viene, pero coincide con el problema (ver op)

No usamos la opción --home-dir explícitamente, pero ps -ef revela que gpg alguna manera lo establece de todos modos.

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

$ GNUPGHOME es utilizado por GnuPG para apuntar al directorio donde se almacenan sus archivos de configuración. Por defecto $ GNUPGHOME no está configurado y su $ HOME se usa en su lugar; por lo tanto, encontrará un directorio ~ / .gnupg inmediatamente después de la instalación.
Para cambiar la ubicación predeterminada, ejecute gpg de esta manera $ gpg --homedir ruta / a / archivo o configure la variable de entorno GNUPGHOME.
''
@ petermax2 ¿ puede comprobar si HOME está disponible en su suite de pruebas?

también interesante https://www.gnupg.org/documentation/manuals/gnupg/Ephemeral-home-directories.html :

Cree un directorio temporal, cree (o copie) una configuración que satisfaga sus necesidades, haga que gpg use este directorio ya sea usando la variable de entorno GNUPGHOME o la opción --homedir. GPGME también admite esto por contexto, modificando la información del motor de los contextos. Ahora ejecute la operación que desee, importe y exporte material clave según sea necesario. Una vez terminado, puede eliminar el directorio. Todos los servicios de backend de GnuPG que se iniciaron detectarán esto y se cerrarán

Probé esto en mi contenedor y limpió el proceso automáticamente según lo prometido.

@ petermax2 ¿ puede comprobar si HOME está disponible en su suite de pruebas?

Sí, HOME está disponible:

HOME = /tmp/elektra-test.3vLR4L

De acuerdo, algo en el conjunto de pruebas está anulando HOME en un directorio tmp (lo cual es bueno). Si todavía está disponible durante la limpieza, simplemente debe eliminarse para detener el agente. Esa sería una solución ideal.

Si simplemente configuramos GNUPGHOME solo se genera una instancia de gpg-agent . GNUPGHOME no se sobrescribe antes de que comience la prueba.

Con GNUPGHOME establecido, solo se ejecuta un solo gpg-agent después de varias ejecuciones de prueba.

Creo que esta es la solución más sencilla.

Tenga en cuenta que si comparte su directorio de inicio, es posible que no pueda ejecutar pruebas en paralelo.
Y aún necesitaría eliminar GNUPGHOME después (no quiere que un agente pgp persistente responda a las llamadas del usuario que ha iniciado sesión, ¿verdad?).

Y qué sucedería si el sistema de destino se retransmite en GNUPGHOME, por lo que necesitaría guardar el entorno existente y restaurarlo manualmente después de las pruebas.

Agradecería que pudiéramos dar un paso atrás y ver cómo esas pruebas pueden influir en las máquinas de los usuarios, no solo en el entorno del servidor de pruebas.

es posible que no pueda ejecutar pruebas en paralelo.

Ejecuté el guión:

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

sin ningún problema. GPG debe manejar el bloqueo, etc.

no desea que un agente pgp persistente responda las llamadas del usuario que ha iniciado sesión, ¿verdad?

Esta es la forma en que se diseñó gpg-agent : se ejecuta para siempre hasta que finaliza la sesión del usuario. No escribe su PID en algún lugar, no hay comandos para salir. Solo reacciona a SIGTERM .

Intenté fork el gpg-agent desde dentro de la prueba unitaria con la opción --server , por lo que tendríamos un PID para kill después. Pero luego gpg-agent no abre los sockets requeridos en $GNUPGHOME y las pruebas unitarias vuelven a abrir otra instancia del agente (que se ejecuta en el modo --daemon ). Además, no hay forma de hacer que gpg-agent abra ningún conector cuando esté en el modo --server (verifiqué esto con el código fuente de gpg-agent ).

gpg-agent es difícil de controlar y apenas está documentado. Incluso estaba leyendo el código fuente de gpg-agent . Nuestro caso de uso no está cubierto. La única opción es SIGTERM .

paralelismo

Estaba más pensando en que quieres separar a los agentes de gpg que no deberían influirse entre sí. es decir, solo desea que el agente a tenga la clave de la prueba ay que el agente b tenga la clave para la prueba b. Si eso no es necesario, una casa tmp codificada está bien.

matando al agente gpg

Cuando investigué por primera vez el problema, encontré un sitio web (vinculado arriba) que indicaba que la forma esperada de cerrar un temp gpg-agent es eliminar su directorio de inicio gpg.

Entonces, si configura GNUPGHOME en /tmp/elektra_tests/gpg y durante la limpieza de prueba elimine este directorio tmp, debería estar bien.

Entonces, si configura GNUPGHOME en / tmp / elektra_tests / gpg y durante la limpieza de la prueba, elimine este directorio tmp, debería estar bien.

¡Funciona! Integraré esta corrección en los casos de prueba crypto y fcrypt . ¡Gracias por el consejo!

Tengo un prototipo funcional. PR llegará mañana.

Debería arreglarse con # 2056. Vuelva a abrir si el problema persiste.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

markus2330 picture markus2330  ·  4Comentarios

dominicjaeger picture dominicjaeger  ·  3Comentarios

sanssecours picture sanssecours  ·  3Comentarios

markus2330 picture markus2330  ·  3Comentarios

e1528532 picture e1528532  ·  4Comentarios