Shell 为什么systemctl没有';在NRPE检查中是否不返回值?
我写的NRPE支票有问题 它是一个简单的shell脚本,运行“systemctl是活动的[service_name]”,并将值返回给我们的Thruk 当我直接使用用户nrpe运行脚本时,它可以工作:Shell 为什么systemctl没有';在NRPE检查中是否不返回值?,shell,systemctl,nrpe,thruk,Shell,Systemctl,Nrpe,Thruk,我写的NRPE支票有问题 它是一个简单的shell脚本,运行“systemctl是活动的[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
-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命令。
当我用另一个命令(如“echo”)替换systemctl时,它就可以工作了
所以我认为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
好的,与
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启动实例中到底发生了什么
希望它会说一些简单的东西,比如找不到systemctl
(表示路径问题),但是,不管它给了你什么,它都应该有助于准确地找出问题所在
更新1:根据您的评论,尝试运行
systemctl
会导致:
systemctl: command not found
这几乎可以肯定,因为这条路是错的。您可以通过在我发布的调试代码中添加以下行来检查路径:
echo "PATH is [$PATH]"
若要修复此问题,请修改脚本中的路径以包含/usr/bin
(假设该路径位于systemctl
所在的位置),或者只运行绝对路径(在调试和原始区域中):
更新2:根据您的评论,使用绝对路径后,您现在可以获得:
/usr/lib64/nagios/plugins/check_service_active.sh: line 32:
/usr/bin/systemctl: Permission denied
这可能是以低权限级别运行的NRPE,或者是以不同的用户身份运行的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行的shell脚本(如
#!/usr/bin/env bash
),我认为setuid
被忽略,因此您可能需要解决这个问题,可能需要构建一个真正的可执行文件来完成这项工作
如果您确实需要为它构建一个真正的可执行文件,那么可以从以下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;
}
#包括
#包括
#包括
int main(int argc,字符**argv){
//检查提供的服务名称。
如果(argc<2){
认沽权(“已提供”);
返回1;
}
//检查允许的服务名称。
静态字符*允许[]={“dynflowd”,NULL};
允许int=0;
for(char**service=&(允许[0]);*service!=NULL;service++){
if(strcmp(*服务,argv[1])==0){
i允许=1;
打破
}
}
如果(!不允许){
puts(“InvalidServiceName”);
返回1;
}
//尝试为命令分配内存。
char*prefix=“/usr/bin/systemctl处于活动状态”;
char*cmdBuff=malloc(strlen(前缀)+strlen(argv[1])+1);
如果(cmdBuff==NULL){
出售(“失忆”);
返回1;
}
//执行命令,释放内存,然后返回。
sprintf(cmdBuff,“%s%s”,前缀,argv[1]);
系统(cmdBuff);
免费(cmdBuff);
返回0;
}
好的,与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启动实例中到底发生了什么
希望它会说一些简单的东西,比如找不到systemctl
(表示路径问题),但是,不管它给了你什么,它都应该有助于准确地找出问题所在
更新1:根据您的评论,尝试运行
systemctl
会导致:
systemctl: command not found
这几乎可以肯定,因为这条路是错的。您可以通过在我发布的调试代码中添加以下行来检查路径:
echo "PATH is [$PATH]"
若要修复此问题,请修改脚本中的路径以包含/usr/bin
(假设该路径位于systemctl
所在的位置),或者只运行绝对路径(在调试和原始区域中):
更新2:根据您的评论,使用绝对路径后,您现在可以获得:
/usr/lib64/nagios/plugins/check_service_active.sh: line 32:
/usr/bin/systemctl: Permission denied
这可能是以低权限级别运行的NRPE,或者是以不同的用户身份运行的NRPE,以提供免受攻击的安全性。