Nagios Core —— 以「对象定义 + 插件退出码」为核心的轻量状态监控框架
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(静默)
- 对象定义:
nagios.cfg用cfg_file/cfg_dir加载*.cfg;host 与 service 通过host_name关联,check_command引用define command。 - 插件执行:按
check_intervalfork 执行command_line($USER1$/check_http -H $HOSTADDRESS$ $ARG1$);宏$HOSTADDRESS$、$SERVICESTATE$、$ARGn$调用时展开。 - 状态判定:退出码映射状态;首次非 OK 为 SOFT,连续
max_check_attempts次失败才转 HARD;仅 HARD 触发通知。 - 通知:
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 官网:https://www.nagios.org/
- Nagios Core 源码仓库:https://github.com/NagiosEnterprises/nagioscore
- NRPE 源码仓库:https://github.com/NagiosEnterprises/nrpe
- 官方插件仓库:https://github.com/nagios-plugins/nagios-plugins
- Icinga 官网:https://icinga.com/
- Icinga 2 源码仓库:https://github.com/Icinga/icinga2