Dan*_*lov 16 kill centos systemd
我正在systemd为 OSSEC HIDS编写单元文件。问题是,当systemd启动服务时,它会立即停止它们。
当我使用以下ExecStart指令时,一切正常。
ExecStart=/var/ossec/bin/ossec-control start
Run Code Online (Sandbox Code Playgroud)
但是当我进行以下小的改进时,我在 OSSEC 日志中发现它SIG 15在启动后收到。
ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start'
Run Code Online (Sandbox Code Playgroud)
如果我再做一个小的更改,服务将SIG 15在 20 秒后收到。
ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start && sleep 20'
Run Code Online (Sandbox Code Playgroud)
所以,我想,这会在服务启动后systemd杀死/bin/sh进程,/bin/sh然后杀死OSSEC.
我怎么解决这个问题?
Jde*_*eBP 40
正如 Wieland 暗示的那样,Type服务的重要性非常重要。该设置表示systemd 期望服务说话的准备协议。一个simple服务被认为是立即准备。一个forking服务被认为其初始过程派生一个子项,然后退出后要准备好。一个dbus服务被认为当一个服务器出现在桌面总线做好准备。等等。
如果您没有获得服务单元中声明的就绪协议以匹配服务所做的事情,那么事情就会出错。就绪协议不匹配会导致服务无法正确启动,或者(更常见的是)被 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非常具体。初始进程必须fork一个子进程,然后退出。systemd 对此协议应用超时。如果初始进程没有在规定的时间内分叉,则无法做好准备。如果初始进程没有在分配的时间内退出,那也是失败。
ossec-control这给我们带来了复杂的东西:那个ossec-control脚本。
事实证明,这是一个 System 5rc脚本,它在 4 到 10 个进程之间分叉,这些进程本身也分叉并退出。它是 System 5rc脚本中的一个,它试图在一个脚本中管理一整套服务器进程,带有for循环、竞争条件、任意sleeps 以试图避免它们,故障模式可以使系统处于半启动状态,以及所有其他让人们在 20 年前发明 AIX 系统资源控制器和 daemontools 之类的东西的恐怖。让我们不要忘记二进制目录中隐藏的 shell 脚本,它会即时重写,以实现特殊enable和disable动词。
所以当你/bin/sh -c '/var/ossec/bin/ossec-control start'发生的事情是:
ossec-control。ossec-control 退出。forking ,也不在simple准备协议,systemd认为服务作为一个整体已经失败,并关闭了回去。在 systemd 下,这些恐怖实际上根本没有必要。都没有。
相反,人们编写了一个非常简单的模板单元:
[单元] 描述=OSSEC HIDS %i 服务器 之后=网络.目标 [服务] 类型=简单 ExecStartPre=/usr/bin/env /var/ossec/bin/%p-%i -t ExecStart=/usr/bin/env /var/ossec/bin/%p-%i -f [安装] WantedBy=multi-user.target
将此保存为/etc/systemd/system/ossec@.service.
各种实际服务是这个模板的实例,命名为:
ossec@dbd.serviceossec@agentlessd.serviceossec@csyslogd.serviceossec@execd.serviceossec@agentd.serviceossec@logcollector.serviceossec@syscheckd.serviceossec@maild.serviceossec@analysisd.serviceossec@remoted.serviceossec@monitord.service然后启用和禁用功能直接来自服务管理系统(修复了RedHat 错误 752774),不需要隐藏的 shell 脚本。
systemctl 启用 ossec@dbd ossec@agentlessd ossec@csyslogd ossec@maild ossec@execd ossec@analysisd ossec@logcollector ossec@remoted ossec@syscheckd ossec@monitord
此外,systemd 可以直接了解和跟踪每个实际服务。它可以过滤他们的日志journalctl -u。它可以知道单个服务何时失败。它知道应该启用和运行哪些服务。
顺便说一句:Type=simple这个-f选项在这里就像在许多其他情况下一样。实际上,在野外很少有服务通过 来表示它们已准备就绪exit,这里的这些也不是这种情况。但这就是forking类型的含义。主要的野外服务只是分叉并退出,因为一些错误的智慧观念认为这就是守护程序应该做的事情。事实上,事实并非如此。自 1990 年代以来就没有了。是时候赶上来了。
| 归档时间: |
|
| 查看次数: |
20678 次 |
| 最近记录: |