You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python远程执行命令编写Nagios RAID状态监控插件方案咨询

Nagios远程检测RAID状态的提权方案与脚本实现

核心提权实现(最高效安全的生产标准方案)

获取RAID状态需要root权限,不要使用root直连SSH、给二进制加SUID这类高风险方案,正确实现步骤如下:

  • 在被监控主机创建专用的监控账号(例如nagios_check),配置监控服务器到该账号的SSH密钥免密登录,同时禁止该账号的交互式登录权限
  • 在被监控主机用visudo命令编辑sudo规则(该命令会自动做语法校验,避免配置错误导致sudo功能失效),添加如下行,给监控账号开放单条命令的免密sudo权限:
nagios_check ALL=(root) NOPASSWD: /opt/MegaRAID/MegaCli/MegaCli64 -ShowSummary -a0

注意:规则必须写全命令的绝对路径和固定参数,不要使用通配符,避免出现权限逃逸漏洞

  • 后续远程执行命令时,在原MegaCli命令前加sudo即可正常获取输出,不需要输入密码,权限边界清晰无额外风险。

现有脚本的问题修正

你提供的初稿存在几处会导致运行失效的错误,需要调整:

  • 语法错误:ssh.stdoutreadlines()为错误写法,正确方法是ssh.stdout.readlines();直接拼接SSH命令字符串存在命令注入风险,应该用列表形式传参给subprocess模块
  • 逻辑错误:原状态判断语句elif (active) or (online) or (k) in (check)存在优先级问题,会直接判定为真,无论输出是否匹配都会返回OK状态;读取的SSH输出为bytes类型,直接做字符串匹配会出现漏判
  • 规范问题:Nagios插件要求标准输出只返回最终状态字符串,多余的调试打印(比如你写的print(args))会导致Nagios无法正常识别状态;未做超时、执行异常处理,网络波动时会导致插件卡死
  • 冗余问题:导入了未使用的os、socket模块,多余的str()类型转换可以删除

修正后可直接使用的插件脚本

#!/usr/bin/env python3
import sys
import argparse
import subprocess

# Nagios标准返回码,固定不可修改
OK = 0
WARNING = 1
CRITICAL = 2
UNKNOWN = 4

# 状态匹配关键词
KEYWORD_DEGRADED = "Degraded"
KEYWORD_FAILED = "Failed"
KEYWORDS_OK = ["Active", "Online", "OK"]

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='LSI RAID控制器状态Nagios检测插件')
    parser.add_argument("--user", "-U", required=True, help="远程SSH连接用户名")
    parser.add_argument("--hostname", "-H", required=True, help="被监控主机地址")
    args = parser.parse_args()

    # 构造SSH执行命令,列表传参避免命令注入
    ssh_exec_cmd = [
        "ssh",
        "-o", "StrictHostKeyChecking=accept-new",
        f"{args.user}@{args.hostname}",
        "sudo", "/opt/MegaRAID/MegaCli/MegaCli64", "-ShowSummary", "-a0"
    ]

    try:
        exec_result = subprocess.run(
            ssh_exec_cmd,
            capture_output=True,
            timeout=30,
            check=True
        )
        # 统一转小写做匹配,规避大小写差异导致的漏判
        raid_output = exec_result.stdout.decode('utf-8', errors='ignore').lower()
    except subprocess.CalledProcessError as e:
        err_msg = e.stderr.decode('utf-8', errors='ignore').strip()
        print(f"UNKNOWN: 远程命令执行失败, 错误信息: {err_msg}")
        sys.exit(UNKNOWN)
    except subprocess.TimeoutExpired:
        print("UNKNOWN: 远程命令执行超时(30秒)")
        sys.exit(UNKNOWN)
    except Exception as e:
        print(f"UNKNOWN: 执行异常: {str(e)}")
        sys.exit(UNKNOWN)

    # 按优先级判断状态
    if KEYWORD_FAILED.lower() in raid_output:
        print("CRITICAL: RAID阵列存在故障硬盘,阵列已失效!")
        sys.exit(CRITICAL)
    elif KEYWORD_DEGRADED.lower() in raid_output:
        print("WARNING: RAID阵列处于降级状态,请及时排查硬盘健康度")
        sys.exit(WARNING)
    elif KEYWORDS_OK[0].lower() in raid_output and KEYWORDS_OK[1].lower() in raid_output or KEYWORDS_OK[2].lower() in raid_output:
        print("OK: RAID控制器、阵列状态均正常")
        sys.exit(OK)
    else:
        print("UNKNOWN: 无法识别RAID返回内容,请手动登录主机排查")
        sys.exit(UNKNOWN)

部署注意事项

  • 给脚本添加可执行权限:chmod +x check_lsi_raid.py,放到Nagios的插件目录下即可按常规插件方式配置监控
  • SSH参数里加了StrictHostKeyChecking=accept-new,可以自动接受首次连接的主机密钥,避免因为host key校验交互导致插件卡住
  • 被监控端sudo规则配置完成后,执行visudo -c校验语法,确认返回解析成功再上线

内容的提问来源于stack exchange,提问作者Alex Noel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 10:54:32