Libelektra: тесты порождают неограниченное количество gpg-агентов

Созданный на 19 апр. 2018  ·  36Комментарии  ·  Источник: ElektraInitiative/libelektra

Шаги по воспроизведению проблемы

  • построить elektra, например, в контейнере докеров, или проверить сервер v2
  • запустить тесты make run_nokdbtests
  • ps -ef
  • запустить тесты make run_nokdbtests
  • ps -ef
  • ????
  • интересно, куда делись все твои пид

ожидаемый результат

тесты должны останавливать gpg-agent после их завершения

Фактический результат

каждый запуск теста порождает больше агентов gpg

Системная информация

  • Электра Версия: мастер

Дополнительные файлы журнала и вывод

+ 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

Самый полезный комментарий

имейте в виду, что если вы используете общий домашний каталог, вы не сможете запускать тесты параллельно.
И вам все равно нужно будет удалить GNUPGHOME после этого (вы же не хотите, чтобы pgp-агент отвечал на вызовы для вошедшего в систему пользователя, верно?).

И что произойдет, если целевая система будет использовать GNUPGHOME, поэтому вам нужно будет сохранить существующий env и восстановить его вручную после тестов.

Я был бы признателен, если бы мы могли сделать шаг назад и посмотреть, как эти тесты могут повлиять на пользовательские машины, а не только на среду тестового сервера.

Все 36 Комментарий

Спасибо, что сообщили о проблеме!

@ petermax2 Возможно ли, что команды gpg во время тестов порождают gpg-агентов?

Ой, я думал, что gpg всегда будет подключаться к одному и тому же агенту. Я займусь расследованием.

@ markus2330 это также причина того, что так много агентов gpg в версии 2 сообщается с вашим идентификатором пользователя, поскольку контейнер докеров работает с 1000: 1000.

но проблема не ограничивается докером: debian-stretch-minimal также имеет> 250 из них

некоторые узлы не затронуты, потому что они настроены для создания gpg-агента для jenkins, который используется тестами (вероятно, необходимо подтвердить)

Спасибо вам обоим за то, что изучили это!

некоторые узлы не затронуты, потому что они настроены для создания gpg-агента для jenkins, который используется тестами (вероятно, необходимо подтвердить)

Если мы не можем найти способ убить запускаемых нами агентов, мы можем просто потребовать, чтобы в среде уже был gpg-agent (# 1888).

Возможно, агент gpg вообще не требуется для запуска, и мы можем подавить его во время тестов. Но я должен посмотреть его вечером.

mh обычно GPG_AGENT_INFO следует устанавливать при запуске, в прошлом мы очищали переменные среды, чтобы это могло объяснить несколько запусков в прошлом. Не знаю, почему это все еще происходит прямо сейчас ...

@ petermax2 тесты, требующие gpg-agent (можно найти путем переименования gpg-agent в gpg-agent.bak;)):

  • testmod_fcrypt
  • testmod_crypto_openssl
  • testmod_crypto_gcrypt

testmod_crypto_botan должен работать точно так же, как testmod_crypto_gcrypt и testmod_crypto_openssl . На сервере запущен тест Botan?

@ petermax2, наверное, да. в среде, где я тестировал, не было установлено Botan. однако здесь он работает и, вероятно, также порождает агентов.

Это не так просто. Я попытался вызвать gpg с аргументом --no-autostart во время модульных тестов, однако gpg все еще запускает агент. --no-use-agent - забавный. На странице руководства говорится:

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

Если мы не можем найти способ убить запускаемых нами агентов, мы можем просто потребовать, чтобы в среде уже был gpg-agent (# 1888).

Можем ли мы дать этому шанс?

Или сделайте cron-задание вроде

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

или что-то подобное на серверах / контейнерах сборки?

Я бы проверил, доступен ли агент, если не запустил его и не сохранил его pid. в тестовой очистке остановите агент. все остальное - взлом.

Вы правы, вопрос только в том, где должен происходить старт и стоп. Сделать это в наших агентах / докерах кажется проще, чем в наших модульных тестах, написанных на C.

Вот что я узнал на данный момент:

Можно подавить автоматический запуск gpg-agent с помощью опции --no-autostart , если она последовательно используется со всеми вызовами gpg . Однако без gpg-agent gpg2 не может выполнять никаких операций, требующих закрытого ключа (т.е. дешифрования, подписи).

Также можно выполнить форк gpg-agent --server но тогда gpg2 не сможет подключиться к агенту. Переменная среды GPG_AGENT_INFO устарела и больше не рассматривается gpg2 .

Попробую форк и execv gpg-agent --daemon . Мне просто нужен способ узнать PID запущенного gpg-agent чтобы я мог SIGTERM когда тесты будут выполнены.

Сделать это в наших агентах / докерах кажется проще, чем в наших модульных тестах, написанных на C.

Думаю, намного проще :-)

Я считаю, что ваше решение было правильным - просто использовать gpg по умолчанию для подключения к агентам.

В качестве альтернативы запуску / остановке gpg-agent мы также можем отключить "use-agent" в .gnupg / gpg.conf

у меня нет проблем с автозапуском одного агента (и даже если он запущен). У меня проблема с запуском нового теста при последующих

Я считаю, что ваше решение было правильным - просто использовать gpg по умолчанию для подключения к агентам.

В производственной среде это лучший вариант. На моей машине crypto и fcrypt всегда подключаются к одному и тому же агенту, и интеграция с моим Yubikey работает очень хорошо.

в наших тестовых средах мы должны поддерживать один экземпляр агента в рабочем состоянии перед запуском тестов. Я думаю, проблема в том, что мы очищаем среду, как упоминалось ранее в @ingwinlu .

Думаю, проблема в том, что мы очищаем окружающую среду

мы больше не должны. но проблема не устранена

Если gpg-agent пытается установить связь через среду, очевидно, что он не может работать, при следующем тестовом запуске среда никогда не будет установлена ​​ранее.

Мне больше всего нравятся следующие два варианта:

  1. мы должным образом запускаем / останавливаем агент gpg внутри контейнеров и документируем в TESTING.md, что агент gpg должен быть запущен (см. № 1888).
  2. мы отключаем запуск агентов gpg (отключите «use-agent» в .gnupg / gpg.conf, должно работать, но не тестировали) и задокументируем это в TESTING.md (см. # 1888).

Настройка, при которой демоны запускаются по запросу без глобального способа узнать, запущен ли демон уже (а переменные env не глобальные, а специфичные для процесса), похоже, не работает. Не стоит пытаться исправить это в рамках тестов.

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

Причина, по которой вы создаете много агентов, - это другой домашний каталог, использующий параметр --homedir, в противном случае был бы использован один. Начиная с GnuPG 2.1, вся связь с агентом осуществляется через сокет в домашнем каталоге GnuPG.

Мы не используем опцию homedir. И https://dev.gnupg.org/T3218 описывает обходной путь stackoverflow как «(очень неудобный) обходной путь».

Возможно, простой запуск gpg-agent - это наиболее перспективный вариант (управляемым способом в нашей среде). Похоже, что в последних версиях запуск gpg-agent больше не является обязательным. (что делает мой вариант 2. выше бессмысленным)

Мы не используем опцию homedir.

Да, я не нашел, откуда он взялся, но он соответствует проблеме (см. Op), поскольку все агенты были созданы с другим.

Это был хороший намек, я узнал, что запуск gpg-agent больше не является обязательным.

Это дает понять, что нам нужно начинать и останавливать. И не пытайтесь избежать запуска.

Мы не используем опцию homedir.

Да, я не нашел, откуда это, но это соответствует проблеме (см. Op)

Мы не используем параметр --home-dir явно, но ps -ef показывает, что gpg все равно каким-то образом устанавливает его.

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

$ GNUPGHOME используется GnuPG для указания каталога, в котором хранятся его файлы конфигурации. По умолчанию $ GNUPGHOME не установлен, и вместо него используется ваш $ HOME; таким образом, вы найдете каталог ~ / .gnupg сразу после установки.
Чтобы изменить расположение по умолчанию, либо запустите gpg следующим образом $ gpg --homedir path / to / file, либо установите переменную среды GNUPGHOME.
``
@ petermax2 вы можете проверить, доступен ли HOME в вашем тестовом наборе?

тоже интересно https://www.gnupg.org/documentation/manuals/gnupg/Ephemeral-home-directories.html :

Создайте временный каталог, создайте (или скопируйте) конфигурацию, которая соответствует вашим потребностям, заставьте gpg использовать этот каталог либо с помощью переменной среды GNUPGHOME, либо с параметром --homedir. GPGME также поддерживает это для каждого контекста, изменяя информацию о механизме контекстов. Теперь выполните любую операцию, которая вам нравится, импортируйте и экспортируйте ключевой материал по мере необходимости. По завершении вы можете удалить каталог. Все запущенные серверные службы GnuPG обнаружат это и отключатся.

Протестировал это в моем контейнере, и он автоматически очистил процесс, как и обещал.

@ petermax2 вы можете проверить, доступен ли HOME в вашем тестовом наборе?

Да, HOME доступно:

HOME = /tmp/elektra-test.3vLR4L

Хорошо, значит, что-то в наборе тестов заменяет HOME в каталог tmp (что хорошо). Если он все еще доступен во время очистки, его следует просто удалить, чтобы остановить агент. Это было бы идеальным решением.

Если мы просто установим GNUPGHOME создан только один экземпляр gpg-agent . GNUPGHOME не перезаписывается перед запуском теста.

При установленном GNUPGHOME только один gpg-agent выполняется после многократных тестовых запусков.

Думаю, это простейшее решение.

имейте в виду, что если вы используете общий домашний каталог, вы не сможете запускать тесты параллельно.
И вам все равно нужно будет удалить GNUPGHOME после этого (вы же не хотите, чтобы pgp-агент отвечал на вызовы для вошедшего в систему пользователя, верно?).

И что произойдет, если целевая система будет использовать GNUPGHOME, поэтому вам нужно будет сохранить существующий env и восстановить его вручную после тестов.

Я был бы признателен, если бы мы могли сделать шаг назад и посмотреть, как эти тесты могут повлиять на пользовательские машины, а не только на среду тестового сервера.

Возможно, вы не сможете запускать тесты параллельно.

Я запустил сценарий:

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

без проблем. GPG должна заниматься блокировкой и т. Д.

вы же не хотите, чтобы pgp-agent отвечал на звонки для вошедшего в систему пользователя?

Так был разработан gpg-agent : он работает вечно, пока пользовательский сеанс не закончится. Он не записывает свой PID в какое-то место, нет команд для выхода из него. Он реагирует только на SIGTERM .

Я попытался fork gpg-agent из модульного теста с опцией --server , так что впоследствии у нас будет PID kill . Но тогда gpg-agent не открывает требуемые сокеты в $GNUPGHOME и модульные тесты повторно открывают другой экземпляр агента (который работает в режиме --daemon ). Также нет способа заставить gpg-agent открывать какие-либо сокеты в режиме --server (я проверил это с помощью исходного кода gpg-agent ).

gpg-agent трудно контролировать и практически не документировать. Я даже читал исходный код gpg-agent . Наш вариант использования не рассматривается. Единственный вариант - SIGTERM .

параллелизм

Я больше думал о том, что нужно разделить gpg-агентов, которые не должны влиять друг на друга. т.е. вы хотите, чтобы только агент a имел ключ теста a, а агент b имел ключ теста b. Если в этом нет необходимости, тогда подойдет жестко запрограммированный tmp home.

убийство gpg-агента

При первом исследовании проблемы я наткнулся на веб-сайт (ссылка на который приведена выше), на котором говорилось, что ожидаемый способ закрыть временный gpg-агент - удалить его домашний каталог gpg.

Поэтому, если вы установите GNUPGHOME на /tmp/elektra_tests/gpg и во время тестовой очистки удалите этот каталог tmp, все будет в порядке.

Поэтому, если вы установите GNUPGHOME в / tmp / elektra_tests / gpg и во время тестовой очистки удалите этот каталог tmp, все будет в порядке.

Оно работает! Я буду интегрировать это исправление в тестовые примеры crypto и fcrypt . Спасибо за совет!

У меня есть рабочий прототип. PR наступает завтра.

Должен быть исправлен с помощью # 2056. Пожалуйста, откройте заново, если проблема не исчезнет.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

mpranj picture mpranj  ·  3Комментарии

markus2330 picture markus2330  ·  4Комментарии

sanssecours picture sanssecours  ·  4Комментарии

mpranj picture mpranj  ·  3Комментарии

mpranj picture mpranj  ·  4Комментарии