我写的NRPE支票有问题。
它是一个简单的shell脚本,运行"systemctl是-active service_name“并将值返回给我们的Thruk。
当我直接与用户nrpe一起运行脚本时,它可以工作:
-bash-4.2$ /usr/lib64/nagios/plugins/check_service_active.sh --service dynflowd
dynflowd
Service dynflowd démarré但是,当我在本地使用NRPE运行它时,它会告诉我服务被停止了:
-bash-4.2$ ./check_nrpe -H 127.0.0.1 -c check_service_active -a 'dynflowd'
dynflowd
Service dynflowd arrêté经过多次测试后,我发现它被链接到systemctl命令。当我将systemctl替换为另一个命令(如"echo“)时,它可以工作。
所以我觉得NRPE和systemctl有什么,但是我找不到什么?我在谷歌上没有找到任何关于它的信息。
所以我来了!
谢谢您的答复,如果我不能理解的话,很抱歉。
这是我的剧本:
#!/bin/sh
#
# Script d'interrogation d'un service via systemctl
# Nagios return codes
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3
STATE_DEPENDENT=4
#Recuperation des parametres
while test -n "$1"; do
case "$1" in
--service)
SERV=$2
shift
;;
-u)
print_usage
exit $STATE_OK
;;
esac
shift
done
STAT=$(systemctl is-active $SERV)
if [[ $STAT == "active" ]]
then
echo "Service $SERV démarré"
exit $STATE_OK
else
echo "Service $SERV arrêté"
exit $STATE_CRITICAL
fi发布于 2020-04-23 08:38:45
我终于找到了问题: NRPE版本!
在我的服务器上,NRPE在nrpe-3.2.1-6中。
我通过NRPE在另一台服务器上运行我的脚本,它可以工作。
另一台服务器运行nrpe-3.2.1-8。
所以解决办法是:更新!
感谢您的时间和想法,特别是>> /tmp/paxdebug.dynflowd 2>&1的想法,帮助我解决问题。
发布于 2020-04-22 07:44:42
好的,类似于cron作业,可能是NRPE (服务器)运行在与您的shell不同的环境中,而且这个不同的环境不知何故没有正确地运行systemctl。
查看这一点的一个简单方法是修改以下内容:
STAT=$(systemctl is-active $SERV)暂时排队,这样你就能看到发生了什么。更改脚本,使该行现在变成:
(
echo ==== $(date) ==== ${SERV}
systemctl is-active $SERV
) >> /tmp/paxdebug.dynflowd 2>&1
STAT=$(systemctl is-active $SERV)除了运行脚本以获取状态外,还可以将一些有用的信息写入/tmp/paxdebug.dynflowd文件,然后您可以检查这些信息,以查看脚本的NRPE启动实例中到底发生了什么。
希望它能说一些简单的东西,比如Cannot find systemctl (指出路径问题),但是,不管它给了您什么,它都应该有助于准确地找出问题的所在。
更新1:根据您的评论,试图运行systemctl会导致:
systemctl: command not found这几乎可以肯定是因为这条路是错的。您可以通过在我发布的调试代码中添加以下行来检查路径:
echo "PATH is [$PATH]"要修复它,要么修改脚本中的路径以包含/usr/bin (假设systemctl驻留在那里),要么只运行绝对路径(在调试区域和原始区域):
/usr/bin/systemctl is-active ${SERV}
STAT=$(/usr/bin/systemctl is-active ${SERV})更新2:根据您的注释,在使用绝对路径之后,您现在可以获得:
/usr/lib64/nagios/plugins/check_service_active.sh: line 32:
/usr/bin/systemctl: Permission denied这可能是在低特权级别运行的NRPE,或者作为一个不同的用户来提供安全攻击。考虑到中央系统对系统运行的影响,允许不受限制地访问它是不明智的。
因此,与上一次更新类似,将以下内容添加到调试区域:
/bin/ls -al /usr/bin/systemctl # Check "ls" is in this directory first.
/usr/bin/id # Ditto for "id".第一行将获得权限,第二行将为您提供用户详细信息。在这一点上,它成为了一个练习,如何在不违反安全性的情况下运行systemctl。
如果发现这是一个权限或用户问题,一种可能是提供一个安全良好的setuid脚本,该脚本将由允许运行systemctl的用户拥有(因此以用户身份运行)。但我的意思是很安全,因为你不想打开一个洞:
# SysCtlIsActive.sh: only allows certain services to be queried.
# Limit to these ones (white-space separated).
allowed="dynflowd"
# If not allowed, reject with special status.
result="GoAway"
for service in ${allowed} ; do
[[ "$1" = "${service}" ]] && result=""
done
# If it IS allowed, get actual status.
[[ -z "${result}" ]] && result="$(/usr/bin/systemctl is-active "$1")"
echo "${result}"也许还有其他的方法(而且它们可能更好),但如果这确实是问题所在,那应该是一个好的开始。
请注意,对于具有shebang行(如setuid )的shell脚本,我认为忽略了它,因此您可能不得不为此而工作,可能需要构建一个真正的可执行文件来完成这项工作。
如果您必须为它构建一个真正的可执行文件,您可以从下面的C代码开始,这是对上面的shell脚本的一种修改:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv) {
// Check service name provided.
if (argc < 2) {
puts("NoServiceProvided");
return 1;
}
// Check service name allowed.
static char *allowed[] = { "dynflowd", NULL };
int isAllowed = 0;
for (char **service = &(allowed[0]); *service != NULL; service++) {
if (strcmp(*service, argv[1]) == 0) {
isAllowed = 1;
break;
}
}
if (! isAllowed) {
puts("InvalidServiceName");
return 1;
}
// Try to allocate memory for command.
char *prefix = "/usr/bin/systemctl is-active ";
char *cmdBuff = malloc(strlen(prefix) + strlen(argv[1]) + 1);
if (cmdBuff == NULL) {
puts("OutOfMemory");
return 1;
}
// Execute command, free memory, and return.
sprintf(cmdBuff, "%s%s", prefix, argv[1]);
system(cmdBuff);
free(cmdBuff);
return 0;
}https://stackoverflow.com/questions/61358685
复制相似问题