首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么systemctl不返回NRPE检查中的值?

为什么systemctl不返回NRPE检查中的值?
EN

Stack Overflow用户
提问于 2020-04-22 06:34:39
回答 2查看 591关注 0票数 1

我写的NRPE支票有问题。

它是一个简单的shell脚本,运行"systemctl是-active service_name“并将值返回给我们的Thruk。

当我直接与用户nrpe一起运行脚本时,它可以工作:

代码语言:javascript
复制
-bash-4.2$ /usr/lib64/nagios/plugins/check_service_active.sh --service dynflowd
dynflowd
Service dynflowd démarré

但是,当我在本地使用NRPE运行它时,它会告诉我服务被停止了:

代码语言:javascript
复制
-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有什么,但是我找不到什么?我在谷歌上没有找到任何关于它的信息。

所以我来了!

谢谢您的答复,如果我不能理解的话,很抱歉。

这是我的剧本:

代码语言:javascript
复制
#!/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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-04-23 08:38:45

我终于找到了问题: NRPE版本!

在我的服务器上,NRPE在nrpe-3.2.1-6中。

我通过NRPE在另一台服务器上运行我的脚本,它可以工作。

另一台服务器运行nrpe-3.2.1-8

所以解决办法是:更新!

感谢您的时间和想法,特别是>> /tmp/paxdebug.dynflowd 2>&1的想法,帮助我解决问题。

票数 0
EN

Stack Overflow用户

发布于 2020-04-22 07:44:42

好的,类似于cron作业,可能是NRPE (服务器)运行在与您的shell不同的环境中,而且这个不同的环境不知何故没有正确地运行systemctl

查看这一点的一个简单方法是修改以下内容:

代码语言:javascript
复制
STAT=$(systemctl is-active $SERV)

暂时排队,这样你就能看到发生了什么。更改脚本,使该行现在变成:

代码语言:javascript
复制
(
    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会导致:

代码语言:javascript
复制
systemctl: command not found

这几乎可以肯定是因为这条路是错的。您可以通过在我发布的调试代码中添加以下行来检查路径:

代码语言:javascript
复制
echo "PATH is [$PATH]"

要修复它,要么修改脚本中的路径以包含/usr/bin (假设systemctl驻留在那里),要么只运行绝对路径(在调试区域和原始区域):

代码语言:javascript
复制
/usr/bin/systemctl is-active ${SERV}
STAT=$(/usr/bin/systemctl is-active ${SERV})

更新2:根据您的注释,在使用绝对路径之后,您现在可以获得:

代码语言:javascript
复制
/usr/lib64/nagios/plugins/check_service_active.sh: line 32:
    /usr/bin/systemctl: Permission denied

这可能是在低特权级别运行的NRPE,或者作为一个不同的用户来提供安全攻击。考虑到中央系统对系统运行的影响,允许不受限制地访问它是不明智的。

因此,与上一次更新类似,将以下内容添加到调试区域:

代码语言:javascript
复制
/bin/ls -al /usr/bin/systemctl # Check "ls" is in this directory first.
/usr/bin/id                    # Ditto for "id".

第一行将获得权限,第二行将为您提供用户详细信息。在这一点上,它成为了一个练习,如何在不违反安全性的情况下运行systemctl

如果发现这是一个权限或用户问题,一种可能是提供一个安全良好的setuid脚本,该脚本将由允许运行systemctl的用户拥有(因此以用户身份运行)。但我的意思是很安全,因为你不想打开一个洞:

代码语言:javascript
复制
# 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脚本的一种修改:

代码语言:javascript
复制
#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;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61358685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档