Я пишу файл системного модуля для OSSEC HIDS. Проблема в том, что когда systemd запускает сервис, он немедленно останавливает их.
Когда я использую эту директиву ExecStart, все работает нормально.
ExecStart=/var/ossec/bin/ossec-control start
Но когда я делаю небольшое улучшение, я замечаю в журналах OSSEC, что он получает SIG 15 после запуска.
ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start'
Если я сделаю еще одно небольшое изменение, сервис получит SIG 15 через 20 секунд.
ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start && sleep 20'
Итак, я думаю, что systemd убивает процесс / bin / sh после запуска службы, а bin / sh затем убивает OSSEC.
Как я могу решить эту проблему?
Ответы:
несоответствие протокола готовности
Как и предполагал Виланд,
Type
услуги важны. Этот параметр обозначает, какой протокол готовности systemd ожидает, что служба будет говорить. Предполагается, чтоsimple
услуга немедленно готова.forking
Служба берется , чтобы быть готовым после его первоначальный процесс разветвляется ребенка , а затем завершает свою работу.dbus
Служба берется , чтобы быть готовым , когда на Desktop Bus появляется сервер. И так далее.Если вы не получите протокол готовности, объявленный в сервисном модуле, чтобы он соответствовал тому, что делает сервис, тогда все пошло не так. Несоответствия протокола готовности приводят к тому, что службы запускаются некорректно или (чаще) диагностируются (ошибочно) системой systemd как сбой. Когда служба считается не способной запустить systemd, она гарантирует, что каждый потерянный дополнительный процесс службы, который мог остаться запущенным как часть сбоя (с его точки зрения), завершается, чтобы надлежащим образом вернуть службу в неактивное состояние. государство.
Вы делаете именно это.
Прежде всего, простые вещи:
sh -c
не соответствуетType=simple
илиType=forking
.В
simple
протоколе, начальный процесс берется быть процесс обслуживания. Но на самом делеsh -c
оболочка запускает реальную сервисную программу как дочерний процесс . Так чтоMAINPID
пойдет не так иExecReload
перестает работать, для начала. При использованииType=simple
нужно либо использовать,sh -c 'exec …'
либо не использоватьsh -c
в первую очередь. Последнее чаще является правильным курсом, чем думают некоторые.sh -c
не соответствуетType=forking
ни. Протокол готовности кforking
услуге довольно специфичен. Начальный процесс должен разветвить ребенка, а затем выйти. systemd применяет тайм-аут к этому протоколу. Если начальный процесс не разветвляется в течение выделенного времени, это не готовность к готовности. Если начальный процесс не завершается в течение отведенного времени, это тоже сбой.ненужный ужас, который
ossec-control
Что приводит нас к сложным вещам: этот
ossec-control
сценарий.Оказывается , это
rc
сценарий System 5, который запускает от 4 до 10 процессов, которые, в свою очередь, тоже разветвляются и выходят. Это один из техrc
сценариев System 5, который пытается управлять целым набором серверных процессов в одном сценарии сfor
циклами, состояниями гонки, произвольными значениями,sleep
чтобы попытаться их избежать, режимами сбоев, которые могут задушить систему в начальном состоянии, и все остальные ужасы, которые заставили людей изобретать такие вещи, как AIX System Resource Controller и daemontools два десятилетия назад. И давайте не будем забывать скрытый сценарий оболочки в двоичном каталоге, который он переписывает на лету, для реализации уникальныхenable
иdisable
глаголов.Итак, когда вы,
/bin/sh -c '/var/ossec/bin/ossec-control start'
что происходит, это:ossec-control
.ossec-control
выходы.forking
ниsimple
протокол готовности, Systemd не считает службу в целом, не удалось , и закрывает его обратно вниз.Ничто из этого ужаса на самом деле не нужно в systemd вообще. Ничего из этого.
системный сервисный шаблон
Вместо этого пишется очень простой шаблонный блок :
Сохраните это как
/etc/systemd/system/ossec@.service
.Различные реальные сервисы являются экземплярами этого шаблона и называются:
ossec@dbd.service
ossec@agentlessd.service
ossec@csyslogd.service
ossec@execd.service
ossec@agentd.service
ossec@logcollector.service
ossec@syscheckd.service
ossec@maild.service
ossec@analysisd.service
ossec@remoted.service
ossec@monitord.service
Затем функция включения и выключения поступает прямо из системы управления службами (с исправленной ошибкой RedHat 752774 ), без необходимости скрытых сценариев оболочки.
Кроме того, systemd узнает и отслеживает каждую реальную службу напрямую. Он может фильтровать их журналы с
journalctl -u
. Он может знать, когда произошел сбой отдельной службы. Он знает, какие службы должны быть включены и запущены.Кстати,
Type=simple
и-f
вариант здесь, как и во многих других случаях. Очень немногие службы в дикой природе фактически сигнализируют о своей готовности посредствомexit
, и это тоже не такие случаи. Но это то, чтоforking
означает тип. Службы в дикой природе в основном просто разветвляются и выходят из-за ошибочно полученного мудрого представления о том, что именно этим и должны заниматься демоны. На самом деле это не так. Это не было с 1990-х годов. Пришло время наверстать упущенное.дальнейшее чтение
источник
Requires=
все необходимые экземпляры, а затем установитьPartOf=ossec.target
в ossec @ .service. Это позволит запустить и остановить ossec, запустив и остановив ossec.target.Оставьте Type = разветвление и укажите местоположение файла pid, если служба запуска / приложение поддерживает какой-либо pid.
[Модуль]
Описание = «Запуск приложения при загрузке»
После = network.target syslog.target auditd.service
[Служба]
Тип = разветвление
PIDFile = / var / run / apache2 / apache2.pid
ExecStart = / etc / init.d / apache2 start
ExecStop = / etc / init.d / apache2 stop
StandardOutput = syslog
StandardError = syslog
Перезапуск = при
ошибке SyslogIdentifier = webappslog
[Установить]
WantedBy = multi-user.target
Alias = webapps
источник
В некотором роде у меня был сервис systemd, который, как оказалось, systemd «убьет» его через 30 секунд.
systemctl status service-name
будет показыватьmain process exited, code=exited, status=1/FAILURE
после 30-х годов прошло.Он будет работать нормально "в изоляции" (как вручную в терминале с той же средой ).
Оказывается, это было
внутри
my_script_to_spawn_process.sh
это делало/bin/something > /dev/null 2>&1 &
который работает, но отбрасывает информацию журнала вывода (обычно это идет в файл, или, если нет, возможно
journalctl
).Изменение его для входа в другое место, как
/bin/something > /tmp/my_file
затем выслеживая
/tmp/my_file
выявленную фактическую причину. Это было (по существу) то, что вы не можете использовать синтаксис, который вы можете использоватьEnvironment=ABC="true"
в bash, это не должно быть кавычек или значения ключа в кавычках, какEnvironment="ABC=true"
это было причиной того, что мой процесс завершил работу «в фазе установки» примерно через 30 секунд.источник
Обратите внимание, что модель демона systemd является упрощенной и несовместимой со многими существующими демонами, которые выполняют множественное разветвление, выполнение и установку. Наиболее распространенными являются демоны, которые запускаются с правами root для настройки, а затем переключаются на менее привилегированный UID для обычной работы. Например, инициализация PID-файла - это то, что не работает в systemd из-за проблем с привилегиями. Есть обходные пути (не исправления), но они плохо документированы.
Объяснение JdeBP приветствуется, но неполно, и его утверждение о том, что во всем виноват ossec-контроль, просто не соответствует действительности. Даже довольно тривиальные вещи проблематичны, например, получение не усеченных строк журнала для отладки проблем или значимых сообщений об ошибках от самой systemd, когда он убивает процессы.
источник