【问题标题】:Why systemctl doesn't return a value in an NRPE check?为什么 systemctl 在 NRPE 检查中不返回值?
【发布时间】:2020-08-05 02:15:01
【问题描述】:

我写的 NRPE 检查有问题。

这是一个简单的 shell 脚本,运行“systemctl is-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 命令相关联。 当我用另一个命令(如“echo”)替换 systemctl 时,它可以工作。

所以我认为 NRPE 和 systemctl 有一些东西,但我找不到什么? 而且我在 Google 上找不到任何关于它的信息。

所以我来了!

提前感谢您的回复,如果我不够理解,请见谅。

这是我的脚本:

#!/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

【问题讨论】:

  • 几个问题: 1/ 打印输出的第一行(服务名称本身)是什么?脚本中似乎没有任何内容可以执行此操作。 2/ NPRE 版本如何,假设它在某个时候调用相同的脚本,当您没有 --server 参数时设置 SERV 变量?我可能不知道 NPRE 的实际工作原理,但这两个问题的答案可能会指导您。
  • 1/ 变量 $STAT 包含我的命令的值(在这里,它可以是活动的或非活动的),根据此,脚本打印服务的状态并使用正确的代码退出:好的或关键的。 2/ 我不知道我是否正确理解了您的问题,但它是 NRPE v3.2.1。设置“SERV”变量的是“--service”参数。
  • 1/ 是的,但是脚本唯一打印的是Service $SERV démarré/arrêté这一行,而您的输出有行@987654327 @ 和 Service dynflowd arrêté。第一行输出来自哪里? 2/ 我知道--service 设置SERV 当你将它提供给脚本时,我只是问你执行的--service 来自哪里check_nrpe 命令 - 你所拥有的就是-a .在check_nrpe 和对您的脚本的调用之间是否还有其他配置?
  • 1/ 我忘了第一行,对不起。这只是测试SERV 变量是否设置正确。 2/ 我忘了在我的 nrpe.cfg 中添加设置 nrpe 命令的行:command[check_service_active]=/usr/lib64/nagios/plugins/check_service_active.sh --service $ARG1$
  • 因此可以使用-c check_service_active 读取命令check_nrpe -H 127.0.0.1 -c check_service_active -a 'dynflowd'(=执行命令check_service_active)和参数-a 'dynflowd'

标签: shell systemctl nrpe thruk


【解决方案1】:

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

在我的服务器上,NRPE 位于nrpe-3.2.1-6

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

这台服务器运行nrpe-3.2.1-8

所以解决办法是:更新!

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

【讨论】:

    【解决方案2】:

    好的,类似于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 的 cmets 导致:

    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:根据您的 cmets,使用绝对路径,您现在得到:

    /usr/lib64/nagios/plugins/check_service_active.sh: line 32:
        /usr/bin/systemctl: Permission denied
    

    可能是 NRPE 以低权限级别运行,或者作为不同的用户提供安全性免受攻击。鉴于 systemd 对系统运行的重要性,允许不受限制地访问它是不明智的。

    所以,和之前的更新类似,在调试区添加如下内容:

    /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}"
    

    可能还有其他方法(它们可能会更好),但如果这确实是问题所在,那应该是一个好的开始。


    请注意,我认为 setuid 对于具有 shebang 行的 shell 脚本(如 #!/usr/bin/env bash)会被忽略,因此您可能需要解决这个问题,可能需要构建一个真正的可执行文件来完成这项工作。

    如果你确实必须为它构建一个真正的可执行文件,你可以从下面的 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;
    }
    

    【讨论】:

    • 我将STAT=$(systemctl is-active $SERV) 行替换为您给我的代码。但是当我运行检查时,除了消息“Service dynflowd arrêté”之外什么都没有发生......而且没有 /tmp/paxdebug.dynflowd 文件。仅当我不使用 NRPE 直接运行脚本但里面没有有用信息时才会出现此文件。
    • 但我同意你的观点,即 NRPE 可能在不同的环境中运行。
    • 好的,几点。我希望在文件中看到的是日期/服务名称行,后跟活动。你说你没有得到有用的信息,但你至少得到了。而且,如果您在 NRPE 下运行时得到 nothing,我会认为它正在运行一些 other 脚本,而不是您修改的那个。
    • 在您发表评论后,我想直接通过 NRPE 重新运行脚本,以确保我没有遗漏任何内容,我终于在 /tmp/paxdebug.dynflowd 文件中打印了一些内容当我运行 NRPE 检查时。我认为运行 NRPE 检查无法创建文件,但可以写入文件。无论如何,它在第 32 行 (systemctl is-active $SERV) 说:systemctl: command not found
    • 为了更进一步,我将 systemctl 替换为 /usr/bin/systemctl 并且文件 /tmp/paxdebug.dynflowd 给了我这个错误:/usr/lib64/nagios/plugins/check_service_active.sh: line 32: /usr/bin/systemctl: Permission denied
    猜你喜欢
    • 2019-11-05
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-21
    • 2020-02-08
    • 2014-02-10
    • 1970-01-01
    相关资源
    最近更新 更多