Nagios Core —— 以「对象定义 + 插件退出码」为核心的轻量状态监控框架

运维监控软件手册 03-一体化监控平台 29.1 KB 原文

Nagios Core —— 以「对象定义 + 插件退出码」为核心的轻量状态监控框架

分类:03 一体化监控平台 适用:中小规模(几十到数百台)以「是否可用、是否超阈值」为主的服务器、网络设备与业务服务状态检查;无数据库、资源占用低 一句话:一切监控都是配置文件里的对象定义,一切检查都是返回 0/1/2/3 的可执行插件 官方:https://www.nagios.org/ | https://github.com/NagiosEnterprises/nagioscore | https://nagios-plugins.org/ 授权:Nagios Core 为 GPLv2 开源免费;Nagios XI(Web 配置、向导、报表、商业支持)为付费商业版;Core 无节点限制但规模化需自行工程化

1. 它解决什么问题

痛点 对应能力
只想确认主机/端口/进程/URL 是否活着 插件体系:check_ping/check_http/check_tcp/check_procs,退出码即状态
需要统一的状态语义与告警分级 OK(0)/WARNING(1)/CRITICAL(2)/UNKNOWN(3) + SOFT/HARD 状态机
告警要按值班表升级、分时段、分联系人 contact/contactgroup/timeperiod/*escalation
机器在防火墙后,无法被中心直连 NRPE 在被管机本地执行插件,中心通过 check_nrpe 取结果
希望配置纯文本、可 Git 管理、可批量生成 *.cfg 对象定义 + cfg_dir 目录加载,无数据库、无 Web 写配置
「上游故障抑制下游告警」 hostdependency / servicedependency 依赖定义

不擅长:长期指标趋势与容量分析(无内置时序库)、海量主机自动发现(配置靠手写/脚本生成)、容器与短生命周期对象、开箱即用的图形报表;这些是 Icinga 2 / Zabbix / Prometheus 的强项。

2. 核心概念与架构

2.1 术语表

术语 含义
Object definition define host{...} / define service{...} 文本块,是 Nagios 唯一的配置载体
Host / Service / Command 被监控主机 / 主机上的检查项 / define command{command_line ...} 包装插件(参数 $ARG1$)
Plugin / NRPE libexec/ 下靠退出码 + 标准输出传状态与 perfdata 的可执行程序;NRPE 为远端插件执行守护进程(5666/TCP)
Contact / Contactgroup / Timeperiod 通知接收人、分组;24x7/workhours 时间窗控制检查与通知时段
State / State type OK/WARNING/CRITICAL/UNKNOWN;SOFT(未达重试次数,不发通知)/ HARD(确认故障,触发通知)
max_check_attempts / retry_interval SOFT→HARD 所需连续失败次数 / 软状态重试间隔
Escalation / Dependency 按通知次数升级到更高级联系人 / 上游故障时抑制下游告警
External command file / status.dat /usr/local/nagios/var/rw/nagios.cmd(运行时提交 downtime/ack)/ 状态快照(供 CGI 读取)
$USERn$ resource.cfg 中的宏,最常用 $USER1$ = 插件目录,用于隐藏路径与敏感串

2.2 对象定义 → 插件 → 状态 → 通知 链路

 etc/*.cfg 对象定义 ──载入/编译──▶ Nagios daemon(调度器/reaper)
   hosts/services/commands ──────────────┐
   contacts/timeperiods/resource.cfg     │ fork/exec(或 check_nrpe 经 5666)
                                         ▼
 CGI Web ─读 status.dat ──── 插件 check_* → exit 0/1/2/3 + 文本输出
                                         ▼ 状态判定
      SOFT(重试中) ─max_check_attempts─▶ HARD(确认故障) ─匹配 period/options/contacts
                                         ▼
              notification_commands → 邮件/企微/钉钉/Webhook
                    ▲ escalation(第N次) / dependency(抑制) / downtime(静默)
  1. 对象定义:nagios.cfg 用 cfg_file/cfg_dir 加载 *.cfg;host 与 service 通过 host_name 关联,check_command 引用 define command。
  2. 插件执行:按 check_interval fork 执行 command_line($USER1$/check_http -H $HOSTADDRESS$ $ARG1$);宏 $HOSTADDRESS$、$SERVICESTATE$、$ARGn$ 调用时展开。
  3. 状态判定:退出码映射状态;首次非 OK 为 SOFT,连续 max_check_attempts 次失败才转 HARD;仅 HARD 触发通知。
  4. 通知:contactgroup → contact.notification_commands 执行脚本;*escalation 按通知序号升级;dependency 与 downtime 抑制;向 nagios.cmd 写 [<epoch>] <COMMAND>;<args> 可做停机/确认/强制检查。

2.3 与 Icinga 的差异说明

维度 Nagios Core Icinga 1(已停止维护) Icinga 2(当前主线)
渊源 / 配置 原项目(1999 起)/ 手写 *.cfg 对象定义 Nagios fork,配置兼容 完全重写;自研 DSL(object Host / apply 规则),不兼容 Nagios cfg
分布式 / Web / API 无原生(靠 NRPE/NSCA/NRDP/Mod Gearman)/ 自带陈旧 CGI / 无 API 同左 原生 Master/Satellite/Agent + CA 签发 / Icinga Web 2 / 原生 REST API
性能 / 插件 中小规模够用,海量需调优 / 兼容 Monitoring Plugins 规范 类似 原生多线程、检查负载均衡 / 同样兼容插件规范
迁移 — 配置近零改动 需重写配置,官方提供迁移工具与文档

结论:新项目若看中 Nagios 生态与插件规范但想要现代 UI / 分布式 / API,应直接选 Icinga 2;维护存量 Core 时才继续用 Core。两者共用插件退出码规范,自定义插件可直接复用。

3. 安装与部署

Core 官方以源码编译为主,发行版仓库包名差异大(Debian/Ubuntu 为 nagios4/monitoring-plugins/nagios-nrpe-*,RHEL 系需 EPEL)。版本与下载路径 以 https://www.nagios.org/ 与 https://github.com/NagiosEnterprises/nagioscore/releases 最新稳定版为准;<version>、<tag> 为占位符。

3.1 环境准备

项 要求
编译依赖 gcc、make、autoconf、gettext、libgd-dev(状态图)、openssl、unzip、wget
Web / 账号 Apache + PHP + mod_cgi/mod_rewrite(make install-webconf 生成 vhost);系统用户 nagios、命令组 nagcmd(Web 用户 apache/www-data 需加入以写 nagios.cmd)
端口 80/443(CGI Web)、5666/TCP(NRPE)、5667/TCP(NSCA 被动结果,可选)、SNMP 161/UDP
数据库 / 时间 不需要(纯文本状态);全节点 NTP 同步(downtime 与外部命令时间戳依赖时钟)

3.2 多种安装方式

A. 源码编译(官方标准方式):

# 1) 依赖(Ubuntu/Debian;RHEL 用 dnf install gcc glibc glibc-common make gd gd-devel openssl-devel httpd php unzip wget)
apt update && apt install -y autoconf gcc libc6 make wget unzip apache2 php libapache2-mod-php libgd-dev openssl libssl-dev
# 2) 账号与命令组
useradd -m -s /bin/bash nagios && groupadd nagcmd
usermod -aG nagcmd nagios && usermod -aG nagcmd www-data      # RHEL 换成 apache
# 3) 编译 Core(tarball 名称以官方 releases 页为准)
cd /tmp && wget https://github.com/NagiosEnterprises/nagioscore/archive/nagios-<version>.tar.gz
tar xzf nagios-<version>.tar.gz && cd nagioscore-*/
./configure --with-command-group=nagcmd --with-httpd-conf=/etc/apache2/sites-enabled
make -j"$(nproc)" all
make install && make install-init && make install-commandmode && make install-config
make install-webconf && make install-daemoninit && a2enmod rewrite cgi && systemctl restart apache2
htpasswd -c /usr/local/nagios/etc/htpasswd.users nagiosadmin
# 4) 官方插件(落到 /usr/local/nagios/libexec/)
wget https://github.com/nagios-plugins/nagios-plugins/archive/release-<version>.tar.gz
tar xzf release-<version>.tar.gz && cd nagios-plugins-release-*/
./tools/setup && ./configure --with-nagios-user=nagios --with-nagios-group=nagios && make -j"$(nproc)" && make install
apt install -y nagios-nrpe-plugin      # 提供 check_nrpe;RHEL 包名以 EPEL 为准
# 5) 被管机装 NRPE:apt install -y nagios-nrpe-server monitoring-plugins

B. 发行版包(快速体验):

# Debian/Ubuntu:配置在 /etc/nagios4/ 或 /etc/nagios/,插件在 /usr/lib/nagios/plugins
apt install -y nagios4 monitoring-plugins nagios-nrpe-plugin nagios-nrpe-server
# RHEL 系需先启用 EPEL,包名以仓库实际为准(如 nagios、nagios-plugins-all、nrpe)
dnf install -y epel-release && dnf install -y nagios nagios-plugins-all nrpe nagios-plugins-nrpe

⚠️ 包安装与源码安装的配置根路径不同(/etc/nagios* vs /usr/local/nagios/etc),下文按源码安装路径书写,包安装需替换路径。

C. Docker(自建镜像,避免依赖第三方 tag):写 Dockerfile(FROM ubuntu:<tag>,安装上表依赖后按 A 步骤编译并 make install*),再 docker build -t nagios-core:<tag> . && docker run -d -p 8080:80 --name nagios nagios-core:<tag>;容器内用 service apache2 start && /usr/local/nagios/bin/nagios -d /usr/local/nagios/etc/nagios.cfg 启动,暴露 80/5666。基础镜像 tag 以所用发行版官方仓库为准。

3.3 首次启动与验证

/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg    # 1 校验:Warnings/Errors 必须为 0
systemctl enable --now nagios apache2 && systemctl status nagios --no-pager
# 2 Web:http://<host>/nagios ,账号 nagiosadmin + htpasswd 口令
/usr/local/nagios/libexec/check_ping -H 127.0.0.1 -w 100,20% -c 200,40%    # 3 本地插件自测
/usr/local/nagios/libexec/check_nrpe -H <被管机IP> -c check_load           # 4 NRPE 连通性

⚠️ 配置校验未通过前不要 restart,否则守护进程拒绝启动并中断监控。

4. 配置文件详解

路径 作用
/usr/local/nagios/etc/nagios.cfg 主配置:加载哪些 cfg、日志/状态/命令文件路径、全局开关
/usr/local/nagios/etc/objects/*.cfg 对象定义:commands.cfg、contacts.cfg、timeperiods.cfg、templates.cfg、localhost.cfg
resource.cfg / cgi.cfg $USERn$ 资源宏($USER1$=插件目录,权限 600)/ CGI 认证与 authorized_for_* 授权
htpasswd.users / libexec/ Apache Basic 认证口令文件 / 插件目录
var/ nagios.log、status.dat、objects.cache、retention.dat、archives/、rw/nagios.cmd(外部命令 FIFO,属组 nagcmd)
/etc/nagios/nrpe.cfg(被管机) allowed_hosts、command[...]、dont_blame_nrpe

nagios.cfg 关键项说明表:

参数 说明
cfg_file / cfg_dir 单个对象文件 / 目录(递归加载 *.cfg),批量纳管靠 cfg_dir
log_file / log_rotation_method / log_archive_path 主日志路径、按日/周/月轮转、归档目录
status_file / object_cache_file / state_retention_file status.dat / objects.cache / retention.dat
command_file / check_external_commands 外部命令文件路径;必须为 1 才能提交 downtime/ack
resource_file / nagios_user / nagios_group 指向 resource.cfg;守护进程运行身份
interval_length 时间单位秒数(默认 60,check_interval=5 即 5 分钟)
service_check_timeout / host_check_timeout / notification_timeout 各类超时,插件卡住时兜底
max_concurrent_checks / check_result_buffer_slots / reaper_interval 并发检查数、结果缓冲槽、回收间隔(大规模调优)
enable_notifications / execute_service_checks / accept_passive_service_checks 全局开关(0=全局关闭)
use_large_installation_tweaks / date_format / illegal_macro_output_chars 大规模内核调优;日期格式;宏中需转义的危险字符

对象定义语法:define <类型>{ 指令=值 ... },use 继承模板,; 为注释,check_command 用 ! 分隔参数(对应 $ARG1$、$ARG2$)。类型:host、service、command、contact、contactgroup、hostgroup、servicegroup、timeperiod、hostescalation、serviceescalation、hostdependency、servicedependency。

nagios.cfg 最小片段:

cfg_file=/usr/local/nagios/etc/objects/commands.cfg
cfg_file=/usr/local/nagios/etc/objects/contacts.cfg
cfg_file=/usr/local/nagios/etc/objects/timeperiods.cfg
cfg_file=/usr/local/nagios/etc/objects/templates.cfg
cfg_dir=/usr/local/nagios/etc/servers
resource_file=/usr/local/nagios/etc/resource.cfg
log_file=/usr/local/nagios/var/nagios.log
status_file=/usr/local/nagios/var/status.dat
object_cache_file=/usr/local/nagios/var/objects.cache
state_retention_file=/usr/local/nagios/var/retention.dat
command_file=/usr/local/nagios/var/rw/nagios.cmd
check_external_commands=1
nagios_user=nagios
nagios_group=nagios
interval_length=60
enable_notifications=1
service_check_timeout=60

objects/commands.cfg + contacts.cfg + timeperiods.cfg + servers/linux-hosts.cfg(objects 定义文件完整示例):

# ---- commands.cfg ----
define command{ command_name check-host-alive ; command_line $USER1$/check_ping -H $HOSTADDRESS$ -w 3000.0,80% -c 5000.0,100% -p 5 }
define command{ command_name check_http_url ; command_line $USER1$/check_http -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$ }
define command{ command_name check_nrpe ; command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$ }
define command{ command_name notify-service-by-email
  command_line /usr/bin/printf "%b" "Service: $SERVICEDESC$ Host: $HOSTNAME$ State: $SERVICESTATE$ Info: $SERVICEOUTPUT$\n" | /usr/bin/mail -s "** $NOTIFICATIONTYPE$ $HOSTNAME$ $SERVICESTATE$ **" $CONTACTEMAIL$ }
define command{ command_name notify-host-by-email
  command_line /usr/bin/printf "%b" "Host $HOSTNAME$ is $HOSTSTATE$" | /usr/bin/mail -s "Host $HOSTSTATE$: $HOSTNAME$" $CONTACTEMAIL$ }
# ---- contacts.cfg / timeperiods.cfg ----
define contact{ contact_name ops ; alias 运维值班
  service_notification_period 24x7 ; host_notification_period 24x7
  service_notification_options w,u,c,r,f ; host_notification_options d,u,r,f
  service_notification_commands notify-service-by-email ; host_notification_commands notify-host-by-email
  email ops@<域名> }
define contactgroup{ contactgroup_name ops-group ; members ops }
define timeperiod{ timeperiod_name 24x7 ; alias 24x7
  sunday 00:00-24:00 ; monday 00:00-24:00 ; tuesday 00:00-24:00 ; wednesday 00:00-24:00
  thursday 00:00-24:00 ; friday 00:00-24:00 ; saturday 00:00-24:00 }
# ---- servers/linux-hosts.cfg ----
define host{ use linux-server ; host_name web01 ; alias Web服务器01 ; address <ip>
  hostgroups linux-servers ; max_check_attempts 3 ; check_period 24x7
  notification_interval 30 ; notification_period 24x7 ; contact_groups ops-group }
define service{ use generic-service ; host_name web01 ; service_description HTTP
  check_command check_http_url!2!5 ; max_check_attempts 3 ; normal_check_interval 5
  retry_check_interval 1 ; notification_interval 30 ; contact_groups ops-group }
define service{ use generic-service ; host_name web01 ; service_description "Disk /"
  check_command check_nrpe!check_disk }
define serviceescalation{ host_name web01 ; service_description HTTP
  first_notification 3 ; last_notification 0 ; notification_interval 10
  escalation_period 24x7 ; escalation_options w,c,r ; contact_groups oncall-manager }

resource.cfg 中定义 $USER1$=/usr/local/nagios/libexec(包安装改为 /usr/lib/nagios/plugins);改完必须 nagios -v 校验再 reload。

5. 核心使用方法

插件命令行(退出码 0 OK / 1 WARNING / 2 CRITICAL / 3 UNKNOWN;§5 命令合计 ≥20 条):

P=/usr/local/nagios/libexec
$P/check_ping  -H <ip> -w 100,20% -c 200,40% -p 5                 # 1 存活+丢包/延迟
$P/check_http  -H <host> -w 2 -c 5                                  # 2 HTTP 响应时间
$P/check_http  -H <host> -S -p 443 -N -e 'HTTP/1.1 200'            # 3 HTTPS + 校正文
$P/check_tcp   -H <ip> -p 3306 -w 2 -c 5                            # 4 端口连通
$P/check_ssh   -H <ip>                                              # 5 SSH
$P/check_disk  -w 20% -c 10% -p /                                   # 6 磁盘剩余百分比
$P/check_load  -w 5,4,3 -c 10,8,6                                   # 7 负载
$P/check_procs -c 1: -C nginx                                       # 8 进程数下限
$P/check_swap  -w 20% -c 10%                                        # 9 swap
$P/check_users -w 10 -c 20                                          # 10 登录用户数
$P/check_snmp  -H <ip> -C <community> -o <OID> -w <w> -c <c>       # 11 SNMP
$P/check_nrpe  -H <ip> -c check_disk                                # 12 远端 NRPE 检查
$P/check_nrpe  -H <ip> -c check_load -a '-w 5,4,3 -c 10,8,6'        # 13 NRPE 传参(需 dont_blame_nrpe=1)
$P/check_nrpe  -H <ip>                                              # 14 NRPE 握手/版本
$P/check_nagios -F /usr/local/nagios/var/status.dat -e 5 -t 30      # 15 自监控守护进程新鲜度
$P/check_disk --help ; echo $?                                      # 16 查看参数 / 17 读退出码
printf 'OK - queue=3 | queue=3;10;20;0;100\n'; exit 0               # 18 带 perfdata 的自定义输出
printf 'CRITICAL - queue=25 | queue=25;10;20;0;100\n'; exit 2        # 19 模拟故障
/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg     # 20 校验配置
/usr/local/nagios/bin/nagiostats -c /usr/local/nagios/etc/nagios.cfg # 21 检查统计/延迟
systemctl start|stop|restart|reload|status nagios                    # 22 服务管理
tail -f /usr/local/nagios/var/nagios.log                             # 23 实时日志
grep -c '^define host{' /usr/local/nagios/etc/servers/*.cfg           # 24 统计主机对象数

| 之后为性能数据(供 PNP4Nagios/Grafana 采集),格式 'label=value[UOM];warn;crit;min;max';⚠️ 插件输出不能含未转义的 |、'、" 等字符(illegal_macro_output_chars)。

NRPE 配置(被管机 /etc/nagios/nrpe.cfg):

server_port=5666
nrpe_user=nagios
nrpe_group=nagios
allowed_hosts=127.0.0.1,::1,<NAGIOS_SERVER_IP>     # 白名单,⚠️ 不要写 0.0.0.0
dont_blame_nrpe=0                                   # 0=禁止中心侧传参(安全默认)
command[check_users]=/usr/lib/nagios/plugins/check_users -w 5 -c 10
command[check_load]=/usr/lib/nagios/plugins/check_load -w 5,4,3 -c 10,8,6
command[check_disk]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /
command[check_biz_queue]=/usr/local/bin/check_biz_queue.sh -w 10 -c 20
systemctl enable --now nagios-nrpe-server     # Debian/Ubuntu 服务名;RHEL 为 nrpe
ss -lntp | grep 5666                          # 验证监听;中心侧 check_nrpe -H <ip> -c check_disk

⚠️ 开启 dont_blame_nrpe=1 允许中心传 -a 参数,等于把任意命令执行能力暴露给中心,必须配合 allowed_hosts 与最小权限插件;生产建议保持 0,阈值固化在 command[...] 里。

外部命令文件(格式 [<epoch>] <COMMAND>;<arg1>;...):

CMD=/usr/local/nagios/var/rw/nagios.cmd; T=$(date +%s)
printf '[%s] SCHEDULE_FORCED_SVC_CHECK;web01;HTTP;%s\n' "$T" "$T" > $CMD   # 强制立即检查
printf '[%s] DISABLE_SVC_NOTIFICATIONS;web01;HTTP\n' "$T" > $CMD           # 关闭某服务通知
printf '[%s] ACKNOWLEDGE_SVC_PROBLEM;web01;HTTP;2;1;1;ops;处理中\n' "$T" > $CMD  # 确认告警
printf '[%s] SCHEDULE_SVC_DOWNTIME;web01;HTTP;%s;%s;1;0;0;ops;维护\n' "$T" "$T" "$((T+3600))" > $CMD  # 计划停机
printf '[%s] DISABLE_NOTIFICATIONS\n' "$T" > $CMD                          # 全局静默

nagios.cfg → check_external_commands=1 且 nagios.cmd 属组 nagcmd、Web 用户在组内,否则命令被静默丢弃。

Web UI 操作路径:Tactical Overview(tac.cgi)、Hosts/Services(status.cgi)、Problems(status.cgi?host=all&servicestatustypes=28)、详情页「Schedule downtime / Acknowledge」表单(写 nagios.cmd)、Reports → Availability、Configuration → Object browser(config.cgi,需 authorized_for_configuration_information)、Process Info(extinfo.cgi?type=0,可启停全局通知)。

6. 告警与通知

机制 说明
notification_commands 普通可执行脚本,宏 $HOSTSTATE$/$SERVICESTATE$/$SERVICEOUTPUT$/$NOTIFICATIONTYPE$/$CONTACTEMAIL$ 传参
通知条件 notification_period、notification_options(w/u/c/r/f、d/u/r/f/s)、notification_interval、contactgroup 关联
告警升级 *escalation:first_notification~`last_notification、escalation_options、更小 notification_interval`、升级 contactgroup
抑制 / 维护期 hostdependency/servicedependency(上游 CRITICAL 时下游不发通知)、downtime、ack;Core 无「维护期对象」,用 SCHEDULE_*_DOWNTIME 外部命令或 Web 表单设置固定/弹性停机

邮件通知:见 §4 notify-*-by-email(依赖本机 mail/postfix)。企业微信 / 钉钉 Webhook 通知脚本:

#!/usr/bin/env bash
# /usr/local/nagios/libexec/notify-wechat.sh <通知类型> <主机> <服务> <状态> <详情>
set -euo pipefail
TYPE="$1"; HOST="$2"; SVC="$3"; STATE="$4"; INFO="$5"
KEY='<企业微信机器人 key>'   # 地址以企业实际创建结果为准
curl -sS -X POST -H 'Content-Type: application/json' \
  --data "$(jq -n --arg t "$TYPE" --arg h "$HOST" --arg s "$SVC" --arg st "$STATE" --arg i "$INFO" \
     '{msgtype:"text",text:{content:("[Nagios "+ $t +"] "+ $h +"/"+ $s +" = "+ $st +"\n"+ $i)}}')" \
  "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${KEY}"
define command{ command_name notify-service-by-wechat
  command_line $USER1$/notify-wechat.sh "$NOTIFICATIONTYPE$" "$HOSTNAME$" "$SERVICEDESC$" "$SERVICESTATE$" "$SERVICEOUTPUT$" }

钉钉把 URL 换成 https://oapi.dingtalk.com/robot/send?access_token=<TOKEN> 并用 msgtype:markdown;通用做法是把 $CONTACTPAGER$ 当作 URL 存入 contact,脚本 curl -X POST "$URL",便于按联系人分流到不同群。⚠️ 通知脚本以 nagios 低权限运行,禁止 eval 宏内容(宏来自插件输出,可能含注入字符)。

7. 实战场景

场景一:批量纳管 100 台主机(cfg_dir + 脚本生成对象定义)

目标:从主机清单批量生成 define host + 通用 define service,一次校验后 reload 生效。

CSV=hosts.csv                     # hostname,ip,group  如 web01,10.0.1.11,linux-servers
DIR=/usr/local/nagios/etc/servers && mkdir -p "$DIR"
while IFS=, read -r H IP G; do
  [ "$H" = "hostname" ] && continue
  cat > "$DIR/$H.cfg" <<EOF
define host{
  use linux-server ; host_name $H ; alias $H ; address $IP ; hostgroups $G
  max_check_attempts 3 ; notification_interval 30 ; notification_period 24x7 ; contact_groups ops-group
}
define service{ use generic-service ; host_name $H ; service_description PING
  check_command check-host-alive ; contact_groups ops-group }
define service{ use generic-service ; host_name $H ; service_description "Disk /"
  check_command check_nrpe!check_disk ; contact_groups ops-group }
EOF
done < "$CSV"
/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg    # 必须 0 warnings / 0 errors
systemctl reload nagios

验证:Web Hosts 数量、nagiostats 活跃检查数、check_nrpe -H <ip> -c check_disk 抽查。 回滚:rm "$DIR"/<hostname>.cfg 后重新 -v 校验并 reload;⚠️ 先备份 $DIR。 前置:nagios.cfg 含 cfg_dir=.../servers,templates.cfg 有 linux-server/generic-service,hostgroups 已定义。

场景二:自定义监控项(业务队列积压 + 阈值告警)

目标:写自定义插件采集队列长度,>10 WARNING、>20 CRITICAL,经 NRPE 纳管。

# 1) 被管机插件:/usr/local/bin/check_biz_queue.sh
cat > /usr/local/bin/check_biz_queue.sh <<'EOF'
#!/usr/bin/env bash
Q=$(cat /var/run/biz/queue.depth 2>/dev/null || echo -1); W=10; C=20
if [ "$Q" -lt 0 ]; then printf 'UNKNOWN - cannot read queue | queue=%s\n' "$Q"; exit 3; fi
if [ "$Q" -ge "$C" ]; then printf 'CRITICAL - queue=%d | queue=%d;%d;%d;0;1000\n' "$Q" "$Q" "$W" "$C"; exit 2; fi
if [ "$Q" -ge "$W" ]; then printf 'WARNING - queue=%d | queue=%d;%d;%d;0;1000\n' "$Q" "$Q" "$W" "$C"; exit 1; fi
printf 'OK - queue=%d | queue=%d;%d;%d;0;1000\n' "$Q" "$Q" "$W" "$C"; exit 0
EOF
chmod 755 /usr/local/bin/check_biz_queue.sh
printf '\ncommand[check_biz_queue]=/usr/local/bin/check_biz_queue.sh\n' >> /etc/nagios/nrpe.cfg
systemctl restart nagios-nrpe-server
/usr/local/nagios/libexec/check_nrpe -H <被管机IP> -c check_biz_queue    # 3 中心侧验证
define service{ use generic-service ; host_name web01 ; service_description 业务队列积压
  check_command check_nrpe!check_biz_queue
  max_check_attempts 3 ; normal_check_interval 1 ; notification_options w,c,r ; contact_groups ops-group }
/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg && systemctl reload nagios
echo 25 > /var/run/biz/queue.depth     # 制造 CRITICAL 验证告警

验证:check_nrpe 返回带 perfdata 的输出;Web Services 出现新服务;写队列深度后转 CRITICAL 并发通知。 回滚:删除该 define service、注释 command[check_biz_queue]、重启 NRPE 与 reload Core;插件文件可保留。

场景三:告警升级与维护期静默

目标:HTTP 前 2 次通知发值班组,第 3 次起每 10 分钟发主管,直到恢复;计划维护不发告警。

define contactgroup{ contactgroup_name oncall-manager ; members manager }
define serviceescalation{ host_name web01 ; service_description HTTP
  first_notification 3 ; last_notification 0 ; notification_interval 10
  escalation_period 24x7 ; escalation_options c,r ; contact_groups oncall-manager }
define servicedependency{ host_name core-switch01 ; service_description PING
  dependent_host_name web01 ; dependent_service_description HTTP
  execution_failure_criteria n ; notification_failure_criteria w,u,c }
/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg && systemctl reload nagios
T=$(date +%s); CMD=/usr/local/nagios/var/rw/nagios.cmd
printf '[%s] SCHEDULE_SVC_DOWNTIME;web01;HTTP;%s;%s;1;0;0;ops;割接窗口\n' "$T" "$T" "$((T+7200))" > $CMD
grep -i 'DOWNTIME ALERT\|SERVICE NOTIFICATION' /usr/local/nagios/var/nagios.log

验证:日志出现 SERVICE NOTIFICATION 且第 3 条指向 manager;停机期间无通知。 回滚:删除 escalation/dependency 定义并 reload;DEL_SVC_DOWNTIME 外部命令可提前结束停机。

8. 日常运维与故障排查

systemctl status nagios apache2 --no-pager && systemctl reload nagios
/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg        # 任何改配置后必做
/usr/local/nagios/bin/nagiostats -c /usr/local/nagios/etc/nagios.cfg    # 检查延迟/并发/缓冲
grep -E 'SERVICE ALERT|HOST ALERT|SERVICE NOTIFICATION' /usr/local/nagios/var/nagios.log
ls -l /usr/local/nagios/var/rw/nagios.cmd                               # 外部命令文件权限
现象 原因 处置
-v 报 Unexpected token / 对象未定义 少 }、指令拼错、use 模板不存在、check_command 未定义 按报错行号修 cfg,补齐模板/命令,再校验
服务 UNKNOWN / (No output returned from plugin) 插件路径错、$USER1$ 未定义、无执行权限、超时 ls -l $USER1$/check_*,手动跑插件,调大 service_check_timeout
CHECK_NRPE: Error - Could not complete SSL handshake 两端 NRPE SSL 编译选项/版本不一致 统一版本或都关 SSL;核对 allowed_hosts
CHECK_NRPE: Received 0 bytes from daemon NRPE 未启动、防火墙 5666 未放、allowed_hosts 不含中心 IP ss -lntp|grep 5666、放行端口、加白名单后重启
NRPE -a 传参不生效 / Request contained command arguments dont_blame_nrpe=0 保持 0 并把阈值固化到 command[...];确需传参再开 1(⚠️ 高危)
故障发生但通知迟迟不来 SOFT 状态未耗尽 max_check_attempts、notification_period/options 不匹配、enable_notifications=0、contactgroup 没关联 逐项核对对象定义与日志的 NOTIFICATION 行
外部命令(downtime/ack)无效果 check_external_commands=0、nagios.cmd 权限/属组不对、时间戳格式错 置 1、chgrp nagcmd + 660、用 [<epoch>] COMMAND;args 格式
Web 空白或 403 CGI 未启用、cgi.cfg 授权不足、htpasswd 用户未列入 authorized_for_* a2enmod cgi,配 use_authentication=1 与授权,重启 apache
⚠️ 重启后状态全丢 未启用状态保留或 retention.dat 被清 配 state_retention_file、retention_update_interval,勿手工删 var 目录

9. 性能、容量与高可用

规模估算:Core 无数据库,开销主要来自 fork/exec 插件。每秒检查数 ≈ (主机数×主机频率 + 服务数×服务频率)/60;经验上单机数百台 × 数十服务可行,上千台需调优并把重检查分散。用 nagiostats 观察 Service Check Latency、Check Result Buffer Slots 与近 5/15/60 分钟活跃检查,延迟持续 >30s 说明调度饱和。

调优项 说明
max_concurrent_checks=0 0=自动,大规模可显式设较大值
check_result_buffer_slots 结果缓冲槽,突发检查时避免丢失
use_large_installation_tweaks=1 减少 fork 开销、合并缓存写,大规模推荐
service_check_timeout / host_check_timeout 插件超时兜底,避免慢插件拖垮调度
enable_embedded_perl / use_embedded_perl_implicitly ePN 加速 Perl 插件(有兼容代价,谨慎)
check_for_orphaned_services / orphan_check_interval 回收异常检查结果

分布式:Core 无原生 Proxy。远程检查靠 NRPE(中心主动拉)、NSCA/NRDP(远端被动上报,适合防火墙单向)、SNMP Trap;社区常用 Mod Gearman / DNX 做检查负载分担;规模化时按机房拆 cfg_dir、多实例 + 汇总视图。 高可用:无原生 HA。常见做法是主备双机共享配置(rsync/Git)+ 各自本地状态,keepalived 漂移 VIP;⚠️ 主备会各自发通知,需在备机 enable_notifications=0 或联动脚本切换;商业版 Nagios XI 提供官方 HA。 自监控:check_nagios -F /usr/local/nagios/var/status.dat -e 5 -t 30(守护进程新鲜度)、nagiostats、监控 nagios.log 写入与 nagios.cmd 可写性;把 Core 自身也定义成 host,检查 PING + check_nagios。

10. 安全加固、备份与升级

认证鉴权:cgi.cfg 设 use_authentication=1,按 authorized_for_system_information/configuration_information/all_services/all_hosts/system_commands 分配最小 CGI 权限;htpasswd.users 权限 640;Web 强制 HTTPS;resource.cfg 权限 600(内含 $USERn$ 敏感串,如 SNMP community)。 NRPE 与最小权限:allowed_hosts 精确白名单;dont_blame_nrpe=0;command[...] 用绝对路径、不接中心侧任意参数;确需特权检查时用 sudoers 精确到单条命令(如 nagios ALL=(root) NOPASSWD: /usr/lib/nagios/plugins/check_raid),⚠️ 禁止通配 sudo;nrpe_user=nagios 低权限;nagios.cmd 属组 nagcmd。 插件安全:illegal_macro_output_chars 转义宏中危险字符;通知脚本不 eval 宏;自定义插件校验所有外部输入(宏来自插件输出,可能含注入)。

备份与恢复:

tar czf /backup/nagios-$(date +%F).tgz /usr/local/nagios/etc /usr/local/nagios/libexec /usr/local/nagios/var/archives
systemctl stop nagios
tar xzf /backup/nagios-<日期>.tgz -C /
chown -R nagios:nagios /usr/local/nagios && chgrp nagcmd /usr/local/nagios/var/rw/nagios.cmd
/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg && systemctl start nagios

⚠️ 不要直接编辑/删除 status.dat、retention.dat、objects.cache(运行时产物);var/rw/ 权限误改会导致外部命令全部失效。 跨大版本升级:大版本间对象定义指令可能增改。顺序:全量备份 etc + 自定义 libexec 插件 → 测试机编译新版本 → 用新 nagios -v 逐条修 cfg → 停旧服务 → make install 覆盖二进制(勿覆盖 etc)→ 校验 → 启动 → 观察日志;包安装走 apt/dnf upgrade 但同样先备份 /etc/nagios*。回滚:恢复备份的 etc + 旧版二进制,⚠️ 不要只降级 RPM 却保留新版配置。具体变更以官方 release notes 为准。

11. 常见坑(现象 → 原因 → 解决)

现象 原因 解决
-v 报 Host name 'x' specified more than once 同名 host 在多个 cfg 重复定义 grep -rn 'host_name.*x' 去重,一台主机只定义一次
check_command 参数不生效 参数用 ! 分隔却写成空格;$ARG1$ 未引用 写 check_http_url!2!5,command_line 用 $ARG1$ $ARG2$
$USER1$ 展开为空 / 插件找不到 resource.cfg 未定义或写成发行版包路径 定义 $USER1$=/usr/local/nagios/libexec,核对 resource_file
服务定义了却不出现在 Web host_name 大小写不一致、模板未加载、cfg 未被 cfg_dir 包含 统一名称,确认 cfg_file/cfg_dir 与 objects.cache 对象数
NRPE Socket timeout / 0 bytes 防火墙 5666、allowed_hosts 未含中心 IP、未监听 放行端口、加白名单、ss -lntp 核对后重启
通知总在凌晨发、或不发 notification_period=workhours / notification_options 缺 r(recovery) 或 f(flapping) 统一 24x7 并补齐 w,u,c,r,核对 contactgroups
告警风暴(上游交换机挂,全部服务报警) 缺 servicedependency/hostdependency 定义依赖,notification_failure_criteria 覆盖上游状态
SOFT 状态反复却不通知,误以为漏报 未达 max_check_attempts 或 retry_interval 过长 调小次数/间隔,理解 SOFT→HARD 状态机
外部命令写了没反应 check_external_commands=0、时间戳不是 epoch、少分号、权限不对 置 1、用 date +%s、严格 [epoch] CMD;a;b、检查属组
⚠️ dont_blame_nrpe=1 + command[...] 拼接参数 等价于允许中心远程执行任意命令 保持 0;必须传参时用固定命令 + 严格白名单 + 低权限 sudoers
⚠️ 直接改 status.dat / 删 var/ 目录 破坏运行时状态,外部命令失效 只改 etc,运行时产物交给守护进程管理
⚠️ 生产直接覆盖编译新版不先 -v 新版本指令不兼容导致守护进程起不来 测试机校验 → 备份 → 灰度 → 启动

12. 速查表

类别 项 值 / 命令
命令 校验配置 /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg
命令 统计/延迟 /usr/local/nagios/bin/nagiostats -c /usr/local/nagios/etc/nagios.cfg
命令 服务管理 / 前台调试 systemctl start|stop|restart|reload|status nagios / nagios <nagios.cfg>
命令 插件自测 / NRPE $USER1$/check_http -H <host> -w 2 -c 5 / $USER1$/check_nrpe -H <ip> -c check_disk
命令 外部命令 printf '[<epoch>] SCHEDULE_FORCED_SVC_CHECK;h;s;<epoch>\n' > .../rw/nagios.cmd
配置 主配置 / 对象目录 /usr/local/nagios/etc/nagios.cfg / objects/*.cfg、servers/*.cfg
配置 资源宏 / CGI 授权 / 认证 resource.cfg / cgi.cfg / htpasswd.users
配置 插件目录 / 日志 /usr/local/nagios/libexec/ / /usr/local/nagios/var/nagios.log
配置 NRPE 配置(被管机) /etc/nagios/nrpe.cfg
端口 Web / NRPE / NSCA 80,443 / 5666/TCP / 5667/TCP
状态 插件退出码 0 OK、1 WARNING、2 CRITICAL、3 UNKNOWN
对象 常用 define host、service、command、contact、timeperiod、*escalation、*dependency
宏 参数/主机/状态 $ARG1$、$HOSTADDRESS$、$HOSTNAME$、$SERVICESTATE$、$SERVICEOUTPUT$、$USER1$
语法 参数分隔 / perfdata check_command check_http_url!2!5 / `OK - x=3
Web 入口 / CGI http://<host>/nagios(nagiosadmin)/ tac.cgi、status.cgi、extinfo.cgi、config.cgi
默认账号 初始 nagiosadmin(htpasswd -c 创建,⚠️ 立即设强口令)

13. 选型建议与同类对比

维度 Nagios Core Zabbix Prometheus Checkmk Icinga 2
定位 轻量状态检查框架 全栈一体化监控 云原生指标 + 时序 规则驱动、自动发现强 Nagios 精神续作、分布式
数据模型 Host/Service 状态 Host/Item + 关系库历史 时序 + label Host/Service/Check + 规则集 自研 DSL 对象
采集 插件 + NRPE/NSCA Agent(2)/SNMP/JMX/Proxy Pull + exporter Agent(6556)/SNMP 原生 Agent + 插件
配置 手写 *.cfg 对象定义 模板 + 宏 + LLD + UI/API 配置文件 + 服务发现 规则集 + WATO/Setup DSL + Director/API
告警 escalation + dependency + downtime 表达式/升级/抑制/维护期 Alertmanager 内置规则 + 通知规则 原生 Notification + API
可视化 / 分布式 自带 CGI(陈旧)/ 无原生 内置 Dashboard / 原生 Proxy + HA Grafana / 联邦 内置视图 / 原生分布式站点 Icinga Web 2 / 原生 Master-Satellite
数据库 / 许可 无 / GPLv2 强依赖 / AGPLv3(7.0+) 自带 TSDB / Apache-2.0 无(RRD)/ GPLv2(Raw) 可选 IDO / GPLv2
学习曲线 / 规模 低 / 小到中 中 / 中到超大 中 / 中到大 中低 / 中到大 中 / 中到大

何时选 Nagios Core:已有大量存量 *.cfg 与自定义插件要维护;环境很小、只做「通不通 / 超没超阈值」;资源极其紧张、不能跑数据库;需要纯文本配置全量进 Git、禁止 Web 写配置;团队熟悉插件规范且愿意自己工程化批量生成配置。 何时不选:需要历史趋势、容量报表与开箱即用图形(Zabbix / Prometheus + Grafana);需要自动发现与规则化批量配置(Checkmk / Icinga 2 Director);需要原生分布式、REST API、现代 Web(Icinga 2);纯 K8s 云原生(Prometheus)。从零起步又喜欢 Nagios 插件生态,优先评估 Icinga 2。

14. 参考链接

Nagios Core —— 以「对象定义 + 插件退出码」为核心的轻量状态监控框架 - 知识库 - 起航社区