Nagios-指南第二版-全-
Nagios 指南第二版(全)
原文:Nagios, 2nd Edition
译者:飞龙
引言
周一早上十点钟。分支机构老板怒火中烧。他已经等了几个小时,等待一封重要的电子邮件,但它仍然没有到达。这一定是邮件服务器的错;它可能又出故障了。但快速检查电脑显示,那里没有邮件在队列中,日志文件中也没有提到相关发件人的邮件已到达。那么问题出在哪里?
公司的核心邮件服务器对ping无响应。这可能是问题的根源。但公司总部 IT 部门坚决否认责任。它也无法 ping 通分支机构的邮件节点,但它坚持认为总部网络运行正常,因此问题一定出在分支机构网络。错误搜索仍在继续...
令人羞愧的结果:连接到总部的 VPN 连接已中断,尽管 ISDN 备份连接正在工作,但在备份路由器中并未定义通往总部(以及中央邮件服务器)的路由。一个全球运营的 IT 服务提供商负责分支机构与总部之间的网络连接(VPN 和 ISDN),对于他们来说,类似的事情“根本就不会发生”。最终结果:花费数小时寻找错误,一个愤怒的老板(紧急需要的会议早已结束),以及一个满头大汗的管理员。
在一个正确配置的 Nagios 系统中,管理员会在早上八点就已经注意到问题,并在几分钟内就能找出其根源。这样一来,就不会浪费宝贵的时间,可以直接通知 IT 服务提供商。消除错误(在这个案例中,半小时)所需的时间足以及时发送电子邮件。
第二个例子:在德国某地,存储医院中央 Oracle 数据库日志文件的那个硬盘已达到满容量。尽管这不会导致手术室“灯火管制”,但数据库停止工作,工作流程受到很大干扰:患者无法入院,检查结果无法保存,报告无法记录,直到问题得到解决。
如果关键的硬盘驱动器被 Nagios 监控,IT 部门会在早期阶段收到警告。问题甚至可能根本就不会发生。
随着人力资源越来越稀缺,没有任何 IT 部门真的能负担得起定期手动检查所有系统。尤其是日益复杂的网络,特别需要提前了解已发生的故障或即将发生的问题。Nagios,一个开源的系统和网络监控工具,帮助管理员在电话铃响之前发现问题。
软件的目标是快速通知管理员有关可疑(警告)或关键条件(关键)。什么被视为“可疑”或“关键”由管理员在配置中定义。网页摘要随后通知管理员正常工作的系统和服务的状态,Nagios 用绿色显示,可疑条件(黄色),以及关键情况(红色)。还有可能根据具体服务或系统选择性地通过电子邮件或通过诸如短信之类的呼叫服务通知管理员。
通过专注于交通灯状态(绿色、黄色、红色),Nagios 与显示已过时间图形(例如,在 WAN 接口的负载或整个一天的 CPU)或记录和测量网络流量(特定接口上 HTTP 的比例有多高?)的网络工具不同。Nagios 直接简单地处理是否一切正常的问题。软件在这方面做得很好,不仅限于当前状态,而且也涉及长期时间。
测试
在检查关键主机和服务时,Nagios 区分主机检查和服务检查。主机检查测试一台计算机,在 Nagios 术语中称为主机,以检查其可达性——通常使用简单的ping。服务检查选择性地测试单个网络服务,如 HTTP、SMTP、DNS 等,以及运行中的进程、CPU 负载或日志文件。只要主机上有一个服务可以访问,那么这基本上对该计算机整体有效,因此可以省略这个测试。Nagios 在不规则和必要时执行主机检查,例如,如果监控的主机上没有要监控的服务可以访问。
网络服务的最简单测试是查看相关目标端口是否开放,以及是否有服务在那里监听。但这并不一定意味着,例如,SSH 守护进程确实正在 TCP 端口 22 上运行。因此,Nagios 使用多种服务测试,这些测试要深入几步。例如,对于 SMTP,软件还会测试邮件服务器是否通过“220”输出自我宣布,即所谓的SMTP 问候;而对于 PostgreSQL 数据库,它会检查是否接受 SQL 查询。
Nagios 之所以特别有趣,是因为它考虑了网络拓扑中的依赖关系(如果配置了这样做的话)。如果目标系统只能通过一个刚刚宕机的特定路由器访问,那么 Nagios 会报告目标系统“不可达”,并且不会进一步对其进行主机和服务检查。软件使管理员能够更快地发现实际原因并纠正情况。
信息供应商
Nagios 的强大之处——即使在与其他网络监控工具的比较中——也在于其模块化结构。Nagios 核心不包含单个测试。相反,它使用外部程序进行服务和主机检查,这些程序被称为插件。基本设备已经包含了一些标准插件,用于最重要的应用场景。超出这些范围的特殊需求,如果你具备基本的编程知识,可以通过编写自己的插件来满足。然而,在投入时间开发这些插件之前,首先值得在网上浏览相关邮件列表,^([2]) 因为在这个领域有活跃的活动。可用的插件很多,尤其是在 Nagios Exchange 平台,www.nagiosexchange.org/。
插件是一个简单的程序——通常是 shell 脚本(Bash、Perl 等)——它提供四种可能的状态之一:OK、WARNING、CRITICAL 或(例如,在操作错误的情况下)UNKNOWN。
这意味着在原则上,Nagios 可以测试所有可以电子测量或计数的对象:服务器室中的温度和湿度、降雨量、在不应有人进入的某个房间中的人员存在。只要你能找到一种方法提供可以由计算机评估的测量数据或事件作为信息(例如,使用温度和湿度传感器、红外传感器等),就没有限制。除了标准插件外,本书还相应地介绍了其他免费可用的插件,例如在第二十一章(Chapter 21)中,从第 505 页介绍如何使用插件查询温度和湿度传感器。
^([2]) www.nagios.org/support/mailinglists.php
保持管理员信息更新
Nagios 拥有一个复杂的通知系统。在发送方(即,与主机或服务检查)方面,你可以配置何时通知每个人员组——所谓的联系人组——关于哪些条件或事件(故障、恢复、警告等)。在接收方,你还可以在多个级别上定义对相应消息的处理方式——例如,根据一天中的时间,系统是否应该转发它,或者丢弃该消息。
如果一个特定服务需要每周七天全天候监控,这并不意味着负责的管理员永远不会休息。例如,您可以指示 Nagios 只在周一至周五上午 8 点至下午 5 点之间,每隔两小时通知相关人员。如果负责的管理员在指定的时间内无法解决问题,例如八小时,那么部门负责人应该收到消息。这个过程被称为升级管理。相应的配置在第十二章中有解释。
Nagios 还可以利用自由配置的外部程序进行通知,这样您就可以集成任何喜欢的系统,从电子邮件到短信,甚至是一个管理员可以调用并接收有关错误语音消息的语音服务器。
通过其 Web 接口(第十六章]),尽管面临越来越多的竞争,但它仍然非常受欢迎。一个相对较新但非常强大的替代品是 Cacti^([5]):它具有更广泛的应用范围,可以通过 Web 界面进行配置,并避免了 MRTG 的限制,MRTG 只能同时显示两个测量值,并且不能显示任何负值。另一个有趣的新替代品是 Munin.^([6])
Nagios 本身也可以使用扩展(第十九章图形显示性能数据]) www.bb4.org/
^([4]) www.mrtg.org/
^([5]) www.cacti.net/
^([6]) munin.projects.linpro.no/
关于本书
本书面向希望使用开源工具了解其系统和网络状况的网络管理员。它描述了 Nagios 的 2.x 和 3.0 版本。另一方面,插件有自己的生活,在很大程度上独立于 Nagios,因此不受特定版本的限制。
尽管本书基于使用 Linux 作为 Nagios 计算机的操作系统,但这并不是一个必要条件。大多数描述也适用于其他 Unix 系统,^([7])只需要相应地调整系统特定的细节,例如启动脚本。然而,Nagios 目前尚未在 Windows 上官方运行.^([8])
本书的第一部分主要介绍如何以最简单的方式快速配置 Nagios,尽管这种配置对于许多用途来说已经足够,但仍然需要尽快完成。这就是为什么从第一章到第三章没有对所有选项和功能进行详细描述和处理。这些内容将在书的第二部分进行探讨。
第四章探讨了服务和主机检查的细节,特别是介绍了它们对网络拓扑的依赖性。
第五章描述了 Nagios 实现服务检查和获取其结果的可选方案。
接下来,本书将介绍个别标准插件以及一些额外可免费获取的插件。第六章探讨了直接从 Nagios 主机检查网络协议服务的插件,而第七章总结了需要在被监控机器上安装的插件,并且 Nagios 需要额外的工具来使它们运行。在第八章中介绍了几个辅助插件,这些插件本身不执行任何测试,但会操纵已经建立的结果。
在接下来的两个章节中,介绍了 Nagios 运行远程主机上的本地插件所需的两个工具。第九章描述了 SSH,而第十章介绍了一个专门为 Nagios 开发的守护进程。
无论在何处监控网络,都需要实现 SNMP。第十一章不仅描述了具有 SNMP 功能的插件,而且还详细探讨了协议和 SNMP 世界本身,提供了进行此操作所需的相关背景知识。
第十二章介绍了 Nagios 通知系统,同时也涉及了使用短信进行通知、升级管理以及考虑依赖关系。
外部命令的接口在第十三章中进行了讨论。这构成了其他 Nagios 机制的基础,例如 Nagios 服务检查接受器(NSCA),一种用于传输被动测试结果的客户端-服务器机制,在第十四章第十四章。Nagios 服务检查接受器(NSCA)中进行了介绍。这种用法在两个具体示例中得到了展示——集成syslog-ng和处理 SNMP 陷阱。NSCA 也是分布式监控的要求,在第十五章第十五章。分布式监控中进行了讨论。
书的第三部分致力于如何将提取的信息以图形方式表示。第十六章第十六章。经典 Web 界面详细解释了这是如何工作的以及如何设置,并辅以一些有用的截图。它还解释了一系列参数,这些参数在其他地方几乎没有文档,除了在源代码中。
通过添加外部应用程序,可以扩展 Nagios。NDOUtils 允许将所有 Nagios 对象以数据库驱动的方式存储,并在第十七章第十七章。使用 NDOUtils 的灵活 Web 界面中进行了描述。使用第十八章第十八章。NagVis 中描述的附加组件连接到数据库,您就可以构建一个可以配置远超 Nagios 基本范围的 Web 界面。
尽管在操作中,Nagios 主要关注交通信号灯信号(红-黄-绿),但有一些方法可以评估和表示插件提供的性能数据,这些方法在第十九章第十九章。性能数据的图形显示中进行了详细描述。
本书第四部分致力于特殊应用。网络很少是同质的——也就是说,只配备了 Linux 和其他基于 Unix 的操作系统。因此,第二十章第二十章。监控 Windows 服务器展示了可以用来集成和监控 Windows 系统的工具。
第二十一章第二十一章。监控室温和湿度使用低成本硬件传感器的例子来展示如何简单而有效地监控室温和湿度。
只要插件中存在可以查询集成到插件中的系统状态的机制,Nagios 也可以监控专有商业软件。在第二十二章第二十二章。监控 SAP 系统中,这是使用 SAP-R/3 系统进行描述的。
尽管事件处理在第十四章第十四章。Nagios 服务检查接受器(NSCA)中只是简要概述,但在第二十三章第二十三章。使用 EventDB 处理事件中介绍了一种数据库支持的方法,它提供了更多选择来选择和处理事件,包括与 Nagios 的互连。
本书第五部分探讨了构建自己的插件。第二十四章编写自己的插件探讨了标准插件的一般要求,而第二十五章确定文件和目录大小则通过一个逐步示例展示了如何编写适合发布的自己的插件。第二十六章以 Oracle 的即时客户端为例,演示了如何基于并非真正为此目的而设计的程序构建自己的插件。
附录 A 介绍了两个核心配置文件nagios.cfg和cgi.cfg的所有参数,而附录 B 和附录 C 则专注于一些有用但相对罕见的特性。
专门的附录附录 D 专注于宏,它允许在配置中具有灵活性。
附录 E 略有偏离 Nagios 的核心主题,并演示了单点登录场景也可以用于 Nagios Web 界面的认证。
环境越大,拥有一个强大且反应迅速的 Nagios 系统就越重要。附录 F 提供了一系列建议,而附录 G 则专注于一个特定的工具,即集成到 Nagios 中的 Perl 解释器。
最后,附录 H 简要总结了自 Nagios 2.x 以来所做的所有更改。
^([7]) 例如,*BSD、HP-UX、AIX 和 Solaris;作者不知道有任何 Nagios 版本在 MacOS X 上运行。
^([8]) 然而,关于 Nagios 在 Cygwin 环境中运行的传闻。
关于本书的进一步说明
在本书付印时,Nagios 3.0 即将完成。到本书上市时,可能会有一些修改。有关修改的笔记,以及可能出现的错误,可以在linux.swobspace.net/books/nagios/找到。
感谢信
许多人为本书的成功做出了贡献。首先我要感谢 Dr. Markus Wirtz,是他以评论“那你为什么不写一本 Nagios 的书呢?!”来启动这本书,当时他拒绝接受我的 Nagios 活动作为推迟写另一本书的借口。特别感谢 Patricia Jung,作为德语版的技术编辑,她彻底重写了手稿,并不断地用成千上万的问题来打扰我——这对书的完整性是有好处的,并且最终使读者更容易理解。
当然,没有书中描述的所有工具,这本书也是不可能完成的。特别感谢 Ethan Galstad,作为作者、开发者和维护者,他使 Nagios 成为今天的样子:一个令人敬畏的、极其有用和有帮助的工具,它也满足了高级要求,并且可以依赖一个非常庞大——更重要的是非常活跃——的社区。还要感谢 Ton Voon,他代表所有Nagios 插件开发团队的成员,他与同事们一起管理 Nagios 插件的开发。
我也要感谢那些不仅开发了本书中介绍的所有 Nagios 相关软件,还通过校对和反馈帮助润色和改进本书的人:Matthias Flacke(以check_multi闻名),Jörg Linge(PNP),以及 Steffen Waitz,他校对了第一版,Hendrik Bäcker(npcd),Lars Michelsen,Michael Luebben(NagVis),Gerhard Laußer(check_logfiles),以及 NETWAYS GmbH 的员工(NagiosGrapher,EventDB,交流平台,NagiosExchange)。
我无法列出所有以某种方式为 Nagios 成功做出贡献的个人。因此,我要感谢所有积极支持 Nagios 社区的人,无论是通过免费软件还是通过参与论坛和邮件列表。没有用户,Nagios 会是什么样子?
第一部分。从源代码到运行安装
第一章。安装
最简单的安装方法是安装您所使用发行版提供的 Nagios 软件包。Nagios 2.x 现在已经非常成熟,因此成为大多数发行版的一个组件。Linux 发行商维护的这些软件包中各个目录的路径通常与源软件包中指定的默认路径不同,因此也与本书中使用的路径不同。
Nagios 3.0 相对较新;在此建议您通过编译和安装软件来“亲自动手”。以下安装指南也适用于 Nagios 2.x,版本 2.x 和 3.0 之间的任何差异都会在文本中明确说明。
如果您编译自己的软件,您将控制目录结构和许多其他参数。以这种方式编译的 Nagios 系统也提供了一个几乎完整的主配置文件,其中最初不需要进行任何更改。但应指出,如果您自己编译 Nagios,可能会涉及对必要的开发包进行繁琐的搜索,具体取决于计算机上已经安装的内容。
1.1 准备工作
为了编译 Nagios 本身,您需要 gcc、make、autoconf 和 automake。所需的库是 libgd^([9]) 和 openssl^([10)。这些库的开发包也必须安装(根据发行版的不同,可能以 -dev 或 -devel 结尾):libssl-dev、libgd-dev、libc6-dev**。
使用 Debian 和 Ubuntu,您可以通过使用 apt-get install 来安装软件包 apache2、build-essential 和 libgd2-dev。在 Open-SUSE 中,您可以通过 YAST2 安装 apache2,以及所有 C/C++ 开发库,以及软件包 gd。在 Fedora 中,您在命令行上运行 yum install 命令,并将软件包 httpd、gcc、glibc、glibc-common、gd 和 gd-devel 作为参数输入。
对于插件,建议您还安装以下软件包:ntpdate^([11])(可能包含在软件包 ntp 或 xntp 中),snmp,^([12) smbclient^([13)(可能是软件包 samba-client 的一个组件),libldap2 库,以及相关的开发包 libldap2-dev^([14)(根据发行版的不同,适当的软件包也称为 openldap2-client 和 openldap2-devel)。您还需要安装用于数据库的客户端和开发包(例如,postgresql-client** 和 postgresql-dev(el))。
1.1.1 确定和设置所需的用户
在编译和安装之前,使用命令groupadd设置操作所需的组。使用groupadd设置nagios和nagcmd组,并使用useradd设置分配给这些组并使用其权限运行的nagios用户:
linux:~ # **groupadd -g 9000 nagios**
linux:~ # **groupadd -g 9001 nagcmd**
linux:~ # **useradd -u 9000 -g nagios -G nagcmd -d /usr/local/nagios** \
**-c "Nagios Admin" nagios**
除了这里使用的用户(9000)和组 ID(9000 或 9001)之外,还可以使用任何其他可用的 ID。用户nagios的主要组nagios应仅为此用户保留。
Nagios 在运行 CGI 脚本时使用的是与 Apache Web 服务器运行权限相同的用户 ID。为了使此用户能够访问 Nagios 的某些受保护区域,需要一个额外的组,即所谓的*Nagios 命令组nagcmd。只有 Web 用户和用户nagios应属于此组。Web 用户可以从 Apache 配置文件中确定。在 Debian/Ubuntu 中,它位于/etc/apache2/apache2.conf;在 Fedora 中位于/etc/httpd/httpd.conf:
linux:~ # **grep "^User" /etc/apache2/apache2.conf**
User www-data
以这种方式确定的用户(在 Debian/Ubuntu 中为www-data,在 Open-SUSE 中为www-run,在 Fedora 中为httpd)还分配到nagcmd组,以下以 Debian/Ubuntu 为例:
linux:~ # **usermod -G nagcmd www-data**
在示例中,Web 用户被称为www-data。命令usermod(此命令更改现有用户账户的数据)也通过-G选项将 Web 用户包含在nagcmd组中,这是通过操作文件/etc/group中的相应条目实现的。
此外,指定为用户nagios主目录的目录/usr/local/nagios、配置目录/etc/nagios以及 Nagios 运行时记录变量数据的目录/var/nagios都是手动设置的,并分配给用户nagios和同名的组:
linux:~ # **mkdir /usr/local/nagios /etc/nagios /var/nagios**
linux:~ # **chown nagios.nagios /usr/local/nagios /etc/nagios /var/nagios**
^([9]) www.boutell.com/gd/
^([10]) www.openssl.org/ 根据发行版的不同,所需的 RPM 和 Debian 软件包有时有不同的名称。在这里,您需要参考相应发行版的搜索帮助。对于 Debian,主页将有所帮助。例如,如果configure指令抱怨缺少gd.h文件,您可以在www.debian.org/distrib/packages中专门搜索软件包的内容。搜索结果将显示包含文件gd.h的所有软件包。
^([11]) ntp.isc.org/bin/view/Main/SoftwareDownloads
^([12]) net-snmp.sourceforge.net/
^([13]) samba.org/samba/
^([14]) www.openldap.org/
1.2 编译源代码
Nagios 源代码可在项目页面上下载.^([15]) 下面的安装说明适用于版本 3.0,该版本由开发者以 tarball 形式提供。Nagios 2.x 的安装几乎以相同的方式进行:
linux:~ # **mkdir /usr/local/src**
linux:~ # **cd /usr/local/src**
linux:local/src # **tar xvzf** path/to/**nagios-3.0.tar.gz**
...
三个命令将源代码解压缩到为此目的创建的目录中,/usr/local/src。还创建了一个名为 nagios-3.0 的子目录,其中包含 Nagios 源代码。为了准备编译,在运行 configure 命令时输入偏离默认值的参数。表 1-1 列出了最重要的参数:
linux:~ # **cd /usr/local/src/nagios-3.0**
linux:src/nagios-3.0 # **./configure** \
**--sysconfdir=/etc/nagios** \
**--localstatedir=/var/nagios** \
**--with-command-group=nagcmd**
...
这里选择的值确保安装程序选择书中使用的目录,并在生成主配置文件时设置所有参数正确。这大大简化了配置的微调。如果您想使用内置 Perl 解释器来加速 Perl 脚本的执行,那么您还需要两个开关 --with-perlcache 和 --enable-embedded-perl。
在 Nagios 3.0 中,您可以省略 --with-perlcache,因为它由 --enable-embedded-perl 自动启用。您可以在 附录 G,第 669 页找到更多关于内置 Perl 解释器的信息。
表 1-1. Nagios 的安装参数
| 属性 | 值 | 配置选项 |
|---|---|---|
| 根目录 | /usr/local/nagios |
--prefix |
| 配置目录 | /etc/nagios |
--sysconfdir |
| 变量数据目录 | /var/nagios |
--localstatedir |
| Nagios 用户(用户 ID) | nagios (9000) |
--with-nagios-user |
| Nagios 组(组 ID) | nagios (9000) |
--with-nagios-group |
| Nagios 命令组(组 ID) | nagcmd (9001) |
--with-command-group |
If --prefix 未指定,Nagios 将自身安装在 /usr/local/nagios 目录下。我们建议您坚持使用此目录.^([16])
系统通常将其配置文件存储在其根目录下的 etc 目录中。通常,将这些文件存储在 /etc 层次结构中会更好。在这里,我们使用 /etc/nagios.^([17])
默认情况下,变量数据(如日志文件和状态文件)存储在 /usr/local/nagios/var 目录中。这位于 /usr 层次结构中,其中应只包含程序和其他只读文件,而不是可写文件。为了确保这一点,我们使用 /var/nagios.^([18])
不论这些变化如何,在大多数情况下,configure 并非第一次运行就毫无故障,因为总会有某个包缺失。对于像 libgd 这样的必需库,Nagios 几乎总是要求相关的开发者包,包括头文件(在这里,libgd-dev 或 libgd-devel)。根据发行版的不同,它们的名称将以 -devel 或 -dev 结尾。
在所有测试运行完毕后,configure 会显示所有重要的配置参数的摘要:
******* Configuration summary for nagios 3.0 *******:
General Options:
----------------
Nagios executable: nagios
Nagios user/group: nagios,nagios
Command user/group: nagios,nagcmd
Embedded Perl: yes, with caching
Event Broker: yes
Install $prefix: /usr/local/nagios
Lock file: /var/nagios/nagios.lock
Check result directory: /var/nagios/spool/checkresults
Init directory: /etc/init.d
Apache conf.d directory: /etc/apache2/conf.d
Mail program: /usr/bin/mail
Host OS: linux-gnu
Web Interface Options:
------------------
HTML URL: http://localhost/nagios/
CGI URL: http://localhost/nagios/cgi-bin/
Traceroute (used by WAP): /usr/sbin/traceroute
在 Nagios 2.x 中,缺少 Check result directory、Apache conf.d directory 和 Mail program 这几行。
如果在 Embedded Perl 项后面写有 yes,则启用嵌入式 Perl 解释器。事件代理 提供了一个接口,用于加载作为附加模块的扩展,而系统正在运行.^([19])
如果你对结果满意,make 将开始实际的编译并安装软件:^([20])
linux:src/nagios-3.0 # **make all**
...
linux:src/nagios-3.0 # **make install**
...
linux:src/nagios-3.0 # **make install-init**
...
linux:src/nagios-3.0 # **make install-commandmode**
...
linux:src/nagios-3.0 # **make install-config**
...
命令 make all 编译所有相关程序,然后通过 make install 将它们以及 CGI 脚本和文档复制到相应的目录中。除了 /etc/nagios 和 /var/nagios,在 /usr/local/nagios 下还会创建其他目录,这些目录在 表 1-2 中进行了总结。
表 1-2. /usr/local/nagios 下的 Nagios 目录
| 目录 | 内容 |
|---|---|
./bin |
可执行的 Nagios 主程序 |
./libexec |
插件 |
./sbin |
CGI 脚本 |
./share |
文档,Web 界面的 HTML 文件 |
命令 make install-commandmode 生成用于后续使用 命令文件机制 所需的目录(参见 13.1 外部命令的接口,第 292 页)。这一步是可选的,取决于预期用途,但由于稍后容易忘记,因此最好现在就采取预防措施。最后的 make install-config 创建示例配置,该配置将在 第二章 中使用,第 53 页。
^([15]) www.nagios.org/
^([16]) 根据 文件系统层次结构标准 FHS,版本 2.3,或管理员加载的本地程序应安装在 /usr/local
^([17]) 这与 FHS 2.3 并不完全兼容,FHS 2.3 更希望配置文件位于 /etc/local/nagios。
^([18]) 这也不完全符合 FHS 2.3 的要求。但由于 Nagios 在 spool、cache 和状态信息之间没有区别,因此以简单的方式实现 FHS-true 的复制是不可能的。
^([19]) 在印刷时,还没有任何外部扩展,这就是为什么事件代理目前只对开发者有吸引力。
^([20]) 从 Nagios 2.x 更新到 Nagios 3.0 时需要小心:这里你应该首先备份现有的配置,最初只运行 make all,并仔细阅读第 693 页的 H.13 从 Nagios 2.x 升级到 3.0。在 Nagios 3.0 中,make install-config 命令会覆盖现有文件!
1.3 自动启动 Nagios
命令 make install-init 为系统启动安装合适的初始化脚本。这里 make 会自动尝试检测正确的路径,对于大多数 Linux 发行版是 /etc/init.d。根据你的系统,这可能不正确,因此你应该检查它。为了使 Nagios 在系统启动时自动启动,会在 /etc/rc?.d 目录中创建符号链接。对于使用 System-V-Init 的 Debian 和 Ubuntu,内置的系统脚本 update-rc.d 执行此任务:
linux:~ # **update-rc.d nagios defaults 99**
此命令创建以 S99 为前缀的符号链接到目录 rc2.d 到 rc5.d,以便在切换到运行级别 2 到 5 时 Nagios 能够自动启动。此外,它还确保在目录 rc0.d、rc1.d 和 rc6.d 中的 K99 符号链接在系统关闭和重启以及切换到维护模式时负责停止 Nagios。这对应以下命令行命令:
linux:~ # **ln -s /etc/init.d/nagios /etc/rc2.d/S99nagios**
linux:~ # **ln -s /etc/init.d/nagios /etc/rc3.d/S99nagios**
linux:~ # **ln -s /etc/init.d/nagios /etc/rc4.d/S99nagios**
linux:~ # **ln -s /etc/init.d/nagios /etc/rc5.d/S99nagios**
linux:~ # **ln -s /etc/init.d/nagios /etc/rc0.d/K99nagios**
linux:~ # **ln -s /etc/init.d/nagios /etc/rc1.d/K99nagios**
linux:~ # **ln -s /etc/init.d/nagios /etc/rc6.d/K99nagios**
对于 OpenSUSE,所需的符号链接是通过脚本 insserv 创建的:
linux:~ # **insserv nagios**
Fedora 用户使用 chkconfig 执行此任务:
linux:~ # **chkconfig --add nagios**
linux:~ # **nagios on**
1.4 安装和测试插件
目前仍然缺少的是插件。它们必须从 www.nagios.org/ 独立下载并安装。作为独立程序,它们的版本控制系统与 Nagios 不同。在印刷时,当前版本是 1.4.11,但如果你不介意没有最新功能,也可以使用早期版本的插件。
1.4.1 安装
插件源代码的安装,就像 Nagios 一样,发生在目录 /usr/local 中:
linux:~ # **cd /usr/local/src**
linux:local/src # **tar xvzf** path /to/**nagios-plugins-1.4.tar.gz**
linux:src/nagios-plugins-1.4.11 # **./configure** \
**--sysconfdir=/etc/nagios** \
**--localstatedir=/var/nagios** \
**--enable-perl-modules**
...
当运行configure命令时,您应该指定与服务器相同的非默认值,这里是指配置目录(/etc/nagios)和 Nagios 保存数据的目录(/var/nagios)。由于 Nagios 插件不是由与 Nagios 本身相同的人维护的,您应该始终提前检查,使用./configure --help,以确定 Nagios 和插件的configure选项是否真正匹配或有所偏差。
只有当您打算安装 Perl 模块Nagios::Plugin时,才需要--enable-perl-modules开关——例如,如果您正在使用它用 Perl 编写自己的插件。您可以在 24.2 The Perl Module Nagios::Plugin 中了解更多信息,第 560 页。
可能会在configure命令的输出中出现一系列WARNING警告,类似于以下内容:
...
configure: WARNING: Skipping radius plugin
configure: WARNING: install radius libs to compile this plugin (see
REQUIREMENTS).
...
configure: WARNING: Tried /usr/bin/perl - install Net ::SNMP perl
module if you want to use the perl snmp plugins
...
如果您不使用 Radius,您不必担心忽略相应的错误信息。否则,您应该安装缺失的包并重复configure过程。在这个例子中,经常需要的 SNMP 功能缺失了一个 Perl 模块。这个模块可以通过发行版包或通过在线 CPAN 存档安装:^([21])
linux:~ # **perl -MCPAN -e 'install Net::SNMP'**
...
如果您是第一次运行 CPAN 程序,它将交互式地引导您完成一个自解释的设置,您可以用默认选项回答几乎所有的问题。
在nagios-plugins-1.4.11目录中运行make将编译所有插件。之后,您有机会执行测试,使用make check。由于这些测试并没有被特别仔细地编程,您经常会看到许多错误信息,这些信息更多地与测试本身有关,而不是与插件有关。如果您仍然想尝试,那么还必须安装CachePerl 模块。无论您是否使用make check,您都应该在安装后手动检查最重要的插件。
命令make install最终将插件固定在子目录libexec(在我们的例子中是/usr/local/nagios/libexec)。然而,并非所有插件都是通过此命令安装的。源目录contrib包含了一些make install不会自动安装的插件。
此目录中的大多数插件是 shell 或 Perl 脚本。在需要时,这些脚本会简单地复制到插件目录/usr/local/nagios/libexec。少数 C 程序首先必须编译,在某些情况下,这可能不是一件轻松的事情,因为可能缺少相应的 makefile,甚至缺少所需库的描述。如果简单的make不足以解决问题,就像在以下情况中:
linux:nagios-plugins-1.4.11/contrib # **make check_cluster2**[22]
cc check_cluster2.c -o check_cluster2
然后,最好在 nagiosplug-help 邮件列表中寻求帮助.^([23]) 编译后的程序也必须复制到插件目录中。
1.4.2 插件测试
因为插件是独立的程序,所以现在就可以手动用于测试目的——在 Nagios 安装完成之前。无论如何,你应该检查 check_icmp 插件,它起着至关重要的作用。它检查是否可以通过 ping 访问另一台计算机,并且是唯一既可以用作服务检查也可以用作主机检查的插件。如果它不能正常工作,Nagios 也无法正常工作,因为只要系统将主机分类为“down”,就无法执行任何服务检查。6.2 使用 Ping 进行可达性测试, 108,详细介绍了 check_icmp,这就是为什么这里只简要介绍其手动使用方法。
为了使插件能够正确运行,它必须像 /bin/ping 程序一样,以 root 用户身份运行。这是通过提供 SUID 位 来实现的。在当前插件版本中,make install 会自动设置这个位。一种可以观察到这一点的方式是,源代码中包含一个额外的目录,plugins-root。在较旧版本的插件中,你必须手动完成这项操作:
linux:~ # **chown root.nagios /usr/local/nagios/libexec/check_icmp**
linux:~ # **chmod 4711 /usr/local/nagios/libexec/check_icmp**
linux:~ # **ls -l /usr/local/nagios/libexec/check_icmp**
-rwsr-x--x 1 root nagios 61326 2005-02-08 19:49 check_icmp
使用 -h 选项可以提供插件的简要说明:^([24])
nagios@linux:~$ **/usr/local/nagios/libexec/check_icmp -h**
Usage: check_icmp [options] [-H] host1 host2 hostn
Where options are any combination of:
***** -H | --host specify a target
***** -w | --warn warning threshold (currently 200.000ms,40%)
***** -c | --crit critical threshold (currently 500.000ms,80%)
***** -n | --packets number of packets to send (currently 5)
***** -i | --interval max packet interval (currently 80.000ms)
***** -I | --hostint max target interval (currently 0.000ms)
***** -l | --ttl TTL on outgoing packets (currently 0)
***** -t | --timeout timeout value (seconds, currently 10)
***** -b | --bytes icmp packet size (currenly ignored)
-v | --verbose verbosity++
-h | --help this cruft
The -H switch is optional. Naming a host (or several) to check is not.
对于简单的测试,指定一个 IP 地址就足够了(是否使用 -H 标志无关紧要):
user@linux:~$ **cd /usr/local/nagios/libexec**
user@linux:nagios/libexec$ **./check_icmp -H 192.168.1.13**
OK - 192.168.1.13: rta 0.261ms, lost 0%|rta=0.261ms;200.000;500.000;0;
pl=0%;40;80;;
输出显示为单行,这里为了打印版本而进行了换行:在零百分比的数据包丢失(丢失 0%)的情况下,测试已经通过。Nagios 只使用输出行的前 300 个字节。如果插件提供了更多信息,这些信息将被截断。
如果你想测试其他插件,我们建议你参考第六章和第七章,它们详细介绍了最重要的插件。所有(合理编写的)插件都提供了带有 --help 选项的更详细的说明。
^([21]) www.cpan.org/ 的 Comprehensive Perl Archive Network
^([22]) 使用 check_cluster,可以监控集群的主机和服务的状态。在这里,通常希望在所有节点或冗余服务同时失败时收到通知。另一方面,如果某个特定服务失败,这不算是关键问题,只要集群中的其他主机提供这项服务即可。
^([23]) lists.sourceforge.net/lists/listinfo/nagiosplug-help
^([24]) 列出的选项在 6.2 使用 Ping 进行可达性测试中详细解释,从第 108 页开始。
1.5 配置 Web 界面
为了使 Nagios 的 Web 前端能够运行,Web 服务器必须知道 CGI 目录和主要 Web 目录。以下描述适用于 Apache 1.3、Apache 2.0 和 2.2。
1.5.1 设置 Apache
只要您没有通过configure脚本使用-with-cgiurl添加前端的不同地址,Nagios 就会期望在 URL/nagios/cgi-bin(实际目录:/usr/local/na-gios/sbin)以及/nagios以下的所有 HTML 文件(实际目录:/usr/local/nagios/share)中找到 CGI 程序。Nagios 3.0 包括用于 Web 界面的自己的make目标,它配置目录并设置两个 URL 的相应别名:
linux:~ # **make install-webconf**
...
此命令将文件nagios.conf安装到 Apache 的配置目录中。在 Debian/Ubuntu 和 OpenSUSE 中,它命名为/etc/apache2/ conf.d,或在 Fedora 中为/etc/httpd/conf.d。它看起来是这样的:
ScriptAlias /nagios/cgi-bin "/usr/local/nagios/sbin"
<Directory "/usr/local/nagios/sbin">
Options ExecCGI
AllowOverride None
Order allow,deny
Allow from all
# Order deny,allow
# Deny from all
# Allow from 127.0.0.1
AuthName "Nagios Access"
AuthType Basic
AuthUserFile /etc/nagios/htpasswd.users
Require valid-user
</Directory>
在 Nagios 2.x 版本中,您必须手动设置文件。
指令ScriptAlias确保当调用类似nagios-server/nagios/cgi-bin的 URL 时,Apache 访问 Nagios CGI 目录,而不论 Apache CGI 目录可能位于何处。Options ExcecCGI确保 Web 服务器接受那里放置的所有脚本。Order和Allow最初允许 Web 服务器无限制地访问这里。如果您想限制访问,则改变Order参数的顺序:
Order deny, allow
Deny from all
Allow from 127.0.0.1
Allow from 192.0.2.0/24
此示例确保只有来自网络192.0.2.0/24 (/24代表子网掩码255.255.255.0)和localhost的客户端可以访问指定的目录。三个Auth*和Require指令确保了经过身份验证的访问;有关用户身份验证的更多信息,请参见 1.5.3 用户身份验证,第 49 页。
Nagios 文档目录/usr/local/nagios/share的设置方式类似:指令Alias允许通过 URL nagios-server/nagios访问目录,而不管 Apache-DocumentRoot位于何处。
指令Order和Allow(如果需要,还包括Deny)的设置方式与 CGI 部分相同。在文档领域,身份验证并非绝对必要,但如果您想在其中安装扩展,如 PNP,那么它肯定是有用的(参见 19.6 使用 PNP 进行平滑绘图,第 446 页)。
命令
linux:~ # **/etc/init.d/apache reload**
加载新的配置。如果一切正常,Nagios 主页面将在 Web 浏览器中的nagios-server/nagios下显示。
1.5.2 SELinux
只有少数发行版——特别是 Fedora——默认启用安全增强型 Linux (SELinux)。当启用并适当配置时,这允许诸如 Apache Web 服务器之类的服务仅访问明确提到的文件和目录。Nagios 使用的目录/usr/local/nagios/bin和/usr/local/nagios/share并不包含在内。结果是:SELinux 首先拒绝 Apache 访问,直到通过配置允许为止。命令getenforce显示执行模式是否开启,在这种模式下,SELinux 强制执行配置的访问权限的严格遵守。这可以通过命令关闭。
linux:~ # **setenforce 0**
要在下次系统启动时保持此状态,需要更改/etc/selinux/config中的设置。然而,与其关闭执行模式,不如更好地配置所需的访问权限。这确实需要一些了解 SELinux 如何工作的知识,以及一些通用的 Linux 经验——这些知识将超出本书的范围。对于那些想要更深入地掌握这个主题的人来说,可以在 Nagios 社区 Wiki 中找到更多信息,包括一个具体的指南链接^([25])。
1.5.3 用户身份验证
在交付时的状态中,Nagios 只允许经过身份验证的用户访问 CGI 目录。这意味着未“登录”的用户除了主页和文档外无法看到任何内容。他们被阻止访问其他功能。
有一个很好的理由:除了状态查询和其他显示功能外,Nagios 还有通过 Web 界面发送命令的能力。外部命令的接口用于此目的(13.1 外部命令接口, 第 292 页)。如果此功能激活,可以通过 Web 浏览器切换检查,例如,Nagios 甚至可以重新启动。只有授权用户应该能够这样做。此外,一般的考虑安全因素表明,Nagios 提供的大量信息应该只对可信赖的人开放。
首先,Nagios 的 CGI 配置文件cgi.cfg中的参数use_authenticationin必须设置为 1^([27]):
use_authentication=1
在安装过程中,这是默认设置。Apache 提供的最简单的身份验证形式是基于文件的Basic身份验证,这在配置文件中已经启用:
AuthName "Nagios Access"
AuthType Basic
AuthUserFile /etc/nagios/htpasswd.users
Require valid-user
AuthName是一个信息字段,当 Web 服务器请求身份验证时,浏览器会显示它。AuthType Basic表示简单身份验证,其中密码在没有加密的情况下传输,只要不使用 SSL 连接。最好将密码文件——这里指htpasswd.users——保存在 Nagios 配置目录/etc/nagios中。最后一个参数require valid-user意味着所有经过身份验证的用户都有访问权限(没有对特定组的限制;只需用户密码对有效即可)。
这里将指定(可自由选择的)密码文件名称,以便显示涉及哪种类型的密码文件。它由 Apache 中包含的htpasswd2程序生成。(在 Apache 1.3 和一些其他发行版中,该程序称为htpasswd。)运行
linux:/etc/nagios **# htpasswd2 -c htpasswd.users nagios**
New password: passwort
Re-type new password: passwort
Adding password for user nagios
为用户nagios生成一个新的密码文件。其格式相对简单:
nagios:7NlyfpdI2UZEs
每行包含一个用户密码对,由冒号分隔.^([28)如果您想添加其他用户,应确保省略-c(创建)选项。否则htpasswd(2)将重新创建文件并删除旧内容:
linux:/etc/nagios **# htpasswd2 htpasswd.users** another_user
用户名不能随意选择,而必须与联系人姓名匹配(参见 2.7 定义错误消息的收件人:联系人,第 70 页)。只有网络用户(根据您的发行版,可能是www-data、www-run或httpd,参见 1.1.1 确定和设置所需用户)可以访问生成的htpasswd.users文件,并且应该保护它不被其他人访问:
linux:/etc/nagios **# chown www-data htpasswd.users**
linux:/etc/nagios **# chmod 600 htpasswd**
结合其自身模块和第三方模块,Apache 允许一系列其他身份验证方法。这些包括通过 LDAP 目录、通过可插拔身份验证模块(PAM)^([29])或通过 Windows 服务器使用 SMB 进行身份验证。这里我们推荐您查阅相关文献和 Apache 主页上的高度详细文档.^([30)一个相当高级的例子,其中已经通过 Kerberos 认证的用户不需要再次进行认证,在附录 E 的第 637 页中描述。
尽管 Web 界面的配置现在已经完成,但此时只有文档被正确显示:Nagios 本身必须首先进行相应的调整——正如以下章节中详细描述的那样——然后才能用于监控以这种方式提供的数据。
^([25]) 在www.nagioscommunity.org/wiki/搜索关键字SELinux。
^([26]) www.rickwargo.com/2006/10/29/fc6-selinux-and-nagios/
^([27]) 更多信息请参阅第 77 页的 2.13 cgi.cfg 中的 CGI 配置。
^([28]) 严格来说,第二个位置不包含密码本身,而是其哈希值。
^([29]) “可插拔认证模块”现在控制着所有 Linux 发行版的认证,因此你也可以在这里使用现有的用户账户。
^([30]) httpd.apache.org/
第二章. Nagios 配置
尽管 Nagios 配置可能会变得相当庞大,但你只需要处理其中的一小部分,就可以让系统启动并运行。幸运的是,Nagios 中的许多参数已经设置为合理的默认设置。因此,本章将主要关注最基本的和最常用的参数,这对于初始配置来说已经足够了。
关于配置的更多详细信息可以在各个 Nagios 功能章节中找到:在网络插件中,第六章(第 105 页)提供了许多服务配置的示例。Nagios 消息系统的所有参数都在第十二章(第 265 页)中详细解释,控制 Web 界面的参数在第十六章(第 327 页)中描述。此外,Nagios 还包括其自己的详尽文档(/usr/local/nagios/share/docs),这也可以从 Web 界面访问。这始终可以作为获取进一步信息的有用来源,因此下面的每个部分都引用了原始文档中的相应位置。
安装程序在 make install-config(参见第 39 页的 1.2 编译源代码)中,将单个配置文件的示例存储在目录 /etc/nagios 中。但请注意:Nagios 2.0 中示例文件的名字以 -sample 结尾(这样在更新时不会覆盖生产所需的文件),但在当前的 Nagios 2.x 版本和 Nagios 3.0 中不再是这样。在这里,现有文件会被覆盖。诚然,make install 会重命名现有文件:因此 nagios.cfg 被转换为 nagios.cfg˜。但这只会发生一次。运行 make install 一次后,文件的原内容就会被永久删除。因此,在运行 make install-config 之前备份现有配置是至关重要的。
在此命令之后,Nagios 3.0 的目录/etc/nagios包含三个主要配置文件:nagios.cfg、cgi.cfg和resource.cfg。对象定义最终位于子目录objects中的其他文件中:
user@linux:/etc/nagios$ **tree**[31]
.
|-- nagios.cfg
|-- cgi.cfg
|-- resource.cfg
'-- objects
|-- templates.cfg
|-- commands.cfg
|-- contacts.cfg
|-- timeperiods.cfg
|-- localhost.cfg
|-- windows.cfg
|-- printer.cfg
'-- switch.cfg
Nagios 2.10 使用更少的文件;对象仅在文件localhost.cfg和commands.cfg中定义:
user@linux:/etc/nagios$ **tree**
.
|-- nagios.cfg
|-- cgi.cfg
|-- resource.cfg
|-- localhost.cfg
'-- commands.cfg
所有后续工作都应作为用户nagios执行。如果你以超级用户身份编辑文件,你必须确保目录/etc/nagios的内容在之后再次属于用户nagios。除了文件resource.cfg——它可能包含密码,因此只有所有者nagios应该设置读取权限——所有其他文件都可以被所有人读取。
2.1 主配置文件nagios.cfg
中心配置发生在nagios.cfg中。它不是将所有配置选项存储在那里,而是链接到其他配置文件(CGI 配置除外)。
对于自己编译和安装 Nagios 的用户来说,一个优点是,一开始他们甚至不需要调整nagios.cfg,因为所有路径都已经正确设置。^[[32]) 这就是你需要做的全部。尽管如此,建议进行一个小修改,这有助于保持清晰的画面,并在涉及大型网络时大大简化配置。
相关的参数是cfg_file,它集成了具有对象定义的文件(见第 59 页的 2.2 对象——概述 到 2.10 使用 timeperiod 定义时间周期)。包含在 Nagios 3.0 软件包中的文件nagios.cfg包含以下条目:
nagios@linux:/etc/nagios$ **fgrep cfg_file nagios.cfg**
...
cfg_file=/etc/nagios/objects/commands.cfg
cfg_file=/etc/nagios/objects/contacts.cfg
cfg_file=/etc/nagios/objects/timeperiods.cfg
cfg_file=/etc/nagios/objects/templates.cfg
cfg_file=/etc/nagios/objects/localhost.cfg
...
Nagios 2.x 将所有示例对象文件汇集到仅有的两个配置文件中:
nagios@linux:/etc/nagios$ **fgrep cfg_file nagios.cfg**
...
cfg_file=/etc/nagios/commands.cfg
cfg_file=/etc/nagios/localhost.cfg
...
作为cfg_file的替代方案,你也可以使用参数cfg_dir:这要求你指定一个目录的名称,Nagios 应从该目录中集成所有以.cfg结尾的配置文件(具有其他扩展名的文件将被简单地忽略)。这也适用于递归;因此,Nagios 会评估所有子目录中的所有*.cfg文件。因此,使用cfg_dir参数,你只需要指定一个信号目录,而不是像使用cfg_file一样,单独调用所有配置文件。唯一的限制是:这些必须是描述对象的配置文件。配置文件cgi.cfg和resource.cfg不包括在内,这就是为什么,像主配置文件nagios.cfg一样,它们仍然保留在主目录/etc/nagios中。
简单结构
简单结构
对于特定对象的配置,最好创建一个名为 /etc/nagios/mysite 的目录,然后在 nagios.cfg 中删除所有 cfg_file 指令(或在行首用 # 注释它们),并替换为以下内容:
...
cfg_dir=/etc/nagios/mysite
...
目录 /etc/nagios 的内容将是版本无关的,如下所示:
nagios@linux:/etc/nagios$ **tree**
.
|-- nagios.cfg
|-- cgi.cfg
|-- resource.cfg
|-- htpasswd
'-- mysite
|-- contactgroups.cfg
|-- misccommands.cfg
|-- contacts.cfg
|-- timeperiods.cfg
|-- checkcommands.cfg
|-- hosts.cfg
|-- services.cfg
'-- hostgroups.cfg
主要目录 /etc/nagios 只包含三个配置文件和受保护 Web 访问的密码文件。是否将相同类型的所有对象收集在一个单独的文件中,即所有主机定义在 hosts.cfg 中,所有服务在 services.cfg 中,等等,或者将这些对象分割到单独的文件中,由个人自行决定。
在此示例中,只需要将顶层目录 mysite 与 nagios.cfg 中的 cfg_dir 集成。这构成了我们初始配置的基础。
一个更大的位置
对于较大的安装,您应该将对象定义分割到单独的文件中(例如,为每个主机创建一个包含主机定义的单独文件),并根据合理的标准将这些文件分组到子目录中,如下例所示:
...
'-- mysite
|-- linux
| |-- services
| '-- hosts
| |-- linux01.cfg
| |-- linux02.cfg
| '-- linux03.cfg
|-- windows
| |-- services
| '-- hosts
| |-- win03.cfg
| '-- win09.cfg
'-- router
|-- services
'-- hosts
|-- edge01.cfg
|-- edge02.cfg
'-- backbone.cfg
此示例根据操作系统(linux、windows 和 router)排列对象。这些系统目录中的每个目录都有两个更进一步的子目录:hosts 和 services。
每个单独的主机对象都在一个单独的文件中描述(例如 linux01.cfg)。如果您想创建具有相似属性的其他主机对象,可以轻松地复制这些文件。您也可以以类似的方式复制服务。
其他对象定义可以直接放置在目录 my-site 中,如 简单结构 中的简单结构所示,或者您可以创建子目录,如下一节更详细地描述的那样。
在 nagios.cfg 中,对象定义再次与单个指令绑定:
cfg_dir=/etc/nagios/mysite
具有多个不同位置的较大安装
对于大型安装,最好根据位置将主机和服务对象分割开来。即使对于剩余的对象,我们也建议您将它们分割到单独的文件中,并将这些文件分组到子目录中:
|-- global
| |-- commands
| | |-- check-host-alive.cfg
| | |-- check_http.cfg
| | |-- check_icmp.cfg
... ... ...
| |-- contacts
| | |-- nagios.cfg
| |-- templates
| | |-- host_generic_t.cfg
| | |-- service_generic_t.cfg
| | |-- service_perfdata_t.cfg
... ... ...
| '-- timeperiods
'-- sites
|-- foreignsite
| |-- hosts
| '-- services
|-- mysite
| |-- hosts
| '-- services
'-- othersite
|-- hosts
'--services
在此示例中,目录 global 收集了所有不定义检查的对象(即,所有不是主机或服务对象的东西)。这是 commands、contacts、templates 和 timeperiods 子目录所在的位置,每个子目录都包含同名对象类别的文件。对于许多命令对象,单独的文件比一个大文本文件更容易处理。
如果联系人对象也存储在单独的文件中,禁用联系人就很容易:只需将文件扩展名从 .cfg 更改为 .cfx,然后执行重新加载。Nagios 忽略对象目录中所有不以 .cfg 结尾的文件。上层目录 global 和 sites 被绑定到 nagios.cfg:
cfg_dir=/etc/nagios/global
cfg_dir=/etc/nagios/sites
设置欧洲日期格式
Nagios 中的日期规范默认以美国格式显示 *`MM-DD -YYYY`*:
date_format=us
如果你更喜欢其他格式,例如欧洲日期格式,建议你从一开始就更改 nagios.cfg 中的 date_format 参数。值 iso8601 确保 Nagios 日期规范以 ISO 或 DIN 格式显示 *`YYYY-MM-DD HH-.MM: SS`*。 表 2-1 列出了 date_format 的可能值。
nagios.cfg 中的其他参数在 A.1 主配置文件 nagios.cfg 中描述;在原始文档中,这些可以在 localhost/nagios/docs/configmain.html 或 /usr/local/nagios/share/docs/config-main.html 中找到。
表 2-1. 可能的日期格式
| 值 | 表示 |
|---|---|
us |
MM-DD-YYYY HH:MM:SS |
euro |
DD-MM-YYYY HH:MM:SS |
iso8601 |
YYYY-MM-DD HH:MM:SS |
strict-iso8601 |
YYYY-MM-DDTHH:MM:SS |
^([31]) mama.indstate.edu/users/ice/tree/
^([32]) 如果 Nagios 来自发行版包,至少检查路径细节是值得的。在维护良好的发行版中,这些也将与那里使用的 Nagios 目录相匹配。
2.2 对象——概述
Nagios 对象描述了特定的单元:一个主机、一个服务、一个联系人或每个所属的组。甚至命令也被定义为对象。这种定义并非偶然。Nagios 还能够继承特性(2.11 模板,第 75 页)。
对象定义遵循以下模式:
define *object-type* {
*parameter value*
*parameter value*
...
}
Nagios 有以下 *`object-type`* 的值:
host
主对象描述了要监控的网络节点之一。Nagios 期望在这里使用 IP 地址作为参数(或 完全限定域名)以及定义主机是否存活的命令(参见 2.3 定义要监控的机器,带主机,第 62 页)。主机定义在服务定义中重新引用。
hostgroup
可以将多个主机组合成一个组(参见 2.4 使用 hostgroup 组合计算机,第 65 页)。这简化了配置过程,因为定义服务时可以指定整个主机组而不是单个主机(服务将为组中的每个成员存在)。此外,Nagios 在 Web 前端将主机组的成员一起在表格中展示,这有助于提高清晰度。
service
要监控的各个服务被定义为服务对象(参见 2.5 使用 service 定义要监控的服务,第 66 页)。服务永远不会独立于主机存在。因此,完全可能存在具有相同名称的多个服务,只要它们属于不同的主机。以下代码,
define service {
name PING
host_name linux01
...
}
define service {
name PING
host_name linux03
}
描述了两个具有相同服务名称但属于不同主机的服务。因此,在 Nagios 的语言中,一个服务始终是一个主机-服务对。
servicegroup
与主机组类似,Nagios 将多个服务组合在一起,并在 Web 前端以一个具有自己表格的单元来表示这些服务(参见 2.6 使用 servicegroup 组合服务,第 69 页)。服务组并非绝对必要,但有助于提高清晰度,并且在报告中也会用到。
contact
通知 Nagios 特定事件的人(参见 2.7 定义错误消息的收件人:contact,第 70 页)。Nagios 使用联系对象通过 Web 前端向用户展示用户被列为联系人的人员的相关信息。在基本设置中,用户无法看到他们不负责的主机和服务的详细信息。
contactgroup
主机和服务的通知事件通过联系组进行(参见 2.8 消息的接收者:contactgroup,第 72 页)。主机/服务与联系人之间不可能直接建立联系。
timeperiod
描述了 Nagios 应该通知联系组的时段(参见 2.10 使用 timeperiod 定义时段,第 74 页)。在此时段之外,系统不会发送任何消息。可以通过各种 时段 对消息链进行微调,具体取决于主机/服务以及联系人和联系组。更多内容将在 12.3 消息过滤器中介绍,第 267 页。
command
Nagios 总是通过命令对象调用外部程序(参见 2.9 当 Nagios 需要做某事时:命令对象,第 72 页)。除了插件外,消息程序还包括电子邮件或短信消息应用程序。
servicedependency
此对象类型描述了服务之间的依赖关系。例如,如果一个应用程序没有数据库就无法运行,相应的依赖对象将确保 Nagios 将失败的数据库视为主要问题,而不是仅仅宣布应用程序无法运行(参见 12.6 主机和服务的依赖关系会计,第 285 页)。
serviceescalation
用于定义适当的升级管理:如果某个服务在特定时间段后不可用,Nagios 会通知进一步或不同的人群。这也可以在任何你想要的多级上进行配置(参见 12.5 升级管理)。
hostdependency
类似于servicedependency,但针对主机。
hostescalation
类似于serviceescalation,但针对主机。
hostextinfo (Nagios 2.x)
扩展主机信息对象是可选的,并定义了特定的图形和/或 URL,Nagios 会将其额外集成到其图形输出中。该 URL 可以指向提供主机额外信息的网页(参见 16.4 主机和服务的附加信息,第 362 页)。
hostextinfo 该对象在 Nagios 3.0 中已弃用,但仍然可用。Nagios 3.0 将对象参数集成到了主机定义中。
serviceextinfo (Nagios 2.x)
扩展服务信息,类似于扩展主机信息。
并非所有对象类型都是绝对必要的;尤其是在开始时。你可以很容易地不使用*dependency、*escalation、*extinfo对象以及servicegroup。第十二章详细探讨了升级和依赖关系。hostextinfo和serviceextinfo用于提供“更丰富多彩”的图形表示,但它们对于运行 Nagios 并非绝对必要。16.4 主机和服务的附加信息从第 362 页更详细地探讨了这一点。原始文档还提供了更多信息。33]
以下对象示例的注意事项
以下对象示例的注意事项
虽然以下章节详细描述了各个对象类型,但只描述了必需的参数以及那些对有意义操作绝对必要的参数。这里的必需参数总是以粗体形式打印。每个示例的第一个(注释)行列出记录对象定义要存储的文件。对于标记为(*)的参数,Nagios 2.x 和 Nagios 3.0 之间存在一些差异,这些差异将在文本中更深入地解释。
当你首次开始使用 Nagios 时,建议你限制自己使用最小配置,每个对象类型只有一个或两个对象,以将潜在的错误来源降到最低,并尽可能快地获得一个运行系统。之后,扩展可以非常简单和快速地实现,特别是如果你在模板中包含了 2.11 模板]) localhost/nagios/docs/objectdefinitions.html#hostextinfo 或 #serviceextinfo(Nagios 3.0)
localhost/nagios/docs/xodtemplate.html#hostextinfo 或 #serviceextinfo(Nagios 2.x);文件可以在本地/usr/local/nagios/share/docs/中找到。
2.3 使用host定义要监控的机器
主机对象是所有主机和服务检查的基础中央指挥所。它定义了要监控的机器。必须指定打印为粗体的所有参数:
# -- /etc/nagios/mysite/hosts.cfg
define host{
**host_name** linux01
hostgroups linux-servers
**alias**(*) Linux File Server
**address** 192.168.1.9
check_command check-host-alive
**max_check_attempts** 3
**check_period** 24×7
**contact_groups** localadmins
**notification_interval** 120
**notification_period** 24×7
**notification_options** d,u,r,f,s(*)
parents router01
}
host_name
此参数指定 Nagios 在服务、主机组和其它对象中使用的机器名称。只允许特殊字符-和_。
hostgroups
此参数将主机分配给一个主机组对象,该对象必须已经定义(2.4 使用 hostgroup 将计算机分组)。将主机分配给主机组的第二种可能性,与版本 1.x 兼容,使用在定义主机组本身时使用的members参数。两种方法也可以结合使用。
alias
此参数包含对主机的简短描述,Nagios 会在多个位置将其作为附加信息显示。这里允许使用普通文本。从 Nagios 3.0 开始,该参数不再是必需的。如果缺失,将使用host_name的值。
address
这指定了计算机的 IP 地址或完全限定域名(FQDN)。如果可能(即对于静态 IP 地址),你应该使用 IP 地址,因为将名称解析为 IP 地址始终依赖于 DNS 工作,而这并不总是可靠的。
check_command
这指定了 Nagios 在必要时用来检查主机是否可达的命令。该参数是可选的。如果省略,Nagios 将永远不会执行主机检查!这对于经常关闭的网络组件(例如,打印机服务器)可能很有用。
通常用于check_command的命令称为check-host -alive,它已在提供的文件checkcom-mands.cfg中预定义(见 2.9 当 Nagios 需要做某事时:命令对象,第 72 页)。这使用了插件check_ping或更现代的check_icmp。这两个插件都通过 ICMP 数据包ICMP Echo Request和Echo Reply检查主机的可达性。
max_check_attempts
此参数决定了 Nagios 在第一次测试失败后应多久尝试连接到计算机。示例中的值3表示,如果第一次测试返回的不是 OK,则测试将重复进行最多三次。只要还有重复测试要进行,Nagios 就将其称为软状态。如果最终进行了测试,系统将状态分类为硬状态。Nagios 仅通知系统管理员硬状态,在示例中,只有在第三次测试也以错误或警告结束的情况下才会发送消息。
check_period
这指定了主机应该被监控的时间段。实际上,只有“全天候”才有意义——即24×7。这里涉及到一个timeperiod对象,其定义在 2.10 使用 timeperiod 定义时间周期的第 74 页有更详细的描述。除非你想在特定时间显式抑制主机检查,否则使用除24×7之外的其他指定是没有意义的。
contact_groups
这指定了 Nagios 发送与在此定义的主机相关的消息的接收者,即localadmin。2.8 消息接收者:contactgroup 在第 72 页对此有更全面的解释。
notification_interval
这指定了 Nagios 应该在什么时间间隔内重复通知状态的持续存在。120 个时间单位通常意味着每 120 分钟发送一条消息,前提是错误状态持续。
notification_period
这指定了应该发送消息的时间间隔。与 check_period 不同的时间段在这里可能非常有用。理解这里的区别很重要:如果 check_period 排除了时间段,Nagios 甚至无法确定是否存在错误。但如果主机全天候监控,并且仅通过参数 notification_period 限制通知时间段,Nagios 一定会记录错误,并在 Web 前端和日志评估中显示它们。在 notification_period 之外,系统不会发送任何消息。有关通知系统的更详细描述,请参阅 12.3 消息过滤器,第 267 页。
notification_options
此参数描述了 Nagios 在状态发生时应提供通知的状态。Nagios 对于计算机知道以下状态:
d |
停机 |
|---|---|
u |
不可达(由于 Nagios 和主机之间的网络节点失败,主机不可达,无法确定主机的实际状态) |
r |
恢复(错误后的正常状态) |
f |
振荡(状态变化非常快;有关更多信息,请参阅第 611 页的附录 B)。 |
s |
计划停机时间(Nagios 3.0 提供有关计划维护期开始和结束的信息,或在计划维护期取消的情况下。此选项在 Nagios 2.x 中不可用。) |
通过指定 d、u,当主机不在网络上或通过网络不可达时,系统会发送消息,但如果在错误状态(恢复)之后可以再次到达,则不会发送消息。如果使用 n(无)作为值,Nagios 通常不会发出任何通知。
Nagios 发送消息的形式取决于联系人的定义方式。无论您何时想要被通知,Web 界面总是显示当前状态,即使 Nagios 没有发送消息,因为时间段不匹配或系统仍在重复测试(所谓的软状态)。
parents
这允许考虑网络的物理拓扑。在这里,如果主机不在同一网络段中直接接触,则通过路由器或网络组件可以到达主机。这也可以是 Nagios 服务器和主机之间的交换机。如果 Nagios 由于所有父节点(用逗号分隔)都停机而无法到达主机,则 Nagios 将其分类为 UNREACHABLE,而不是 DOWN。
更多信息可以在 Nagios 3.0 在线帮助中找到,地址为localhost/nagios/docs//objectdefinitions.html#host.^([34]) 在 Nagios 2.x 中,该文件名为xodtemplate.html,位于同一目录下。Nagios 2.x 和 Nagios 3.0 之间的差异在 H.1.1 主机对象中描述,第 678 页。
^([34]) 本地位于 /usr/local/nagios/share/docs/objectdefinitions.html。
2.4 使用 hostgroup 将计算机分组
主机组包含一个或多个计算机,以便它们可以在 Web 界面中一起表示(参见第 334 页的图 16-10)——此外,某些对象(例如,服务)可以应用于整个计算机组,而不是为每个主机单独定义它们。
hostgroup_name 参数指定了组的唯一名称,别名接受简短描述。members 参数列出了属于该组的所有主机名称,名称之间用逗号分隔:
# -- /etc/nagios/mysite/hostgroups.cfg
define hostgroup{
**hostgroup_name** linux-servers
**alias** Linux Servers
members linux01,linux02
hostgroup_members(*) hostgroup1,hostgroup2
}
如果在单个成员计算机的主机定义中指定它们所属的组,使用参数hostgroups (2.3 使用主机定义要监控的机器),则从版本 2.0 开始可以省略members条目。这意味着如果您只想删除单个主机,就不再需要搜索所有组定义。members在hostgroup对象中的使用和hostgroups在host对象中的同时使用是同样可能的。Nagios 3.0 中的新主机组是hostgroup_members,您可以使用它指定其他主机组作为成员,从而形成主机组的层次结构。此选项在 Nagios 2.0 中不可用。
2.5 使用 service 定义要监控的服务
Nagios 中的服务始终由主机和服务的组合组成。这种组合必须是唯一的。另一方面,服务名称可以多次出现,只要它们与不同的主机组合。
最简单的服务由简单的 ping 组成,该 ping 测试相关主机是否可达,并记录响应时间和可能发生的任何丢包:
# -- /etc/nagios/mysite/services.cfg
define service{
**host_name** linux01
**service_description** PING
**check_command** check_ping!100.0,20%!500.0,60%
**max_check_attempts** 3
**normal_check_interval**(*) 5
**retry_check_interval**(*) 1
**check_period** 24×7
**notification_interval** 120
**notification_period**(*) 24×7
**notification_options** w, u, c, r, f, s(*)
**contact_groups**(*) localadmins
}
与 Nagios 仅在无法访问主机上的任何其他服务时才执行的主机检查相比,ping 服务是定期执行的。可以通过响应时间和丢包率相对简单地检测到网络问题。主机检查不适用于此目的。
host_name
这指的是在主机对象中定义的名称。Nagios 也通过这种方式获取计算机的 IP 地址。除了单个主机名外,还可以输入由逗号分隔的多个主机列表。作为 host_name 的替代,也可以使用参数 hostgroup_name 来指定整个主机组而不是单个主机。这样,服务就被认为是为以这种方式组合在一起的每个单独的计算机组定义的。您是否使用这种优化,或者为每台计算机分配自己的服务定义,对 Nagios 来说没有区别。
service_description
此参数定义了服务的实际名称。名称中可以包含空格、冒号和破折号。Nagios 始终将服务视为主机名(此处为 linux01)和服务描述(PING)的组合。这必须是唯一的。
servicegroups
将服务分配给必须已经定义的服务组对象(2.6 使用 servicegroup 将服务分组在一起,第 69 页)。
check_command
这定义了 Nagios 测试服务功能时使用的命令。参数通过感叹号传递给实际命令,例如 check_ping。在示例文件中预定义的 check_ping 命令的定义在 2.9 当 Nagios 需要执行某些操作时:命令对象的第 72 页中解释。
在示例中,确定了警告限制的值(100 ms, 20%)和 CRITICAL 状态的值(500 ms, 60%)。您可以将其比作交通灯:如果响应时间保持在 100 毫秒的警告限制以下,并且没有或小于 20%的数据包丢失,则状态为 OK(绿色)。如果数据包丢失或响应时间超过定义的警告限制,但仍在临界限制以下,则状态为 WARNING(黄色)。如果超过临界限制,Nagios 将发出 CRITICAL 状态(红色)。插件返回值在第六章(第 6 页)的开头描述,基础插件 check_icmp 在 6.2 使用 Ping 进行可达性测试的第 108 页中详细介绍。
max_check_attempts
这指定了 Nagios 应该多久重复一次测试,以验证和最终接受已发现(或已恢复的功能)的错误状态,即将其识别为硬状态。在过渡阶段(例如从 OK 到 CRITICAL),我们称之为软状态。软和硬之间的基本区别仅由 Nagios 通知系统做出,这就是为什么这两个状态在系统上下文中被更详细地描述(见第十二章,第 265 页)。这种差异对 Web 界面的表示没有影响。
`normal_check_interval
这指定了当系统处于稳定状态时,Nagios 应该以什么间隔测试服务——这可以同样是一个 OK 或错误状态。在示例中,这是五个时间单位,通常是五分钟。在 Nagios 3.0 中,该参数也可以写成check_interval;与主机定义一样,两种形式是等效的。
retry_check_interval
这描述了在状态正在变化的过程中(例如,从 OK 到 WARNING),即存在软状态时,两次测试之间的时间间隔。在 Nagios 3.0 中,该参数也可以写成retry_interval;两种形式是等效的。
一旦 Nagios 执行了在max_check_attempts中指定的测试次数,它就会以normal_check_interval的间隔再次检查服务。
check_period
这描述了服务需要被监控的时间段。条目代表一个timeperiod对象,其定义在 2.10 使用 timeperiod 定义时间周期中详细描述,见第 74 页。在此处,你应该输入24×7表示“全天候”,除非你希望明确停止在特定时间运行测试(可能是因为计划中的维护时段)。如果只想在特定时间防止通知,则最好使用notification_period或其他 Nagios 通知系统的过滤器(见第十二章,第 265 页)。
notification_interval
这决定了 Nagios 在什么规律的时间间隔重复报告错误状态。在示例中,只要错误状态持续,系统就会每 120 个时间单位(通常是分钟)这样做。0的值会导致 Nagios 只宣布当前状态一次。从 Nagios 3.0 开始,notification_interval不再是必选参数。如果它缺失,则值将从相关的主机定义中获取。
notification_period
这描述了通知应在其中发生的时间段。这又涉及到一个timeperiod对象(参见 2.10 使用 timeperiod 定义时间段)。在此示例中,24×7被使用,因此通知将全天发送。关于notification_period参数的更详细讨论可以在 12.3 消息过滤器的第 267 页中找到。从 Nagios 3.0 开始,此参数是可选的。如果缺失,则值将从伴随的主机定义中获取。
notification_options
这决定了 Nagios 应报告哪些错误状态。在此处可以使用与主机对象中已描述的相同状态,即c(严重),w(警告),u(未知),r(恢复),f(波动),以及(从 Nagios 3.0 开始)s(计划维护间隔)。指定c,r仅当服务处于严重状态并随后恢复(恢复)时通知系统。
如果使用n(无)作为值,Nagios 通常不会发送任何通知。但 Web 界面仍然显示当前状态。
contact_groups
最后,此参数定义了应接收通知的接收者组。可以输入多个组,用逗号分隔。从 Nagios 3.0 开始,此参数可以省略。然后值将从伴随的主机定义中获取。
更多信息可以在 Nagios 3.0 在线帮助中找到,请访问localhost/nagios/docs/objectdefinitions.html#service.^([35]) 对于 2.x 版本,文件名为xodtemplate.html。Nagios 2.x 和 Nagios 3.0 之间的差异在 H.1.2 服务对象的第 680 页中描述。
^([35]) 相应的文件在安装后位于目录/usr/local/nagios/share/docs/。
2.6 使用servicegroup组合服务
服务组,就像主机组一样,将多个服务组合成一个组,以便可以在 Web 前端一起表示。这增加了清晰度并简化了某些评估,但这是可选的,不建议在开始时使用,以保持配置简单。
# -- /etc/nagios/mysite/servicegroups.cfg
define servicegroup{
**servicegroup_name** all-ping
**alias** All Pings
**members** linux01, PING, linux02, PING
servicegroup_members(*) servicegroup1, servicegroup2
}
servicegroup_name和alias与主机组的含义相同。应注意的是,语法与members条目相同。因为 Nagios 中的服务始终由主机和服务的组合组成,所以两者必须始终成对列出。首先是计算机,然后是服务:
members `hostl`,`servicel`,`host2`,`service2`, ...
如果在服务定义中使用 servicegroups 参数,则可以省略 members 细节(2.5 使用服务定义要监控的服务)。如果您愿意,可以将这两种可能性结合起来使用。至于宿主组,从 Nagios 3.0 开始,可以使用参数 service-group_members 形成服务组层次结构。
2.7 定义错误消息的接收者:contact
联系人基本上是消息通过联系人组发送的接收者:
# -- /etc/nagios/mysite/contacts.cfg
define contact{
**contact_name** nagios
**alias** Nagios Admin
**host_notification_period** 24×7
**service_notification_period** 24×7
**service_notification_options** w, u, c, r
**host_notification_options** d, u, r
service_notification_commands notify-by-email
host_notification_commands host-notify-by-email
**email** nagios-admin@localhost
can_submit_commands(*) 1
}
在认证过程中,联系人也扮演着角色:仅在 Web 前端登录的用户只能看到将联系人输入为该用户的宿主和服务。因此,登录 Web 界面的用户必须与这里指定的 contact_name 值相同。第一次使用时,用户 nagios 就足够了。
contact_name
此参数定义用户名。它必须与密码文件 htpasswd 中的对应用户名匹配。
alias
此参数简要描述联系人。这里允许使用空格。
host_notification_period
此定义了在哪个时间段内可以发送关于计算机可达性的消息。 12.3 消息过滤器(第 267 页)展示了如何在不同对象类型中合理地组合时间段细节。一开始,值 24×7(即:总是)当然不是一个坏选项。
service_notification_period
此定义了 Nagios 向相关用户服务发送通知的时间段。条目作为过滤器生效:如果消息在指定时间段外发送,则简单地丢弃生成的消息。如果没有后续消息,联系人将保持不知情。因此,您必须考虑在各个不同的定义中组合个别时间段。依赖关系在 12.3 消息过滤器 中有详细描述。
host_notification_options
此定义了用户应接收哪些类型的宿主消息。这里使用的选项与宿主参数 notification_options 相同 (2.3 定义要监控的机器,使用宿主).
service_notification_options
此参数描述了联系人接收哪些类型的服务消息。涉及到的五个值与服务和宿主对象的 notification_options 参数相同。
service_notification_commands
此参数定义了哪些命令(一个或多个)负责通知。它们必须定义为command对象类型(见 2.9 当 Nagios 需要做某事时:command对象);基本上任何外部程序都可以集成。
host_notification_commands
与service_notification_commands类似,此参数指定了发送通知时要执行哪些命令,尽管这里它关注的是计算机的可达性。
email
这指定了一个或多个应发送消息的电子邮件地址(以逗号分隔)。通知命令可以评估此值(此示例之一是命令notify-by-email^([36]))。
can_submit_commands(Nagios 3.0)
这控制了联系人是否可以通过 Web 界面执行命令。值0禁止他们这样做。对于 Nagios 2.x,通常任何联系人都可以通过 Web 界面运行命令(见 16.2.3 外部命令接口:cmd.cgi,第 343 页)。从 Nagios 3.0 开始,此参数现在还允许定义具有只读权限的联系人。
更多信息可以在 Nagios 3.0 在线帮助中找到,网址为localhost/nagios/docs/objectdefinitions.html#contact。在 Nagios 2.x 中,该文件称为xodtemplate.html。Nagios 2.x 和 Nagios 3.0 之间的差异在 H.1.4 联系人对象中描述,第 681 页。
^([36]) 见表 12-1 第 277 页
2.8 消息接收者:`contactgroup
contactgroup作为通知系统和单个联系人之间的接口。Nagios 在各个对象定义中从不直接针对单个联系人,而是始终通过联系人组进行。
此外,Nagios 还期望一个名称(contactgroup_name)和一个注释(alias),这向网站访客揭示了该组的目的。对于组的成员(members),您可以输入单个联系人或多个联系人的逗号分隔列表:
# -- /etc/nagios/mysite/contactgroups.cfg
define contactgroup{
**contactgroup_name** localadmins
**alias** Local Site Administrators
**members** nagios
contactgroup_members(*) contactgroup1,contactgroup2
}
额外的参数contactgroup_members允许 Nagios 3.0 将其他联系人组作为成员包含在内。在 Nagios 2.x 中,此参数不可用。
2.9 当 Nagios 需要做某事时:command对象
Nagios 所做的每一件事都是由 command 对象定义的。在提供的示例文件中,checkcommands.cfg 定义了一系列需要包含的命令。为此,你只需将文件复制到子目录 mysite 即可:^([37])
nagios@linux:/etc/nagios$ **cp objects/checkcommands.cfg** \ **mysite/checkcommands.cfg**
现有的命令 check_ping 说明了这种对象类型的定义:
# -- /etc/nagios/mysite/checkcommands.cfg
...
define command{
**command_name** check_ping
**command_line** $USER1$/check_icmp -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$
-p 5
}
...
check_ping 是在定义服务时将使用的命令名称。command_line 描述了要执行的命令。这里不仅使用了旧的插件 check_ping,还使用了更高效的 check_icmp。这两个之间的区别在 6.2 使用 Ping 进行可达性测试的第 108 页有更详细的解释,但它们在很大程度上使用相同的参数。
这里使用并由美元符号包围的标识符是宏。Nagios 识别三种不同类型的宏:$USERx$ 宏(*x* 可以取 1 到 32 之间的值)定义文件 resource.cfg。属于这一类的宏有包含插件目录路径的 $USER1$。
第二组宏是在调用命令时可以传递的参数。这些包括 $ARG1$ 和 $ARG2$。
Nagios 定义的第三组包括宏 $HOSTADDRESS$,它引用主机定义中的主机 IP 地址(即参数 address)。这种类型的宏在在线帮助localhost/nagios/docs/macros.html中有文档说明。
如果你调用服务 linux01,在 2.4 使用 hostgroup 将计算机分组中定义的 PING 作为 check_command
check_ping!100.0,20%!500.0,60%
那么 100.0,20% 将出现在 $ARG1$ 中,而 500.0,60% 将出现在 $ARG2$ 中。为了分隔命令和要传递的参数,使用感叹号。
理论上,可以通过 command_line 启动任何程序,但 Nagios 期望在这里有特定的行为,尤其是关于返回值。因此,应仅使用 Nagios 插件(参见第六章到第九章)。
^([37]) 在 Nagios 2.0 中,示例文件位于目录 /etc/nagios 中。
2.10 使用 timeperiod 定义时间段
timeperiod 对象描述了 Nagios 生成和/或发送通知的时间段。包含的示例文件(Nagios 3.0: objects/timeperiods.cfg;Nagios 2.x: localhost.cfg) 包含了一些定义,可以直接复制到你的 timeperiods.cfg 文件中。
在这里,24×7 的定义是“每周日到周六,每天从 0 点到 24 点:”
# -- /etc/nagios/mysite/timeperiods.cfg
define timeperiod{
**timeperiod_name** 24×7
**alias** 24 Hours A Day, 7 Days A Week
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
}
单个工作日的时间也可以通过逗号分隔的时间段“拼凑”出来:
define timeperiod{
...
Monday 00:00-09:00,12:00-13:00,17:00-24:00
...
}
如果完全省略了日指定,则定义的时间段将不包括该日。
Nagios 3.0 允许定义个别日历日的时间段:
2007-12-24 08:00-12:00
may 1 00:00-24:00
monday 2 may 00:00-24:00
monday 3 00:00-24:00
...
2007-12-24 - 2008-01-08 / 2 00:00-24:00
第一行以 ISO 格式命名固定的日历日,第二行描述每年的 5 月 1 日。第三行的细节指的是五月的第二个星期一,第四行的细节指的是每月的第三个星期一。细节也可以组合,形式为*`from - to`*。随后的/作为分隔符:第六行描述从 2007 年 12 月 24 日到 2008 年 1 月 8 日的每第二个工作日(/ 2)。
H.1.5 时间定义,第 682 页也致力于 Nagios 3.0 的扩展格式。完整的文档可以在 Nagios 3.0 在线帮助中找到,网址为localhost/nagios/docs/objectdefinitions.html#contact。在 Nagios 2.x 中,相应的文件称为xodtemplate.html。
2.11 模板
Nagios 将定义分类为对象,这是有很好的理由的:它们的特性可以被其他对象继承——这是一个可以节省大量打字时间的特性。您可以定义一个所谓的模板,并将其传递给其他对象作为基础,您只需要描述那些不同的细节。
这最好通过一个例子来说明(用于模板使用的必需参数以粗体打印):
# -- /etc/nagios/mysite/hosts.cfg
define host{
**name** **Generic-Host**
**register** **0**
check_command check-host-alive
max_check_attempts 3
check_period 24×7
contact_groups localadmins
notification_interval 120
notification_period 24×7
notification_options d, u, r, f
}
使用name,模板首先被赋予一个名称,以便稍后引用。接下来的条目register 0阻止 Nagios 尝试将此模板视为真实的主机。在示例中,真实主机对象的条目不足;因此,当读取配置文件时,Nagios 会中断,错误信息指出缺少此类定义所必需的参数,例如:
Error: Host name is NULL
所有其他参数涉及应用于所有依赖于Generic-Host的定义的设置。
在实际主机定义中——以下示例为linux03和linux04——参数use引用模板并因此继承预设值:
# -- /etc/nagios/mysite/hosts.cfg
define host{
host_name linux03
**use** **Generic-Host**
alias Linux File Server
address 192.168.0.1
}
define host{
host_name linux04
**use Generic-Host**
alias Linux Print Server
address 192.168.0.2
}
这样,您只需要完成那些在两个主机之间有差异的条目。
但是,参数也可能出现在已经由模板定义的主机定义中。在这种情况下,主机的定义具有优先权,它覆盖了模板中的值。
以这种方式创建的模板通常可以用于所有对象类型。有关它们的使用信息,请参阅 Nagios 3.0 在线帮助中的 localhost/nagios/docs//objectinheritance.html.^([38]) 在 Nagios 2.x 中,该文件被称为 templaterecursion.html。Nagios 3.0 的扩展功能,这些功能仅在更复杂的设置中开始发挥作用,由 H.1.8 继承 从第 684 页描述。
^([38]) 本地位于 /usr/local/nagios/share/docs//objectinheritance.html。
2.12 为那些懒得输入的人提供的配置辅助
2.12.1 为多台计算机定义服务
通过同时为多个主机或甚至主机组定义服务,您可以在服务定义中大大简化事情:
# -- /etc/nagios/mysite/services.cfg
define service{
**host_name** linux01,linux02,linux04,...
service_description PING
...
}
通过逗号分隔的多个主机确保 Nagios 并行定义多个服务。您可以通过指定 * 字符而不是单个计算机别名来更进一步。这将把此服务分配给所有主机。
第三种可能性是通过主机组并行分配:
# -- /etc/nagios/mysite/services.cfg
define service{
**hostgroup_name** linux-servers,windows-servers
service_description PING
...
}
在这种情况下,使用 hostgroup_name 参数而不是 host_name 参数。
2.12.2 为所有计算机使用一个主机组
使用通配符 * 描述包含所有定义计算机的主机组是最快的方法:
# -- /etc/nagios/mysite/hostgroups.cfg
define hostgroup{
hostgroup_name all-hosts
**members ***
...
}
2.12.3 其他配置辅助工具
实际上,2.11 模板 中描述的覆盖多个主机的服务定义迄今为止是最重要的。但还有其他基于升级和依赖对象的配置辅助工具,这些工具在 在不同时间通知不同的管理员 (参见第 282 页的 12.5 升级管理 和第 285 页的 12.6 主机和服务的依赖关系会计 12.6) 中介绍。在那里,您也可以使用 hostgroup_name 代替 host_name (主机组列表) 或 servicegroup_name 代替 service_description。此外,您还可以为 host_name 和 service_description 设置 * 值,这涵盖了所有主机或服务。
2.13 在 cgi.cfg 中的 CGI 配置
为了使 Web 前端正常工作,Nagios 需要配置文件 cgi.cfg。Nagios 的示例文件最初可以逐个继承,因为安装期间其中包含的路径已经正确设置:
nagios@linux:/etc/nagios$ **cp sample/cgi.cfg-sample ./cgi.cfg**
重要:文件 cgi.cfg 必须位于与文件 nagios.cfg 相同的目录中,因为 CGI 程序已经永久编译在此路径。如果 cgi.cfg 位于不同的目录,Web 服务器也必须提供一个包含正确路径的环境变量,称为 NAGIOS_CGI_CONFIG。Apache 中如何设置,请参阅相应的在线文档.^([39])
默认情况下,CGI 配置文件中启用了几个参数。这些参数是什么可以通过以下 egrep 命令揭示,该命令排除了注释和空行:
nagios@linux:/etc/nagios$ **egrep -v '^$|^#' cgi.cfg-sample | less**
main_config_file=/etc/nagios/nagios.cfg
physical_html_path=/usr/local/nagios/share
url_html_path=/nagios
show_context_help=0
use_authentication=1
...
main_config_file
此参数指定主配置文件。
physical_html_path
这指定了文件树中包含 HTML 文档(包括在线文档、图像和 CSS 样式表)的目录的绝对路径。
url_html_path
这也描述了 Nagios HTML 文档的路径,但是从 Web 服务器的角度,而不是操作系统的角度。
show_context_help
此选项在开启(值 1)的情况下提供上下文相关的帮助,如果你在 Web 界面上将鼠标移至单个链接或按钮上。
use_authentication
此选项应始终开启(值 1)。Nagios 将只允许认证用户访问。认证本身在 CGI 目录中的 .htaccess 文件中配置(请参阅第 47 页的 1.5 Web 界面的配置)。如果此文件缺失,并且 use_authentication=1,则 CGI 程序将拒绝工作。
default_statusmap_layout 和 default_statuswrl_layout
这两个布局参数描述了网络依赖性图形表示的形式。可能的值在第 608 页的 A.2 cgi.cfg 中的 CGI 配置中描述。
refresh_rate
这指定了浏览器被指示从 Web 服务器重新加载数据的秒数间隔。这样,浏览器中的显示总是最新的。
authorized_for_all_services and authorized_for_all_hosts
为了使特定用户从一开始就能在 Web 界面上看到所有计算机和服务,而不考虑主机和服务的正确联系人组分配,您还应在文件 cgi.cfg 中激活以下两个参数:
authorized_for_all_services=nagios
authorized_for_all_hosts=nagios
Web 用户(和联系人)nagios 现在能够在 Web 界面上看到所有主机和所有服务,即使他没有被登记为所有主机或服务的联系人。
所有参数的完整列表可以在第 606 页的 A.2 cgi.cfg 中的 CGI 配置中找到。
^([39]) httpd.apache.org/docs-2.0/env.html
2.14 资源文件 resource.cfg
Nagios 期望在资源文件 resource.cfg 中找到宏的定义,关于它们如何用于创建命令对象(2.9 当 Nagios 需要执行某些操作时:命令对象,第 72 页),这也可以作为默认设置使用。
Nagios 应该在主配置文件 nagios.cfg 中的 resource.cfg 参数定义的位置搜索此文件。在这里使用与 nagios.cfg 相同的目录是有意义的。
在其“出厂设置”中,resource.cfg 仅定义了 $USER1$ 宏,它包含插件的路径:
$USER1$=/usr/local/nagios/libexec
总的来说,Nagios 提供了 32 个可自由定义的 $USERx$ 宏,其中 *`x`* 可以从 1 到 32。这些宏与密码结合使用时非常有用,例如:通过这样的宏在文件 resource.cfg 中定义密码,该文件可能只能由用户 nagios 读取。定义的宏用于实际的服务定义中,从而隐藏密码,不让好奇的旁观者看到。
第三章:启动
一旦安装了 Nagios 和插件,Apache 已经设置了 Web 界面,并创建了一个最小配置,如之前所述,系统操作就可以开始了。如果你还没有这样做,建议你首先花一些时间测试 check_icmp 插件,如 1.4 安装和测试插件(第 43 页)中所述,以检查初始配置。
3.1 检查配置
通常以守护进程运行并持续收集数据的 nagios 程序,也可以用来测试配置:
nagios@linux:~$ **/usr/local/nagios/bin/nagios -v /etc/nagios/nagios.cfg**
Nagios 3.0rc1
Copyright (c) 1999-2007 Ethan Galstad (http://www.nagios.org)
Last Modified: 12-17-2007
License: GPL
Reading configuration data...
Running pre-flight check on configuration data...
Checking services...
Checked 2092 services.
Checking hosts...
Warning: Host 'eli-sw01' has no services associated with it!
Checked 183 hosts.
Checking host groups...
Checked 55 host groups.
Checking service groups...
Checked 34 service groups.
Checking contacts...
Checked 59 contacts.
Checking contact groups...
Checked 7 contact groups.
Checking service escalations...
Checked 0 service escalations.
Checking service dependencies...
Checked 24 service dependencies.
Checking host escalations...
Checked 0 host escalations.
Checking host dependencies...
Checked 0 host dependencies.
Checking service groups...
Checked 34 service groups.
Checking contacts...
Checked 59 contacts.
Checking contact groups...
Checked 7 contact groups.
Checking service escalations...
Checked 0 service escalations.
Checking service dependencies...
Checked 24 service dependencies.
Checking host escalations...
Checked 0 host escalations.
Checking host dependencies...
Checked 0 host dependencies.
Checking commands...
Checked 105 commands.
Checking time periods...
Checked 6 time periods.
Checking for circular paths between hosts...
Checking for circular host and service dependencies...
Checking global event handlers...
Checking obsessive compulsive processor commands...
Checking misc settings...
Total Warnings: 1
Total Errors: 0
Things look okay - No serious problems were detected during the pre-flig
ht check
虽然这里显示的警告原则上可以忽略,但这并不总是发明者的初衷:也许你在配置中犯了一个错误,Nagios 正在忽略一个特定的对象,而你实际上想使用它。
如果你没有为主机定义任何服务,例如,Nagios 将发出警告,如上面 eli-sw01 的示例所示。因此,建议为每个主机定义一个“PING”服务,尽管这不是绝对必要的。即使这里使用的插件 check_icmp 与主机检查相同,但这并不是一回事。主机检查只需要一个响应数据包——毕竟,它只想知道主机“是否存活”。作为服务检查,check_icmp 记录数据包运行时间和丢失率,如果需要,可以用来得出有关网卡现有问题的结论。
与警告不同,真正的错误必须消除,因为如果解析器发现错误,Nagios 通常不会启动,如下面的例子所示:
Error: Could not find any host matching 'linux03'
Error: Could not expand hostgroups and/or hosts specified in service
(config file '/etc/nagios/mysite/services.cfg', starting on line 0)
***> One or more problems was encountered while processing the config files...
在这里,配置错误地包含了一个名为linux03的宿主,对于这个宿主没有定义。如果你仔细阅读错误信息,你会很快意识到错误可以在文件/etc/nagios/mysite/services.cfg中找到。
在独立性的定义中(宿主和服务依赖性;参见 12.6 宿主和服务之间依赖性的考虑,第 285 页)存在一个基本的风险,即可能会错误地指定循环依赖性。因为 Nagios 无法自动解决这样的依赖性,所以在启动之前也会进行检查,并在必要时显示错误。
当使用parents参数时,也可能出现两个宿主无意中相互作为“父宿主”的情况;Nagios 也会测试这一点。
3.2 开始监控
在 Nagios 安装过程中,命令
linux:src/nagios # **make install-init**
...
在包含启动脚本的目录中保存启动脚本,通常是/etc/init.d。
3.2.1 手动启动
如果配置测试没有错误运行,Debian、Ubuntu 和 OpenSuSE 上的 Nagios 首先使用此脚本手动启动:
linux:~ # **/etc/init.d/nagios start**
Fedora 提供自己的启动机制:
linux:~ # **service nagios start**
如果这里一切顺利(可以通过运行 Web 界面进行检查——参见 3.3 Web 界面概述,第 85 页),你只需确保脚本在系统启动时执行。根据发行版的不同,所需的步骤在 1.3 自动启动 Nagios,第 43 页中描述。
3.2.2 使配置更改生效
如果进行配置更改,每次都不需要也不建议重新启动 Nagios。相反,你只需执行重新加载:
linux:~ # **/etc/init.d/nagios reload**
这会导致 Nagios 重新读取配置,结束不再存在的宿主和服务的测试,并将新的计算机和服务集成到测试中。然而,每次重新加载都会重新安排检查计划,这意味着 Nagios 计划重新执行所有测试。
为了防止所有测试在启动时同时开始,Nagios 执行所谓的分散。在这里,服务器将测试的开始时间分散在可配置的期间内.^([40]) 因此,对于大量服务,Nagios 在继续特定服务的测试之前可能需要一段时间。因此,你绝对不应该在短时间内运行重新加载:在最坏的情况下,Nagios 可能无法在间隔期间执行某些检查,而只能在最近一次重新加载后一段时间内执行。
在重新加载之前,配置被测试以消除任何现有错误,如 3.1 检查配置中所示。
^([40]) 相关的配置参数被称为max_host_check_spread和max_service_check_spread,见 A.1 主配置文件 nagios.cfg,第 599 页。
3.3 网络界面概览
当 Nagios 守护进程正在运行时,在浏览器中调用 URL nagios-server/nagios,您将被带到图 3-1 中所示的欢迎屏幕。

图 3-1. 启动屏幕
所说的“战术概览”(战术概览),可以通过左侧菜单栏中的第一个monitoring链接访问,如图图 3-2 所示。它总结了所有测试系统的状态。
然而,在实践中,菜单项Service Problems(图 3-3)的显示要有趣得多。它记录了当前引起问题的服务,那些不在 OK 状态的服务,这正是 Nagios 被构思的意义:精确地通知管理员任何问题。

图 3-2. “战术”概览所有要监控的系统和服务

图 3-3. Nagios:所有服务问题的总结
第一列命名了涉及的主机。如果这有一个灰色背景,Nagios 原则上可以访问该计算机。如果主机“down”,这可以通过红色背景看到。对于服务,红色表示 CRITICAL,黄色表示 WARNING。
第二列提供服务名称,第三列再次显示状态,以纯文本形式。第四列指定上次检查的时间。第五列很有趣——它显示了当前状态持续了多长时间。
标题为Attempt的第六列揭示了 Nagios 已经进行了多少次测试(不成功):3/3意味着错误状态已经连续确认了三次,但如果存在错误,测试只进行三次(参数max_check_attempts,见 2.3 定义要监控的机器,包括主机)。
最后,最后一列将插件信息传递给管理员,管理员会详细描述当前状态。在图 3-3 中的上述行警告说,Windows 服务器 ELISAN01 的 D 驱动器(服务DISK_D)上只剩下 21%的磁盘空间。

图 3-4. 所有主机的概述 (摘录)
Host Detail (图 3-4")) 和 Service Detail 概述提供了所有主机和服务的概述。在实际操作中,您将更精确地查找信息,无论是通过单个主机还是主机组或服务组。相关名称输入到显示主机搜索字段中。图 3-5") 使用elix01主机作为示例展示了这一点。
或者,您可以搜索主机和服务组的名称。这里的一个有趣变化是,通过链接Hostgroup Grid显示的状态网格输出,它显示了所有主机及其对应服务的概述,以及这些服务的状态(图 3-6). 通过服务的颜色(绿色/黄色/红色),您可以一眼看出您正在查看的服务组或主机组中是否存在问题。

图 3-5. 对主机 elix01 的服务 (摘录)

图 3-6. 在网格表示中的主机组 eliLINUX
第二部分:更详细地...
第四章:Nagios 基础
如果一个主机可以访问,但上面没有运行任何依赖的服务,那么这个事实本身几乎没有意义。因此,Nagios 中的所有内容都围绕着服务检查展开。毕竟,没有主机就无法运行服务。如果主机计算机失败,它就无法提供所需的服务。如果,例如,一个位于用户和提供服务的系统之间的路由器被引入,事情会变得稍微复杂一些。如果这个路由器失败了,目标主机上可能仍然运行着所需的服务,但对于用户来说,它仍然无法访问。
Nagios 能够重现这样的依赖关系,并精确地通知管理员一个重要网络组件的故障,而不是让管理员被无法访问的服务的不相关错误信息淹没。理解这些依赖关系对于 Nagios 的平稳运行至关重要,这就是为什么 4.1 考虑网络拓扑 将会详细检查这些依赖关系以及 Nagios 的工作方式。
另一个重要的事项是主机或服务的 状态。一方面,Nagios 允许比仅仅 OK 或 "not OK" 更精细的区分;另一方面,软状态 和 硬状态 之间的区分意味着管理员不必处理那些在管理员收到信息时早已消失的短期中断。这些状态也会影响服务检查的强度。这种功能是如何工作的将在 4.3 主机和服务的状态 中详细描述。
4.1 考虑网络拓扑
Nagios 如何处理主机和服务的依赖关系,可以通过一个例子来最好地说明。图 4-1 表示一个包含要监控的 proxy 上的域名服务的小型网络。

图 4-1. 示例网络的拓扑
服务检查始终是系统定期执行的监控的起点。只要服务可以访问,Nagios 就不会采取进一步措施;也就是说,它不会执行任何主机检查.^([41])
对于 switch1、switch2 和 proxy,这样的检查无论如何都是没有意义的,因为如果 DNS 服务对 proxy 响应,那么提到的主机将自动可访问。
然而,如果域名服务失败,Nagios 将通过主机检查测试相关的计算机,以查看是服务还是主机导致了问题。
如果proxy无法访问,Nagios 可能会测试配置中输入的parent主机(图 4-2)。通过parents主机参数,管理员可以提供有关网络拓扑结构的信息给 Nagios。

图 4-2. 服务失败后执行的测试顺序
在进行此操作时,管理员只需为每个主机输入与 Nagios 服务器同一路径上的直接相邻计算机作为父节点。42] 同一网络段内分配的主机定义为没有父节点。对于图 4-1 中的网络拓扑,相应的配置(简化为主机名和父节点)如下所示:
define host{
host_name proxy
...
**parents switch2**
}
define host{
host_name switch2
...
**parents switch1**
}
define host{
host_name switch1
...
}
switch1位于与 Nagios 服务器相同的网络段中,因此没有分配父计算机。属于网络段的是一种观点。如果您将交换机解释为段限制,就像这里的情况一样,这有一个优点,即可以更紧密地隔离中断。但您也可以有不同的看法,将 IP 子网解释为段。那么,路由器就会形成段限制;在我们的例子中,proxy就会计入与 Nagios 服务器相同的网络。然而,将无法区分proxy的故障与switch1或switch2的故障。

图 4-3. Nagios 对单个网络节点的分类
如果示例中的switch1失败,图 4-3 显示了 Nagios 执行的顺序。首先,系统检查proxy上的 DNS 服务并确定该服务已无法访问(1)。为了区分,它现在执行主机检查以确定proxy计算机的状态(2)。由于proxy无法访问,但它有switch2作为父节点,Nagios 在switch2上执行主机检查(3)。如果这个交换机也无法访问,系统会检查其父节点,即switch1(4)。
如果 Nagios 能够与switch1建立联系,那么proxy上 DNS 服务失败的故障原因就可以隔离到switch2。系统相应地指定了主机的状态:switch1是 UP 状态,switch2是 DOWN 状态;另一方面,proxy是不可达的。通过适当配置 Nagios 消息系统(参见第 267 页的 12.3 消息过滤器),你可以使用这种区别来确定,例如,只有当主机处于 DOWN 状态并代表实际问题时,管理员才会被通知,而不是通知那些依赖于 DOWN 主机的其他主机。
在进一步的操作中,Nagios 可以确定网络中的其他拓扑特定故障(所谓的网络中断)。proxy是gate的父节点,因此gate也被表示为 UNREACHABLE(5)。gate反过来又作为父节点;依赖于这个节点的互联网服务器也被分类为“UNREACHABLE”。
这种“智能”,即 Nagios 所特有的,当更多主机和服务依赖于一个失败的组件时,对管理员帮助就更大了。对于一个骨干网中的路由器,它依赖于数百个主机和服务,系统会通知管理员具体的故障,而不是发送数百条本质上没有错误但实际对消除故障没有帮助的错误消息。
^([41]) 第 95 页的 4.2 按需主机检查与定期可达性测试讨论了这些按需检查。
^([42]) 参数名称parents可以通过以下事实来解释:存在一些场景——例如在高可用性环境中——其中主机有两个上游路由器来保证互联网连接,例如。
4.2 按需主机检查与定期可达性测试的比较
原则上,Nagios 定期执行服务检查,除了被动服务检查。 (参见第 293 页的 13.2 被动服务检查。)对于主机检查,有一些稍微不同的规则适用,因为它们扮演着主要角色。Nagios 在需要时执行主机检查——也就是说,按需——并使用它们来监控那些安装了服务的状态变为错误状态的主机,或者那些与失败主机存在拓扑依赖关系的主机。第三种方式是通过主机依赖性,如第 289 页的 12.6.2 仅在异常情况下:主机依赖性所述。按需主机检查是 Nagios 的核心功能,因为这是系统唯一能够精确通知管理员一个失败的中央交换机,而不是用成千上万关于不可达服务的错误消息轰炸他的方式。
定期间隔计划的主机检查——在 Nagios 术语中称为主动主机检查——只扮演了较小的角色。尽管 Nagios 2.0 确实提供了一种实现这种方式的方法,但 Nagios 2.x 只以串行方式执行主动主机检查,这被认为是一个真正的性能杀手。
在 Nagios 3.0 中,检查是同时执行的,消除了早期版本性能下降的问题。如果使用 3.0 之前的 Nagios 版本,建议不要使用主动主机检查。然而,在 Nagios 3.0 中,像这样的常规主机检查可以帮助提高性能,因为该版本可以缓存检查结果,如果需要,可以指定缓存时间。Nagios 在需要时将回退到缓存的结果,从而节省大量时间——前提是这些结果仍然足够最新。Nagios 3.0 中主机检查的新逻辑在第 689 页的 H.7 主机检查的新逻辑中进行了处理。
在 Nagios 2.x 中,可以通过使用基于 ping 的服务检查技巧来定期检查主机的可达性(参见第 108 页的 6.2 使用 Ping 进行可达性测试)。Nagios 并行执行服务检查,因此在 Nagios 2.x 下的性能下降问题得到了缓解。同时,你还可以获得更多额外信息,如响应时间或可能的丢包,这为网络负载或可能的网络问题提供了间接线索。另一方面,主机检查即使在许多数据包丢失且网络性能极差的情况下也会发出 OK 状态。正如“主机检查”这个名字所暗示的,这里涉及到的仅仅是原则上可达性,而不是连接质量。
4.3 主机和服务的状态
Nagios 使用插件进行主机和服务检查。它们提供四种不同的返回值(参见第 105 页的表 6-1):0(OK),1(WARNING),2(CRITICAL),和3(UNKNOWN)。
返回值 UNKNOWN 表示插件运行通常出错,可能是由于参数错误。通常可以指定插件启动时发出警告或临界状态的情况。
Nagios 通过插件的返回值来确定服务和主机的状态。服务状态与返回值 OK、WARNING、CRITICAL 和 UNKNOWN 相同。对于主机来说,情况略有不同:UP 状态描述了一个可达的主机,DOWN 表示计算机已关闭,而 UNREACHABLE 指的是不可达状态,此时 Nagios 无法测试主机是否可用,因为父节点已关闭(参见 4.1 考虑网络拓扑,第 92 页)。
此外,Nagios 在两种状态之间做出区分:软状态和硬状态。如果问题首次发生(即,直到现在服务的状态都没有问题),则程序最初将该新状态分类为软状态,并重复测试几次。可能的情况是,错误状态只是短暂的事件,稍后就被消除了。只有当错误在多次测试后仍然存在时,Nagios 才将其分类为硬状态。管理员只会被告知硬状态,因为涉及短期中断的消息,而这些中断随后又立即消失,只会导致信息的不必要泛滥。
在我们的示例中,可以非常简单地说明服务状态的时间序列。使用以下参数的服务用于此目的:
define service{
host_name proxy
service_description DNS
...
**normal_check_interval**[43] **5**
**retry_check_interval**[44] **1**
**max_check_attempts** **5**
...
}
normal_check_interval 指定了 Nagios 在服务状态正常或存在硬状态时应检查相应服务的间隔——在这种情况下,每五分钟检查一次。retry_check_interval 定义了软状态期间两次服务检查之间的间隔——在示例中为 一分钟。如果发生新的错误,Nagios 将在更短的间隔内更仔细地检查服务。
max_check_attempts 确定了在首次发生错误后服务检查应重复的次数。如果达到 max_check_attempts 并错误状态持续,Nagios 将在 normal_check_interval 中指定的间隔内再次检查服务。
图 4-4 以图形形式表示了时间序列的进展。插图从 OK 状态(这始终是硬状态)开始。通常 Nagios 将在五分钟间隔内重复服务检查。十分钟时发生错误;状态变为 CRITICAL,但最初是软状态。此时,Nagios 尚未发出任何消息。
现在,系统以 retry_check_interval 中指定的间隔检查服务。这里是一分钟。在总共五次(如 max_check_attempts 中指定)检查并得到相同结果后,状态从软状态变为硬状态。只有现在 Nagios 才会通知相关人员。现在测试将以 normal_check_interval 中指定的间隔重复进行。

图 4-4. 监控服务状态时间序列的示例
在下一次测试中,服务再次可用;因此其状态从 CRITICAL 变为 OK。由于 OK 状态始终是硬状态,因此这种变化不会受到 Nagios 在更短间隔内进行的任何测试的影响。
服务在硬状态错误后过渡到 OK 状态被称为硬恢复。系统会通知管理员这一点(如果配置了这样做),以及各种错误相关联的硬状态之间的变化(例如从 WARNING 到 UNKNOWN)。如果服务从错误软状态恢复到正常状态(OK),也称为软恢复,管理员将不会收到通知。
即使消息系统省略了软状态并切换回软状态,它仍然会在 Web 界面和日志文件中记录这些状态。在 Web 前端,可以通过2/5的值出现在尝试列中来识别软状态。这意味着max_check_attempts期望五个尝试,但到目前为止只进行了两个。在硬状态下,max_check_attempts在相应的位置列出两次,在示例中是5/5。
对于 Web 界面中的管理员来说,比状态是否仍然是“软”还是已经“硬”的区别更重要的是持续时间列中的错误状态持续时间。从这个数据可以更好地判断整体问题可能有多大。
对于由于主机故障而不可用的服务,尝试列中会出现 1/5 的条目,因为 Nagios 不会重复进行服务检查,直到整个主机再次可访问。计算机的故障可以通过 Web 界面中的颜色更容易地识别:3.3 Web 界面概述中的服务概览图用红色标记失败的宿主;如果计算机可访问,背景保持灰色。
^([43]) 作为一种替代,Nagios 3.0 允许使用从主机定义中已知的表示法,check_interval。
^([44]) 对于 Nagios 3.0,你可以使用retry_interval作为替代。
第五章。服务检查及其执行方式
为了测试服务,Nagios 使用称为插件的外部程序。在最简单的情况下,这涉及到测试一个互联网服务,例如 SMTP。在这里,服务可以通过网络直接访问,因此只需要在 Nagios 服务器上调用一个测试远程主机上邮件服务器的本地程序就足够了。
并非所有你可能想要测试的内容都可以通过网络轻松访问;例如,没有网络协议可以用来检查硬盘的空闲容量。在这种情况下,你必须通过远程 shell 在远程主机上启动一个插件(但首先这个插件必须安装在远程计算机上),或者使用其他方法,例如简单网络管理协议(SNMP),来测试硬盘容量。
这里提供了不同的方法,但这并不使开始使用 Nagios 变得更容易。因此,本章提供了常见方法的概述,并试图理解涉及的基本概念。随后章节将提供详细的配置示例。

图 5-1. Nagios 允许不同的测试方法。
图 5-1 展示了 Nagios 支持的多种测试方法的概述。带有灰色背景的上方框标记了所有直接在 Nagios 服务器机器上运行的组件:这包括服务器本身,以及插件和其他辅助工具。这个单元与五个客户端接触,以各种方式对这些客户端进行测试。接下来的几节将更详细地介绍个别方法。
为了监控第一个客户端(从左起标记为service)上的网络服务,Nagios 服务器运行其“自己的”插件check_xyz(5.1 Testing Network Services Directly,第 101 页)。对于第二个客户端,它启动“中间插件”check_by_ssh,以便在远程客户端上远程执行它真正想要的插件(5.2 Running Plugins via Secure Shell on the Remote Computer,第 102 页)。
在第三种情况下,插件也直接在客户端机器上执行,但现在 Nagios 使用专门为此目的创建的 NRPE 服务。查询在 Nagios 端通过check_nrpe进行(5.3 The Nagios Remote Plugin Executor,第 102 页)。
第四种方法通过 SNMP 进行查询。为此,客户端必须有一个可用的 SNMP 代理(11.1 Introduction to SNMP,第 228 页)。有各种插件可用于通过 SNMP 查询数据(5.4 Monitoring via SNMP,第 103 页)。
这四种方法代表“主动”检查,因为 Nagios 主动采取行动并触发测试。相比之下,第五种方法是“被动”的。在这种情况下,Nagios 不会主动采取任何行动,而是等待客户端通过程序send_nsca发送给 Nagios 服务器的传入信息。在 Nagios 服务器本身,Nagios 服务检查接受器,NSCA,作为一个守护进程运行,接受传输的结果并将它们转发到外部命令的接口(参见 5.5 The Nagios Service Check Acceptor,第 104 页)。
除了这些方法之外,还有其他执行检查的方式。通常,客户端会安装一个独立的服务,然后 Nagios 服务器通过专门的插件查询该服务。这里的一个典型例子是 NSClient/NC_Net,它可以用来监控 Windows 服务器(20.2.1 NSClient,第 464 页)。
5.1 直接测试网络服务
邮件或 Web 服务器可以通过网络非常简单地测试,因为底层协议 SMTP 和 HTTP 按定义是网络兼容的(图 5-1,第 100 页,客户端 1)。Nagios 可以调用广泛的插件,每个插件都针对特定的服务进行了专门化。
这样的特定程序比通用的程序有优势。通用插件只测试相应的 TCP 或 UDP 端口是否打开,以及服务是否在那里等待,但它并不确定正确的服务是否在端口上,或者它是否处于活动状态。
特定插件采用网络协议,并测试相关端口上的服务是否按预期行为。例如,邮件服务器在建立连接后通常会以所谓的问候进行响应:
220 swobspace.de ESMTP
这里重要的是数字 220。200 系列数字表示正常,220 代表问候。check_smtp 插件评估这个回复。它还可以模拟发送邮件时的初始对话(除了问候之外),如 6.3 监控邮件服务器第 113 页中所示。
它与其他特定插件的行为类似,例如check_http,它不仅能够处理简单的 HTTP 对话,而且在需要时还会操作 HTTP 头,检查 Web 服务器的 SSL 功能和证书,甚至可以使用POST命令向服务器发送数据(更多内容请参阅 6.4 监控 FTP 和 Web 服务器,第 118 页)。
安装 Nagios 插件的软件包是单独安装的(请参阅 1.4 安装和测试插件,第 43 页),它包括最重要的网络服务的特定插件。如果缺少特定服务的插件,值得查看 Nagios 主页^([45])或 Nagios 附加组件交换.^([46])
如果在这些位置找不到合适的插件,可以使用通用插件check_tcp或check_udp,除了执行纯端口测试外,它们还会向目标端口发送数据并评估响应。(在大多数情况下,这只有在涉及基于 ASCII 的协议时才有意义。)更多关于通用插件的内容请参阅 6.7.1 测试 TCP 端口,第 132 页。
^([45]) www.nagios.org/
^([46]) www.nagiosexchange.org/
5.2 在远程计算机上通过安全壳运行插件
要测试本地资源,如硬盘容量、交换区的负载、当前 CPU 负载或特定进程是否正在运行,有各种本地插件可供使用。它们被称为“本地”插件,因为它们必须安装在被检查的计算机上。
Nagios 服务器无法直接通过网络访问此类信息,除非采取进一步措施。然而,它可以通过远程 shell 在远程主机上启动本地插件(图 5-1,第 100 页,客户端 2)。在这里应仅考虑使用安全壳,SSH;远程壳,RSH,存在太多的安全漏洞。
要做到这一点,Nagios 服务器运行程序check_by_ssh,该程序将命令作为参数传递,以在目标主机上运行本地插件。为此,check_by_ssh需要一种无需密码登录目标主机的方法,这可以通过公钥认证来设置。
从 Nagios 服务器的角度来看,check_by_ssh是处理其结果的插件。它不会注意到有关安全壳连接和远程插件启动的任何内容——主要的是回复必须符合 Nagios 标准,并包含状态以及一行供管理员查看的注释文本。(参见第 105 页第六章的介绍。)
关于通过安全壳执行插件远程执行的更多信息,请参阅第 205 页的第九章。
5.3 Nagios 远程插件执行器
通过安全壳运行目标计算机上安装的插件的另一种方法是Nagios 远程插件执行器(NRPE)。图 5-1(第 100 页)以中间客户端为例说明了这一点。
NRPE 安装在目标主机上,并通过 inet 守护进程启动,必须相应地配置。如果 NRPE 通过(可选的)TCP 端口 5666 从 Nagios 服务器接收查询,它将运行相应的查询。与使用安全壳的方法一样,要执行测试的插件必须安装在目标主机上。
因此,所有这些与使用安全壳相比都要做更多的工作,尤其是 SSH 应该安装在几乎每一台 Unix 机器上,并且当它被使用时,可以在 Nagios 服务器上集中配置监控。然而,安全壳方法需要一个具有本地壳的账户,从而允许在目标主机上运行任何命令。^([47]) 相反,远程插件执行器仅限于配置的命令。
如果你不想让用户 nagios 在目标主机上执行任何需要密码的操作,那么坚持使用 NRPE 会更好。该安装配置在第十章")中描述,第 213 页。
^([47]) 安全壳允许在不打开单独的壳的情况下执行单个命令。然而,通常你将想要测试多个资源,因此你需要运行多个命令。
5.4 通过 SNMP 监控
使用 简单网络管理协议,即 SNMP,可以通过网络查询本地资源(参见图 5-1, 第 100 页)中的客户端 4。如果安装了 SNMP 守护进程(广泛使用 NET-SNMPD,并在第 238 页的 11.2.2 NET-SNMP 守护进程中描述),Nagios 可以使用它来查询本地资源,如进程、硬盘和接口负载。
SNMP 的优势在于其广泛的应用。UNIX 和 Windows 系统都有相应的服务,几乎所有现代网络组件,如路由器和交换机,都可以通过 SNMP 进行查询。甚至不间断电源(UPS)和其他设备有时也具有网络连接,可以通过 SNMP 提供当前状态信息。
除了标准的插件 check_snmp,一个通用的 SNMP 插件,还有各种专门的插件,它们专注于特定的 SNMP 查询,但有时使用起来更简单。例如,check_ifstatus 和 check_if-operstatus 专注于网络接口的状态。
如果你第一次处理 SNMP,你很快就会意识到,当定义该协议时,“可读性”似乎并不是优先考虑的事项之一。SNMP 查询针对机器处理进行了优化,例如用于网络监控工具。
如果你使用供应商提供的网络组件工具,SNMP 将基本上对用户隐藏。但为了与 Nagios 一起使用,你必须动手操作,并涉及协议及其底层语法。这需要一些习惯,但事实上并没有看起来那么困难。
SNMP 的使用是第十一章(第 227 页)的主题;在那里你可以学习如何配置和使用 Linux 和其他 UNIX 系统的 SNMP 守护进程。
5.5 Nagios 服务检查接受者
处理服务检查结果的方法之一导致了Nagios 服务检查接受者,NSCA 的使用。它作为 Nagios 服务器上的守护进程运行,等待接收测试结果(参见图 5-1,位于第五章的右侧)。这种方法被称为被动,因为 Nagios 本身并不主动。
NSCA 使用 CGI 脚本使用的外部命令接口,以及其他接口,向 Nagios 发送命令。它由一个命名管道组成,Nagios 从中读取外部命令。使用命令PROCESS_SERVICE_CHECK_RESULT,Nagios 处理在其他地方确定的测试结果。该接口的详细信息在 13.1 外部命令接口的第 292 页有更详细的描述。
NSCA 的主要用途是分布式监控。这意味着有多个不同的 Nagios 安装将它们的结果发送到一个中央 Nagios 服务器。分布式的 Nagios 服务器,可能在公司的不同分支,作为自主和独立的 Nagios 实例运行,除了它们还将结果发送到总部。这并不是积极检查分散的网络,而是以纯粹被动的方式处理来自分支的信息。
NSCA 不仅限于分布式监控。使用程序send_nsca,可以将测试结果发送出去,这些结果并非来自 Nagios 实例,而是来自例如执行所需服务检查的 cron 作业。
在使用 NSCA 之前,你应该考虑安全性方面的问题。因为外部程序可以使用它来向 Nagios 发送信息和命令,所以存在被滥用的风险。这不应该阻止你使用 NSCA,而应该激励你在配置 NSCA 时关注安全性方面。
关于使用 NSCA、分布式监控以及一般安全性的更多信息,请参阅第十四章的第 299 页。
^([48]) 命名管道是一个缓冲区,一个进程向其中写入数据,另一个进程从中读取数据。这个缓冲区在文件系统中被赋予一个名称,以便可以具体地指向它,这就是为什么它被称为命名管道。
第六章:网络服务插件
用于主机和服务检查的每个插件都是一个独立且独立的程序,也可以独立于 Nagios 使用。反过来,就不那么容易了:为了使 Nagios 使用外部程序,它必须遵守某些规则。其中最重要的是程序返回的返回状态。通过使用它,Nagios 可以精确评估状态。表 6-1 显示了可能值。
表 6-1. Nagios 插件的返回值
| 状态 | 名称 | 描述 |
|---|---|---|
| 0 | OK | 一切正常 |
| 1 | WARNING | 警告限制已超过,但尚未达到临界限制 |
| 2 | CRITICAL | 超过临界限制或插件在超时后中断了测试 |
| 3 | UNKNOWN | 插件内部发生错误(例如使用了错误的参数) |
因此,插件不是通过使用“OK—Not OK”的模式来区分的,而是更加细致。为了能够将状态分类为 WARNING,它需要知道某个事件在什么测量值以下被视为 OK,何时被视为 WARNING,以及何时被视为 CRITICAL。
例如,除了响应时间外,ping 还会返回数据包丢失率。对于慢速网络连接(ISDN、DSL),1000 毫秒的响应时间可以被视为警告限制,5000 毫秒为临界,因为这意味着交互式工作将不再可能。如果网络连接负载高,偶尔也会发生数据包丢失,^([49]) 因此可以将 20%的数据包丢失指定为警告限制,60%为临界限制。
在所有情况下,管理员决定哪些值应作为警告信号或被视为临界。由于所有服务都可以单独配置,因此每个主机的值可能不同,即使在同一插件中也是如此。
插件总是有一个 超时时间,通常是十秒。这防止程序无限期地等待,从而阻止大量插件进程在 Nagios 主机上积累。在其他方面,对于许多应用来说,超过 10 秒的响应时间也几乎没有意义,因为这些应用会在一定时间后中断连接尝试,这具有与相应服务完全失败相同的效果。在这种情况下,管理员可以介入并明确指定不同的超时时间。
所有插件的一个进一步特点是文本输出,Nagios 在其概览中显示它。它主要面向管理员,因此需要是“可读的”。Nagios 2.x 只处理第一行,这里的输出可能不超过 300 个字符。自 3.0 版本以来,Nagios 已不再有此限制。输出可以有多个行,长度可达 8KB(参见 8.5.1 多行插件输出)。然而,在 Web 界面中,Nagios 3.0 也只显示第一行。因此,简单插件应将其输出限制为单行,多行输出仅推荐用于特殊应用,例如plugin check_multi (8.5 使用 check_multi 汇总检查)。文本输出的以下形式已经确立:
*TYPE_OF_CHECK STATUS - informational text*
实际的文本输出看起来像这样:
SMTP OK - 0.186 sec. response time
DISK WARNING - free space: /net/eli02/a 3905 MB (7%);
上述示例分别来自check_smtp和check_disk插件。在这两种情况下,检查类型(此处为SMTP或DISK)后面跟着文本形式的状况,然后是实际信息。并非所有插件都遵循此建议进行输出。有时测试类型的细节缺失,有时甚至状况也缺失。
不同的插件也提供性能信息,这些信息可以用外部程序进行评估和图形表示(参见第十九章):
OK - 172.17.129.2: rta 97.751ms, lost 0%| rta=97.751ms;200.000;500.000;0; pl=0%;40;80;;
如此可见,从check_icmp插件的示例中,性能数据遵循文本输出,由管道字符|分隔。这些数据在 Web 界面中不会显示。
check_icmp在这里提供两个值:中等的回复时间,*`r`*****ta (Real Time Answer,实际时间回答),以毫秒为单位,以及数据包丢失率,pl.^([50]) 对于每个变量,插件首先显示测量值(97.751毫秒和0%),然后是警告限制(200 毫秒或 40%)和临界限制(500 毫秒或 80%)。Developer Guidelines 指定了只有*`r`*****ta或pl列表中的第一个值提供单位,因为变量的单位不会改变,所以只需要给出一次。
为了尽可能简化安装过程(1.4 安装和测试插件]) 用于测试网络服务。借助它们,Nagios 服务器查询其他服务器上的服务。描述仅限于对正常操作重要的功能。如果您对所有选项感兴趣,我们建议您参考集成在线帮助。
6.1 标准选项
表 6-2 列出了所有插件共有的选项。粗体字体的选项必须为所有插件所知。非粗体字体的关键词可以被程序省略,但如果它们被支持,则必须按照指定的意义使用。
如果一个选项需要参数,通常在简短形式中通过空格分隔,但在长形式中通过等号分隔。但对于 Perl 或 shell 脚本特别地,并非所有作者都遵循这些规则,因此在这里您没有选择,只能查看相应的描述。
表 6-2. 插件的标准选项
| 简短形式 | 长形式 | 描述 |
|---|---|---|
| ^([a]) | ||
-h |
--help |
输出在线帮助 |
-V |
--version |
输出插件版本 |
-v |
--verbose |
输出额外信息——此选项可以多次给出^([a]) |
-H |
--hostname |
目标的主机名或 IP 地址 |
-t |
--timeout |
超时时间(秒),在此时间后插件将中断操作并返回 CRITICAL 状态 |
-w |
--warning |
指定警告限制值 |
-c |
--critical |
指定临界限制值 |
−4 |
--use-ipv4 |
强制使用 IPv4 |
−6 |
--use-ipv6 |
强制使用 IPv6 |
|
^([a]) 这是否会导致更多信息取决于特定的插件...
|
因此,不允许使用-c,例如,用于指定除临界限制以外的任何内容。另一方面,-c和-w的确切使用方法可能因插件而异,因为有时可能需要一个单独的值,而在其他时候,可能需要多个值(也请参阅下面对插件check_icmp的解释)。
大多数插件也具有−4和−6选项,但在版本 1.4 之前并不一定如此。
^([49]) ICMP 数据包不会被重发;丢失的数据包将保持丢失。
^([50]) 短称数据包丢失。
^([51]) 1.4 版本之前的版本不应再使用。一些参数已更改,并且通常性能数据输出会缺失。此外,插件开发者付出了巨大的努力来清理现有错误并不断改进插件。
6.2 使用 Ping 进行可达性测试
UNIX 系统中的经典可达性测试一直是 ping,它发送 ICMP 回显请求数据包并等待 ICMP 回显响应数据包。Nagios 插件包包括两个执行此 ping 检查的程序:check_icmp和check_ping。尽管check_ping在标准配置中使用,但你应该用更有效的check_icmp来替换它,该功能自插件版本 1.4 以来已包含在内。
而check_ping调用 UNIX 程序/bin/ping,这就是为什么总是与现有的ping版本存在兼容性问题,check_icmp则无需任何外部帮助程序发送 ICMP。check_icmp基本上更有效率,因为它不像ping那样在各个数据包之间等待一秒钟。此外,它还会评估 ICMP 错误消息,如ICMP 主机不可达,而check_ping会丢弃这些消息。check_icmp与check_ping向后兼容;这使得可以完全不用check_ping,并用check_icmp来替换它。
check_icmp测量 ICMP 数据包的回复时间并确定丢失的数据包比例。如果收到的是预期的ICMP 回显应答之外的错误消息,则会立即进行评估。因此,如果收到ICMP 主机不可达消息,Nagios 会中断测试。
check_icmp有以下选项^([52])。
-H *`地址`*
没有要测试的计算机的主机名或 IP 地址,check_icmp无法工作。使用-H,可以使用空格分隔多个*`主机`*条目。
-w *`response_time,packet_loss_percent%`*
此开关设置警告的警告限制。*`响应时间`*代表所需的响应时间(以毫秒为单位),*`丢包百分比`*代表相应的丢包百分比。如果你指定-w 500.0,20%,则插件会在响应时间至少为 500.0 毫秒或 20%或更多 ICMP 数据包丢失时发出警告。
-c *`response_time,packet_loss_percent%`*
此开关以与-w定义警告值相同的方式指定临界限制。临界限制应始终大于警告限制。
-n *`数据包`*
使用*`数据包`*,你可以设置check_icmp在每次测试中应使用的数据包数量。默认为5个数据包。
-i *`数据包间隔`*
此开关设置发送到同一主机的两个单独数据包之间的时间间隔。默认为 80 毫秒。它指定为浮点数(例如,-i 80.000)。
-I *`目标间隔`*
此开关设置向不同主机发送数据包的时间间隔(前提是 -H 包含多个主机)。默认值为 0 毫秒,意味着向多个主机发送数据包是同时进行的。
-m *`number_of_reachable_hosts`*
此开关指定必须可访问的主机数量,插件才能返回 OK。此选项允许简单的集群检查:
nagios@linux:local/libexec$ **./check_icmp -m 2 -H 192.168.1.9**
\
**192.168.1.11 192.168.1.13**
OK - 192.168.1.9: rta 0.098ms, lost 0% :: **192.168.1.11: rta nan, lost 100%** ::
192.168.1.13: rta 0.744ms, lost 0%|192.168.1.9rta=0.09 8ms;200.000;500.000;0;
192.168.1.9pl=0%;40;80;; 192.168.1.11rta=0\. 000ms;200.000;500.000;0;
192.168.1.11pl=100%;40;80;;
192.168.1.13r ta=0.744ms;200.000 ;500.000;0; 192.168.1.13pl=0%;40;80;;
在指定的三个主机中,192.168.1.11(加粗显示)无法访问。-m 2 仅请求两个可访问的主机;因此,结果是 OK。如果没有这个细节,结果将是 CRITICAL,因为有一个主机无法访问。
-l *`ttl`*
大于 0 的值设置 IP 数据包的 TTL(生存时间)。默认值是 0,这意味着插件将 TTL 的选择留给操作系统。
-t *`timeout`*
经过 *`timeout`* 秒后,插件中断测试并返回 CRITICAL 状态。默认值为 10 秒。
与程序 /bin/ping 一样,check_icmp 也必须以 *`r`*****oot 权限运行,这就是为什么设置了 SUID 位:
linux:~ # **chown root.nagios /usr/local/nagios/libexec/check_icmp**
linux:~ # **chmod 4711 /usr/local/nagios/libexec/check_icmp**
linux:~ # **ls -l /usr/local/nagios/libexec/check_icmp**
-rwsr-x--x l root nagios 61326 2005-02-08 19:49 check_icmp
作为测试,您应该在命令行上以用户 nagios 的身份执行插件,因为 Nagios 将后来以这个账户执行它:
nagios@linux:~$ **cd /usr/local/nagios/libexec**
nagios@linux:nagios/libexec$ **./check_icmp -H 192.168.1.13** \ **-w 100.0,20%
-c 200.0,40%**
OK - 192.168.1.13: rta 0.253ms, lost 0%| rta=0.253ms;100.000;200.000;0; pl=0%;20;40;;
check_icmp 然后发送标准数量的五个 ICMP 数据包。如果所有数据包的平均响应时间至少为 100.0 毫秒,或者丢失 20% 或更多——即至少有一个数据包在五个中,它就会立即发出警告。对于 CRITICAL 状态,平均响应时间必须至少为 200.0 毫秒,或者至少有两个数据包(五个中的 40%)未得到响应。
6.2.1 check_icmp 作为服务检查
为了将 check_icmp 用作服务检查,您需要一个合适的命令对象。包含 check_ping 的文件 checkcommands.cfg 已经有一个用于 ping 服务。我们只需将其中的 check_ping 插件替换为 check_icmp:
define command{
**command_name check**_**ping**
command_line $USER1$/**check**_**icmp** -H $HOSTADDRESS$ -w $ARG1$ -c
$ARG2$
}
宏 $HOSTADDRESS$ 提供了主机定义中 address 参数的 IP 地址,以及两个自由定义的宏 $ARG1$ 和 `\(ARG2\),可以从服务定义中获取参数,因此可以使用这些宏设置警告和临界限制。
在 PING 服务的服务定义(此处显示的是其中的一部分)中,除了要执行的命令对象的名称外,现在还需要两个参数,这些参数在命令之后输入,并用感叹号分隔:
define service{
service_description PING
host_name linux01
**check_command check_ping!100.0,20%!500.0,60%**
...
}
从命令对象的定义中,您可以看到第一个参数(100.0,20%)定义了警告限制,第二个参数(500.0,60%)定义了临界值。
6.2.2 check_icmp 作为主机检查
要能够在主机检查中使用名为 check_host 的插件,需要设置一个指向 check_icmp 的相应符号链接:
linux:~ # **cd /usr/local/nagios/libexec**
linux:nagios/libexec # **ln -s check_icmp check**_**host**
如果以新名称 check_host 调用,该插件会稍微修改其行为:在收到第一个 ICMP 回显响应后中断测试,因为单个响应包就足以证明主机“活着”。如果第一个返回的响应是错误消息,例如 ICMP 网络不可达 或 主机不可达,则主机被认为是不可达的。
主机检查的定义与其他检查类似。唯一的区别是,这个测试是在定义主机对象时指定的(而不是服务对象):
define host{
host_name linux01
alias Linux File Server
address 192.168.1.21
**check**_**command check-host-alive**
...
}
这里使用的名称 check-host-alive 可以自由定义,并且可以为每个主机单独指定。命令本身的定义是在 checkcommands.cfg 中进行的:
define command{
**command**_**name check-host-alive**
command_line $USER1$/**check**_**host** -H $HOSTADDRESS$
}
主机检查不总是需要使用 check_icmp 来执行。你也可以测量冰箱温度或使用 TCP 或 UDP 的通用插件(check_tcp 和 check_udp;参见第 132 页的 6.7.1 测试 TCP 端口)来测试特定的端口是否打开。例如,端口扫描器 nmap 使用 TCP 端口 80(HTTP)。
这种方法的缺点在于,除了主机本身之外,还需要运行另一个应用程序——即 Web 服务器。此外,对特定应用程序的测试并不能证明计算机不再可访问。ping 的一大优点是内核会自己回复 ICMP 回显请求消息,因此不需要运行任何应用程序。因此,只有当有充分的理由时,才应该从 ping 转换到其他主机检查方法。一个例子可能是一个防火墙,它会过滤 ICMP 消息,管理员无法对其产生影响,但允许通过 TCP 端口 80 的 HTTP 查询。
^([52]) 在线帮助 check_icmp -h 表示它还知道一些长格式选项,但这些选项至今尚未实现。
^([53]) 与任何其他对象一样,服务定义也可以定义在你选择的文件中,Nagios 会从这个文件中加载对象定义。为了清晰起见,最好为文件选择一个描述性的名称,例如 services.cfg,就像我们在简单结构示例中所做的那样。
6.3 监控邮件服务器
许多插件也可用于监控邮件服务器。邮件服务器本身(邮件传输代理(MTA))由check_smtp监控,而邮件服务器上的邮件队列可以通过check_mailq进行检查。由于后者的测试是在本地进行的,因此该插件将在下一章 7.8 定期检查邮件队列状态(第 180 页)中描述。
要监控邮件用户代理(MUA)协议 POP3 和 IMAP——包括 SSL 变体 POP3S 和 IMAPS——使用插件check_tcp。check_pop等是check_tcp的符号链接,它通过被调用的名称确定应测试哪种协议,并做出相关预设。
6.3.1 使用check_smtp监控 SMTP
SMTP 监控插件check_smtp有以下选项:
-H *`address`* /--host=*****`address`*
详细说明应检查 SMTP 服务的计算机。
-p *`port`* /--port=*****`port`*
*`port`*确定端口,如果邮件服务不在标准端口 25 上监听。例如,可以使用这种方式监控邮件病毒扫描器 Amavis(通常端口 10024)。但通常只能从localhost访问。
-e *`string`* /--expect=*****`string`*
*`string`*定义了邮件服务器必须在第一行回复中提供的文本。*`string`*的默认设置是220,这是正常 SMTP 问候语开始的地方,但可能有服务器有不同的设置。监控服务的错误回复将生成一个警告。
-f *`address`* /--from=*****`address`*
使用*`address`*指定一个邮件地址,check_smtp随后将使用“MAIL FROM:”命令将该地址发送到服务器。此选项是测试 Microsoft Exchange 2000 服务器所必需的。
-C *`"mail command"`* /--command=*****`"mail command"`*
使用-C可以向服务器发送单个邮件命令,以稍微扩展测试(见以下示例)。
-R *`"string"`* /--response= *`"string"`*
如果您使用-C向服务器发送 SMTP 命令,您可以在这里指定预期的回复,而不是*`string`*(例如,250)。一个“错误”的回复将触发一个警告。
-S / --starttls
测试期间建立的连接使用 STARTTLS。
-D *`duration`*/--certificate=*`duration`*
用于 STARTTLS 的证书必须仍然有效的最小持续时间(以天为单位)。
-A / --authtype=*****`autheutication type`*
SMTP-Auth 过程的认证类型。默认是none(无认证)。目前唯一支持的过程是LOGIN,它基于用户密码对。
-U / --authuser=*****`user`*
如果使用 -A LOGIN,则为 SMTP 身份验证的用户名。
-P / --authpass=*****`密码`*
如果指定了 -A LOGIN,则附带密码。
-w *`浮点数秒`* /--warning=*****`浮点数秒`*
如果服务器回答所需时间超过 *`浮点数秒`*,则 check_smtp 会发出警告。
-c *`浮点数秒`* /--critical=*****`浮点数秒`*
与 -w 类似,但 check_smtp 在 *`浮点数秒`* 秒后发出 CRITICAL。
在最简单的情况下,你只需输入邮件服务器的名称或 IP 地址:
nagios@linux:nagios/libexec$ **./check_smtp -H smtp01**
SMTP OK - 0,008 sec. response time|time=0,008157s;;;0,000000
在收到 SMTP 问候后,插件 check_smtp 会发送一个 HELO *`主机名`*,其中应包含回复 250。
在这种情况下,相应的命令对象定义如下:
define command{
command_name **check_smtp**
command_line $USER1$/**check_smtp** -H $HOSTADDRESS$
}
要使用此选项检查主机对象 linux01,需要以下服务定义:
define service{
service_description SMTP
host_name linux01
**check_command check_smtp**
...
}
使用 -C 选项,可以将 SMTP 对话扩展得更远,大致直到 RCPT TO:
nagios@linux:nagios/libexec$ **./check_smtp -H localhost** \
**-C "MAIL FROM: <bla@gna.dot>" -R "250"** \
**-C "RCPT TO: <bla@gna.dot>" -R "554"**
SMTP OK - 0,019 sec. response time|time=0,018553s;;;0,000000
例如,此类测试可以用来检查内置在邮件服务器中的限制配置(无效域名、垃圾邮件防御等)。示例检查邮件服务器是否拒绝接受包含无效域名 gna.dot(即在 RCPT TO 中)的邮件。如果服务器以 554 的状态拒绝邮件,则测试运行成功。在此处,check_smtp 所执行的操作对应于以下由 telnet 复制的邮件对话:
user@linux:~$ **telnet localhost 25**
Trying 127.0.0.1...
Connected to loca1host.
Escape character is '^]'.
220 swobspace.de ESMTP
**helo swobspace**
250 swobspace.de
**MAIL FROM: <bla@gna.dot>**
250 Ok
**RCPT TO: <bla@gna.dot>**
554 <bla@gna.dot>: Recipient address rejected: test not existing top lev
el domain
...
如果邮件服务器没有因为配置错误而拒绝接收者域名,则回复将不再包含 554,插件将发出警告。
通常,在检查限制时,你应该记住,服务器只有在收到 RCPT TO: 后才会拒绝邮件,即使在此之前(一个特定的客户端 IP 地址、HELO 中的服务器名称或 MAIL FROM: 中的发送者地址)已经发生了这种情况。
6.3.2 POP 和 IMAP
有四个伪插件可用于测试 POP 和 IMAP 协议:check_pop、check_spop、check_imap 和 check_simap。它们被称为伪插件,因为它们只是对插件 check_tcp 的符号链接。通过插件调用的名称,这确定了其预期用途,并相应地设置了所需的参数,例如标准端口、是否应向服务器发送某些内容、预期的响应以及如何终止连接。所有插件都使用相同的选项,因此我们将一起介绍它们:
-H *`地址`* /--host=*****`地址`*
这指定了要检查 POP 或 IMAP 的计算机。
-p *`端口`* /--port=*****`端口`*
*`port`*指定一个替代端口,如果插件旨在监视标准端口以外的端口:check_pop为 110,check_spop为 995,check_imap为 143,check_simap为 993(另见/etc/services)。
-w *`floating_point_dec`* /--warning=*****`floating_point_dec`*
占位符*`floating_point_dec`*被替换为响应时间的警告限制,以秒为单位,指定为浮点小数。
-c *`floating_point_dec`* /--critical=*****`floating_point_dec`*
这设置了响应时间的临界限制(秒),(见-w)。
-s *`"string"`* /--send=*****`"string"`*
此字符串要发送到服务器。在默认设置下,四个插件都不使用此选项。
-e *`"string"`* /--expect=*****`"string"`*
*`string`*指定一个文本字符串,该字符串必须包含在服务器的响应中。默认情况下,(S) POP 为+0K,(S)IMAP 为* OK。此选项可以多次给出,以在答案中搜索不同的部分字符串。
-E / --escape
此选项允许在-s和-e的详细信息中使用转义序列\n、\r、\t或简单地使用\。在所有情况下,-E必须放在它要影响的选择-s和-e之前。
-A / --all
如果你指定了多个回复字符串与-e,带有-A的插件只有在找到所有必需的回复字符串时才会返回 OK。没有这个选项,多个搜索字符串中只要有一个找到就足以触发积极的确认。
-M *`return value`* / -mismatch=*****`return value`*
如果返回的字符串与-e中的声明不匹配,插件应该如何反应?默认值为warn,表示有 WARNING。使用crit可以将错误返回值指定为 CRITICAL,使用ok则为 OK。
-q *`"string"`* /--quit=*****`"string"`*
这是请求服务结束连接的字符串。对于(S)POP,这是QUIT\r\n,对于(S)IMAP,al L0G0UT\r\n。
-S / --ssl
测试期间建立的连接使用 SSL/TLS 进行连接。如果你调用插件check_simap和check_spop,此选项会自动设置。为了建立连接,服务器必须在指定的端口上直接支持 SSL/TLS。
仅凭 STARTTLS 本身不支持插件。使用
./check_imap -H *computer* -s "a1 CAPABILITY" -e "STARTTLS"
你至少可以检查服务器是否提供此方法:如果回复字符串包含 STARTTLS,插件返回 OK,如果不包含,则返回 WARNING。但这并不是真正测试 STARTTLS 是否真正正常工作的测试。
-D *`duration`* /--certificate=*****`duration`*
此开关指定用于 STARTTLS 的证书将保持有效的天数。
-r *`return_value`* / -refuse=*****`return_value`*
此开关指定如果服务器拒绝 TCP 连接,插件返回哪个值。默认值为 crit(严重)。如果没有任何 POP 或 IMAP 服务可用,可以设置 ok 值。第三个可能的值,warn,会触发警告。
-m *`bytes`* /--maxbytes=*****`bytes`*
此开关建议插件在接收到指定数据量(以字节为单位)后关闭 TCP 连接。
-d *`seconds`* /--delay=*****`seconds`*
此开关在发送字符串到服务器后等待指定时间,然后搜索使用 -e 指定的字符串。
当然,所有通用插件 check_tcp(在第 132 页的 6.7.1 测试 TCP 端口 中描述)的其他选项都可以与 check_pop、check_spop、check_imap 和 check_simap 一起使用。
在最简单的情况下,您只需提供要测试的计算机名称(此处:mailsrv)或 IP 地址:
nagios@linux:nagios/libexec$ **./check_pop -H mailsrv**
POP OK - 0.064 second response time on port 110 [+OK eli11 Cyrus POP3
v2.1.16 server ready <1481963980.1118597146@eli11>]
|time=0.064228s;0.000000;0.000000;0.000000;10.000000
在每种情况下,插件仅提供一行输出,这里为了布局原因进行了换行。管道字符 | 后面的详细信息涉及 Web 界面未显示的性能数据。性能数据的结构和处理方式在 19.1 使用 Nagios 处理插件性能数据 中有更详细的描述,第 404 页。
作为命令对象实现,上述 check_pop 命令看起来是这样的:
define command{
command_name **check_pop**
command_line $USER1$/**check_pop** -H $HOSTADDRESS$
}
作为对 linuxO1 机器的服务,它被集成如下:
define service{
service_description POP
host_name linux01
**check_command check_pop**
...
}
^([54]) STARTTLS 指的是在建立正常连接之后,服务设置 SSL/TLS 加密连接的能力——例如,对于 POP3,通过 TCP 端口 110。实现 STARTTLS 的每个服务都必须有一个合适的命令来完成此操作。对于 POP3,这被称为 STLS(见 RFC 2595)。STARTTLS 与 SMTP、LDAP、IMAP 和 POP3 等一起使用,但并非所有服务器都自动支持此方法。
6.4 监控 FTP 和 Web 服务器
Nagios 插件包提供了两个插件来监控经典的互联网服务 FTP 和 HTTP(包括 HTTPS):check_ftp 和 check_http。当网络中的许多用户使用 Web 服务时,通常会使用代理。为了监控这一点,您也可以使用 check_http,但与 check_squid.pl 插件相比,Nagios Exchange 有一个更好的工具可用。
6.4.1 FTP 服务
插件 check_ftp 与 POP 和 IMAP 插件一样,是通用插件 check_tcp 的符号链接,因此它也有相同的选项。它们在 132 页的 6.7.1 测试 TCP 端口 中详细描述。
如果使用名称 check_ftp 调用通用插件,则设置以下参数:
--port=21 --expect="220" --quit="QUIT\r\n"
它不会向服务器发送字符串,而是期望包含文本 220 的回复,并且使用 QUIT\r\n 清洁地结束到标准端口 21 的连接。
在命令行中,通常有一行回复(对于打印版本,带有换行符),其中包含在 | 字符后面的性能数据,该数据在 Web 界面中未显示(参见 404 页的 19.1 使用 Nagios 处理插件性能数据 以了解此信息):
nagios@linux:nagios/libexec$ **./check_ftp -H ftp.gwdg.de**
FTP OK - 0,130 second response time on port 21 [220-Gesellschaft fuer wi
ssenschaftliche Datenverarbeitung mbH Goettingen] |time=0,130300s;0,0000
00;0,000000;0,000000;10,000000
作为命令对象,此调用如下所示:
define command{
command_name **check_ftp**
command_line $USER1$/**check_ftp** -H $HOSTADDRESS$
}
相应的服务定义看起来如下:
define service{
service_description FTP
host_name linux01
**check_command check_ftp**
...
}
6.4.2 通过 HTTP 控制 Web 服务器
根据 intended use,HTTP 和 HTTPS 的 check_http 插件包含大量非常有用的选项:
-H *`virtual_host`* /--hostn.ame=*****`virtual_host`*
此开关指定插件在 HTTP 头部的 host: 字段中传输的虚拟主机名:
nagios@linux:nagios/libexec$ **./check_http -H www.swobspace.de**
HTTP OK HTTP/1.1 200 OK - 2553 bytes in 0.154 seconds
如果您不想 check_http 发送此信息,可以使用 -I 代替。
-I *`ip-address`* /--IP-address=*****`ip-address`*
而不是 *`ip`*,给出目标计算机的计算机名或 IP 地址。对于具有多个虚拟环境的系统,您将进入默认环境,对于大多数 Web 托管提供商,您将收到错误消息:
nagios@linux:nagios/libexec$ **./check_http -I www.swobspace.de**
HTTP WARNING: HTTP/1.1 404 Not Found
-u *`url_or_path`* /--url=*****`url_or_path`*
参数是要发送到 Web 服务器的 URL。如果设计文档位于要测试的服务器上,则只需输入从服务器的 文档根 开始的目录路径:
nagios@linux:nagios/libexec$ **./check_http -H linux.swobspace.net \**
**-u /mailinglisten/index.html**
HTTP OK HTTP/1.1 200 OK - 5858 bytes in 3.461 seconds
如果未指定此选项,插件将请求文档根/。
-p *`port`* /--port=*****`port`*
这是 HTTP 的替代端口指定。
-w *`floating_point_dec`* /--warning=*****`floati.ng_point_dec`*
这是 Web 服务器响应时间的警告限制(以秒为单位)。
-c *`floating_point_dec`* /--critical=*****`floating_point_dec`*
这是 Web 服务器响应时间的临界限制(以秒为单位)。
-t *`timeout`* /--timeout=*****`timeout`*
在 *`timeout`* 秒后过期,插件中断测试并返回 CRITICAL 状态。默认值为 10 秒。
-L /--link-url
此选项确保在文本输出中,虚拟主机在 Web 界面中作为链接显示。
nagios@linux:nagios/libexec$ **./check_http -H www.swobspace.de -L**
<A HREF="http://www.swobspace.de:80/" target="_blank"> HTTP OK HTT P/1.1 200 OK
- 2553 bytes in 0.156 seconds</A>
-a *`username : password`* /--authorization=*****`username : password`*
如果 Web 服务器需要身份验证,可以使用此选项指定用户密码对。然而,插件只能处理基本身份验证;摘要身份验证目前尚不可行。
-f *`behavior`* /--onredirect=*****`behavior`*
如果 Web 服务器将重定向作为对请求的 Web 页面的回复发送,*`behavior`*参数会影响插件的行为。允许的值有ok、warning、critical和follow。默认值为ok,因此插件将简单地返回 OK,而不会跟随重定向。可以通过follow使插件跟随重定向。带有重定向的warning和critical返回WARNING或CRITICAL状态。
-e *`"string"`* /--expect=*****`"string"`*
这是服务器响应应在其第一行状态中包含的文本。如果未指定此选项,插件期望HTTP/1作为*`*string`*。
-s *`"string"`* /--string=*****`"string"`*
这是在页面返回的内容中插件搜索的搜索文本,而不是在标题中。
-r *`"regexp"`* /--regex=*****`"regexp"`*
这是插件应在返回的页面中搜索的正则表达式。
-R *`"regexp"`* /--eregi=*****`"regexp"`*
此开关与*`-r`*类似,但插件现在不区分大小写。
--invert-regex
这将*`-r`*或-R的搜索反转。如果匹配,插件现在返回 CRITICAL 而不是 OK。
-l /--linespan
通常,正则表达式的搜索限制在一行内,使用*`-r`*和-R。如果−l在这些选项之前,搜索模式可以引用多行文本。
-P *`string`* /--post=*****`string`*
使用此开关发送您希望通过 POST 命令发送到 Web 服务器的数据。*`*string`*中的字符必须按照 RFC 1738 进行编码:仅允许字母 A 到 Z(大小写)、特殊字符$-_. + !*' ()和数字 0 到 9。
要发送文本Übung für Anfänger(德语中的“Exercise For Beginners”),在发送之前必须对重音符号和空格进行编码:%DCbung%20f%FCr%20Anf%E4nger。
-T *`string`* / -content-type=*****`string`*
这指定了头部的内容类型,如果您正在使用--post向服务器发送某些内容。默认为application/x-www-form-urlencoded。所有内容类型的列表在文件/etc/mime.types中给出,格式描述可以在 RFC2045 中找到.^([57])
-m *`min_bytes:max_bytes`* /--pagesize=*****`min_bytes:max_bytes`*
此参数定义返回的页面必须至少为*`min_bytes`*大小,否则插件将发出警告。您还可以使用一个上限(由冒号分隔)来指定网页的大小。现在check_http如果返回的页面大于*`max_bytes`*,也会发出警告。在以下示例中,如果返回的页面大小至少为 500 字节且最多为 2000 字节,则一切正常:
nagios@linux:nagios/libexec$ **./check_http -H www.swobspace.de** \
**m 500:2000**
HTTP WARNING: page size 2802 too large|size=2802B;500;0;0
-N /--no-body
使用此选项,插件不会等待服务器返回完整的页面内容,而是只读取头部数据。为此,它使用 HTTP 命令GET或POST,而不是HEAD。
-M *`seconds`* /--max-age=*****`seconds`*
如果返回的文档早于头部中指定的日期(HTTP 头部字段Date:),则插件将生成警告。除了秒(不包含其他详细信息)之外,您还可以使用显式单位,例如5m(五分钟)、12h(十二小时)或3d(三天);不允许组合。
-A *`"string"`* /--useragent=*****`"string"`*
此参数明确指定 HTTP 头中的用户代理,例如-A "Lynx/1.12"用于 Lynx 版本 1.12。通常插件不会发送此字段。
-k *`"string"`* /--header=*****`"string"`*
这指定了任何 HTTP 头标签。如果需要指定多个标签,它们必须由分号分隔,如下例所示:
-k "Accept-Charset: iso-8859-1; Accept-Encoding: compress, gzip;"
-S /--ssl
这强制使用 SSL 连接:
nagios@linux:nagios/libexec$ **./check_http --ssl -H \**
**www.verisign.com**
HTTP OK HTTP/1.1 200 OK - 33836 bytes in 1.911 seconds
主机www.verisign.com允许 SSL 连接。如果不是这种情况,服务器将返回错误,插件将返回值 CRITICAL:^([58])
nagios@linux:nagios/libexec$ **./check_http --ssl -H www.swobspace.de**
Connection refused
Unable to open TCP socket
-C *`days`* /--certificate=*****`days`*
测试证书是否至少有效给定天数。否则将发出警告。
−4 /--use-ipv4
测试是在 IPv4 连接上明确进行的。
−6 /--use-ipv6
测试是在 IPv6 连接上明确进行的。
相应命令对象及其作为服务的定义与基于其他插件的不同;6.4.3 监控 Web 代理展示了示例。
6.4.3 监控 Web 代理
使用check_http进行代理测试
类似于 Squid 这样的代理也可以用check_http进行测试,但这假设您对浏览器如何与代理建立联系有一些了解。它是通过以下形式的 HTTP 头部来做的:
GET **http://www.swobspace.de/** HTTP/1.1
Host: **www.swobspace.de**
User-Agent: Mozilla/5.0 (X11; U; Linux i686; de-DE; rv:1.7.5)
Gecko/20041108 Firefox/1.0
Accept: text/xml,application/xml,application/xhtml+xml,...
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Proxy-Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
决定性的条目以粗体形式打印。与正常的 Web 服务器查询相比,浏览器通过 GET 命令从服务器请求文档,而不是指定目录路径,而是使用包括协议类型在内的完整 URL。在Host:字段中,它指定了它实际上想要到达的 Web 服务器的名称。对于直接发送到 Web 服务器(而不是通过代理)的正常 HTTP 查询,Web 服务器的名称将写入那里。此行为可以用check_http来重现:
nagios@linux:nagios/libexec$ **./check_http -H www.swobspace.de** \
**-I 192.168.1.13 -p 3128 -u http://www.swobspace.de**
HTTP OK HTTP/1.0 200 OK - 2553 bytes in 0.002 seconds
为了在头部设置Host:字段,您需要使用-H指定 Web 服务器的名称。非本地 URL 由-u强制,同时指定-I确保代理被寻址,而不是 Web 服务器本身。最后,您需要选择代理端口,然后代理测试就完成了。然后check_http将以下 HTTP 头部发送到代理:
GET **http://www.swobspace.de HTTP/1.0**
User-Agent: check_http/v1861 (nagios-plugins 1.4.11)
Connection: close
Host: **www.swobspace.de**
此测试不使用代理的任何特定实现信息,因此它应该与每个 Web 代理一起工作。
命令对象定义为如下:
define command{
command_name **check_proxy**
command_line $USER1$/**check_http** -H www.googl
e.de -u http://www.google.de -I $HOSTADDRESS$ -p $ARG1$
}
然后使用以下服务测试代理计算机linuxO1:
define service{
service_description Webproxy
host_name linux01
**check_command check_proxy!3128**
...
}
参数3128确保命令对象check_proxy可以从$ARG1$中读取端口。
使用check_squid进行代理测试
在上一节中介绍的check_http代理检查仅在所需 Web 页面可用或已存在于缓存中时才有效。如果这两种情况都不成立,此测试将产生错误,即使代理在原则上正在工作。
插件check_squid.pl使用不同的方法,但它不是标准安装的一部分,可以在检查插件类别下找到,在软件 | HTTP & FTP | Squid 代理下.^([59])
它利用 Squid 代理的缓存管理器,该管理器通过伪协议进行查询。命令以以下形式发送
GET cache_object: //*ip_address/command* HTTP/1.1\n\n
向 Squid 发送并获取所需信息。插件check_squid.pl使用info命令,该命令查询一系列统计使用信息:
user@linux:~$ **echo "GET cache_object://192.168.1.13/info HTTP/1.1\n\n"** \
| **netcat 192.168.1.13 3128**
...
File descriptor usage for squid:
Maximum number of file descriptors: 1024
Largest file desc currently in use: 18
Number of file desc currently in use: 15
Files queued for open: 0
Available number of file descriptors: 1009
Reserved number of file descriptors: 100
Store Disk files open: 0
...
它针对的是仍然空闲的文件描述符数量(从末尾起的第三行);您可以为此值设置警告或临界限制。文件描述符的数量在同时访问 Squid 缓存中的对象时发挥作用。在具有大量并行访问代理的环境下,1024 个文件描述符可能不足。在只有几百个用户的小型网络中,并非所有用户都在同一时间上网,编译的 1024 值将足够。
Squid 配置 通常 Squid 只允许从localhost访问缓存管理器。为了使 Nagios 可以通过网络查询它,代理必须相应地重新配置:
...
acl manager proto cache_object
**acl nagiosserver 192.168.1.9**
**http_access allow manager nagiosserver**
http_access deny manager
**cachemgr_passwd none info menu**
...
配置文件squid.conf中必要的更改以粗体形式打印,其他相关行已包含在默认文件中。要打印的第一行定义了一个通过内部协议cache_object的访问控制列表(访问控制列表,acl)名为manager,因此它指的是使用cache_object协议访问代理的所有内容。接下来是一个基于 Nagios 服务器 IP 地址的访问控制列表,这里为192.168.1.9。列表名称nagiosserver可以在这里自由选择(第一行中的manager也可以自由选择)。通过http_access allow,nagiosserver在行之前获得对缓存管理器(manager)的访问权限。
http_access deny manager
通过cache_object协议禁止所有其他访问。最后,cachemgr_passwd为缓存管理器访问提供密码。如果您省略此选项,则没有密码,则应仅允许执行没有潜在更改事物的选定命令,例如info和menu,后者显示缓存管理器可以执行的所有操作。修改配置文件后,Squid 需要重新读取它:
linux:~ # **/etc/init.d/squid reload**
应用插件 测试插件check_squid.pl本身有以下选项:
-H *`address`* /--hostname=*****`address`*
这是 Squid 要测试的服务器,通过 IP 地址或 FQDN 指定。
-P *`port`* / --port=*****`port`*
这指定了 Squid 监听的端口号。默认值为标准端口 3128。
-p *`password`* / --password=*****`password`*
这是访问缓存管理器的密码。
-w *`free_descriptors`* / --warning=*****`free_descriptors`*
这是插件将发出警告的空闲文件描述符数量。默认值为 200。
-c *`free_descriptors`* / --critical=*****`free_descriptors`*
这是空闲文件描述符的临界限制。如果数量低于此值,check_squid返回 CRITICAL。默认值为 50。
当运行check_squid时,通常非常不起眼:
nagios@linux:nagios/libexec$ **./check_squid.pl -H 192.168.1.13**
Squid cache OK (1009 FreeFileDesc)
相应的命令也没有问题 ...
define command{
command_name **check_squid.pl**
command_line $USER1$/**check_squid.pl** -H $HOSTADDRESS$
}
... 对于服务定义也是如此:
define service{
service_description Squid
host_name linux01
**check_command check_squid.pl**
...
}
^([55]) Posix 正则表达式,请参阅man 7 regex。
^([56]) www.faqs.org/rfcs/rfcl738.html,第 2.2 段
^([57]) tools.ietf.org/html/rfc2045#section-5
^([58]) 这可以在 shell 中通过echo $?进行检查。
^([59]) www.nagiosexchange.org/cgi-bin/pages/Detailed/1764.html
6.5 控制域名服务器
还提供了两个插件用于测试 域名服务 (DNS):check_dns 和 check_dig。虽然 check_dns 通过使用外部 nslookup 程序测试主机名是否可以解析,但 check_dig 允许查询所有记录。这两个插件都是标准分发的一部分。
它们被使用的场景有所重叠。使用 check_dns,你也可以显式查询特定的 DNS 服务器,尽管这个插件实际上是用于检查名称服务是否通常可用。
6.5.1 使用 nslookup 进行 DNS 检查
check_dns 插件检查指定的主机名是否可以解析为 IP 地址。在本地使用时,该插件测试运行它的计算机上的 DNS 配置。对于名称解析,它使用 /etc/resolv.conf 中配置的名称服务器。
可能的选项同样不起眼。
-H *`主机`* / --hostname=*****`主机`*
这是需要解析为 IP 地址的主机名。
-s *`DNS 服务器`* / --server=*****`DNS 服务器`*
此选项明确指定要使用的名称服务器。如果此选项缺失,check_dns 将使用 /etc/resolv.conf 中的名称服务器。
-a *`IP 地址`* / --expected-address=*****`IP 地址`*
*`IP 地址`* 是 *`主机`* 应该有的 IP 地址。如果名称服务返回不同的地址,插件将使用 CRITICAL 状态发出警报。此选项仅在需要名称服务器提供固定 IP 地址时才有意义。没有此选项,插件将接受所有 IP 地址作为回复。
-A / --expect-authority
使用 -s 指定的名称服务器应该能够权威地回答给定的查询,因此相应的域名必须充当主域名服务器或辅助域名服务器。如果不是这种情况,插件将返回 CRITICAL 状态。
-w *`浮点数`* / - 警告=*****`浮点数`*
此选项指定名称服务器响应时间的警告限制(以秒为单位,指定为浮点数)。
-c *`浮点数`* / - 临界=*****`浮点数`*
此选项以秒为单位指定名称服务器的临界响应时间,指定为浮点数。
-t *`超时`* / --timeout=*****`超时`*
在 *`超时`* 秒后,插件中断测试并返回 CRITICAL 状态。默认值为 10 秒。
对于本地 DNS 配置测试(不是名称服务器),你只需要一个不太可能从 DNS 中消失的主机名,例如 www.google.com:
nagios@linux:nagios/libexec$ **/check_dns -H www.google.com**
DNS OK: 0,009 seconds response time www.google.com returns 216.239.59.99
在这种情况下,相应的命令定义如下:
define command{
command_name **check_dns**
command_line $USER1$/**check_dns** -H www.google.de
}
以下服务测试计算机 linux01 的域名服务器配置是否正常工作:
define service{
service_description DNS/nslookup
host_name linux01
**check_command check_dns**
...
}
6.5.2 使用 dig 监控域名服务器
插件 check_dig 为监控域名服务器提供了比 check_dns 更多的选项。正如其名所示,它基于外部实用程序 dig,旨在实现这一目的。
-H *`address`* / --hostname=*****`address`*
*`address`* 是要测试的 DNS 服务器的 IP 地址。也可以指定一个主机名(而不是 IP 地址),但在大多数情况下这几乎没有意义,因为这首先必须解析,然后才能到达域名服务器。
-p *`port`* / --port=*****`port`*
此开关指定要使用的 UDP 端口。默认值为 53。
−1 *`hostname`* / --lookup= *`hostuame`*
*`hostname`* 是要测试的主机名。如果未查找特定计算机,而是仅测试 DNS 服务器的功能,则应在此处指定一个易于从互联网访问的地址,例如 www.google.com。
-T *`record_type`* / --record_type=*****`record_type`*
此开关指定要查询的记录类型。默认为 A(IPv4 地址),但通常也使用 NS(相关域名服务器)、MX(相关 邮件交换)、PTR(指针;反向查找的 IP 地址)或 S0A(授权源,域的管理细节)。
-w *`floating_point_dec`* / --warning=*****`floating_point_dec`*
此开关设置域名服务器响应时间的警告限制(以秒为单位,浮点十进制)。
-c *`floating_point_dec`* / --critical=*****`floating_point_dec`*
此开关设置域名服务器在秒(浮点十进制)内的关键响应时间。
-a *`address`* / --expected_address=*****`address`*
这是 dig 应在 ANSWER SECTION 中返回的地址。与 check_dns, check_dig 不同,只有当 IP 地址不匹配时,check_dig 才会发出警告,但回复本身已在该给定时间限制内到达。
-t *`timeout`* / --timeout=*****`timeout`*
在 *`timeout`* 秒后过期,插件中断测试并返回 CRITICAL 状态。默认值为 10 秒。
以下两个示例检查域名服务器 194.25.2.129,通过请求其计算机 www.swobspace.de 的 IP 地址。第二个示例以警告结束,因为域名服务器对 www.swobspace.de 的回复返回了与 ANSWER SECTION 中的 1.2.3.4 不同的 IP 地址:
nagios@linux:nagios/libexec$ **./check_dig -H 194.25.2.129 -l** \
**www.swobspace.de**
DNS OK - 2,107 Sekunden Antwortzeit (www.swobspace.de. 1800 IN A 21
2.227.119.101)
nagios@linux:nagios/libexec$ **./check_dig -H 194.25.2.129 -l** \
**www.swobspace.de -a 1.2.3.4**
DNS WARNING - 0,094 Sekunden Antwortzeit (Server nicht gefunden in ANSWE
R SECTION)
示例 1 实现为一个命令对象,如下所示:
define command{
command_name **check_dig**
command_line $USER1$/**check_dig** -H $HOSTADDRESS$ −1 $ARG1$
}
为了测试特定的名称服务器 linux0l,您寻找 Nagios 应该始终能够解析的地址,例如 www.google.com
define service{
service_description DNS/dig
host_name linux01
**check_command check_dig!www.google.com**
...
}
6.6 查询 Secure Shell 服务器
无论 Secure Shell 服务器使用的是协议版本 1 还是 2,对 Secure Shell 服务器的监控都由插件 check_ssh(包含在标准发行版中)负责。它相当简单,只是评估 SSH 握手。测试不需要用户名和密码。
不要与 check_sshis 混淆的插件 check_by_ssh(见第九章通过 SSH 执行插件),该插件在另一台计算机上远程启动插件。
-H *`address`* / --hostname=*****`address`*
插件应建立 SSH 连接的计算机的主机名或 IP 地址。
-p *`port`* / --port=*****`port`*
这指定了一个备用端口。默认为 22。
-r *`version`* / --remote-version=*****`version`*
测试的 Secure Shell 的版本详细信息必须与指定的文本匹配,而不是 *`version`*,否则将发送警告(见下例)。如果版本详细信息包含空格,则字符串必须用双引号括起来。
-t *`timeout`* / --timeout=*****`timeout`*
在 *`timeout`*(默认为 10)秒后,插件中断测试并返回 CRITICAL 状态。
以下示例依次测试本地计算机和 wobgate 上的 Secure Shell 守护程序,以查看是否正在使用 Debian Etch 的当前 SSH 版本:
nagios@linux:nagios/libexec$ **./check_ssh -H localhost** \
**-r 'OpenSSH_4.3p2 Debian-9'**
SSH OK - OpenSSH_4.3p2 Debian-9 (protocol 2.0)
nagios@linux:nagios/libexec$ **./check_ssh -H wobgate -r** \
**'OpenSSH_4.3p2 Debian-9'**
SSH WARNING - OpenSSH_3.8.1p1 Debian-8.sarge.6 (protocol 2.0) version mi
smatch, expected 'OpenSSH_4.3p2 Debian-9'
在 wobgate 上未使用 SSH 的最新版本。
在具有各种 Linux 发行版的异构环境中,您通常只需“手动”进行插件调用时才使用版本检查,并且很少将它们集成到 Nagios 配置中。相反,通常使用以下简单模式使用命令和服务定义就足够了:
define command{
command_name **check_ssh**
command_line $USER1$/**check_ssh** -H $HOSTADDRESS$
}
define service{
service_description SSH
host_name linux01
**check_command check_ssh**
...
}
否则,您将面临在每次安全更新后都必须调整命令对象中版本号的风险。
6.7 通用网络插件
有时找不到与要监控的服务完全匹配的插件。对于此类情况,有两个通用插件可用:check_tcp 和 check_udp。它们都测试目标端口上是否针对相关协议有活动服务。尽管这还不能保证在端口上运行的服务确实是所需的服务,但在一个管理员负责和配置的环境中,可以通过其他方式充分保证这一点。
这两个插件都会向服务器发送一个字符串并评估回复。对于基于文本的协议,如 POP 或 IMAP,这最为简单:这两个“特定”插件,专为这两种邮件服务量身定制(参见第 115 页的 6.3.2 POP 和 IMAP),除了到check_tcp的符号链接外,没有使用任何其他东西,而check_tcp已经完成了相应的问答游戏,并设置了相关默认设置。
如果您知道要测试的协议,并配置了一个适合此协议的“测验”(对于二进制协议来说这不是一件容易的事),那么检查就不仅仅是端口扫描了。这样,通用插件也可以替代缺失的特定插件。
6.7.1 测试 TCP 端口
check_tcp专注于基于 TCP 的服务。与其通用性质一致,它有许多选项:
-H *`address`* / --hostname=*****`address`*
这是应测试端口的计算机的 IP 地址或主机名。
-p *`port`* / --port=*****`port`*
这指定了目标端口。与作为check_tcp符号链接的插件不同,此详细信息始终是必需的。
-w *`floating_point_dec`* / --warning=*****`floating_point_dec`*
这将设置响应时间的警告限制(以秒为单位)。
-c *`floating_point_dec`* / --critical=*****`floating_point_dec`*
这设置了一个类似于-w的时间限制,但指定了临界限制值。
-s *`"string"`* / --send=*****`"string"`*
这是插件应发送到服务器的字符串。
-e *`"string"`*/ --expect=*`"string"`*
这是服务器回复中应包含的字符串。插件不会将其搜索限制在第一行。
-E / --escape
这允许使用转义序列\n、\r、\t或简单地\来表示-s和-e。在所有情况下,-E必须放在影响-s和-e选项之前。
-A / --all
如果您指定了多个回复字符串-e,则带有-A的插件只有在所有必需的回复字符串都被找到时才会返回 OK。如果没有此选项,只要找到几个字符串中的任何一个就足够了。
-M *`return_value`* / --mismatch=*****`return_value`*
如果返回的字符串与-e指定的内容不匹配,插件应该如何反应?默认值为warn,这意味着会发出警告。使用crit,错误的返回值可能被分类为 CRITICAL,而使用ok,则被视为 OK。
-q *`"string"`* / --quit=*****`"string"`*
这是请求服务结束连接的字符串。
-m *`bytes`* / --maxbytes=*****`bytes`*
插件在接收到超过*`bytes`*后关闭连接。
-d *`floating_point_decimal`* / --delay=*****`floating_point_decimal`*
这是发送字符串和检查响应之间的秒数间隔。
-t *`timeout`* / --timeout=*****`timeout`*
在*`timeout`*(默认为10)秒后,插件停止测试并返回 CRITICAL 状态。
-j / --jail
设置此选项将显示 TCP 输出。对于基于文本的协议,如 POP 或 IMAP,这通常是“可读的”,但对于二进制协议,你通常无法解析输出,因此-j是合适的。
-r *`return_value`* / --refuse=*****`return_value`*
此选项指定插件在服务器拒绝 TCP 连接时返回的值。默认为crit(CRITICAL)。如果*`return_value`*为ok,则可以测试是否有一个不应从外部访问的服务可用。第三种可能的值,warn,确保给出 WARNING。
-D *`days`* / --certificate=*****`days`*
这是服务器证书至少需要有效的天数范围,以便测试成功运行。这仅适用于 SSL 连接。请注意,存在混淆的危险:在check_http插件中,此相同选项是-C(见 6.4.2 通过 HTTP 控制 Web 服务器)。如果时间范围低于为服务器证书指定的时间段,插件将返回 WARNING。
-S / --ssl
应使用 SSL/TLS 进行连接。插件无法处理 STARTTLS^([60])。
以下示例检查命令行是否在目标主机192.168.1.89的 5631 端口上激活了服务,这是 Windows 远程控制软件 PCAnywhere 的 TCP 端口:
nagios@linux:nagios/libexec$ **./check_tcp -H 192.168.1.89 -p 5631**
TCP OK - 0,061 second response time on port 5631 | time=0,060744s;0,
000000;0,000000;0,000000;10,000000
对于所有计算机名和端口细节足以作为测试参数的服务,命令对象如下:
define command{
command_name **check_tcp**
command_line $USER1$/**check_tcp** -H $HOSTADDRESS$ -p $ARG1$
}
要监控机器Win0l上的 PCAnywhere,将使用以下服务定义:
define service{
service_description pcAnywhere
host_name Win01
**check_command check_tcp!5631**
...
}
^([60]) 见 6.3.2 POP 和 IMAP 中的脚注。
6.7.2 监控 UDP 端口
监控 UDP 端口并不简单,因为没有标准连接设置,例如 TCP 的 三次握手,在这个过程中连接被打开,但数据尚未传输。对于无状态协议如 UDP,没有发送和接收数据包的规范序列。服务器可以用 UDP 数据包回复客户端发送的 UDP 数据包,但它没有义务这样做。
如果你找到一个未使用的端口,请求的主机通常会发送一个 ICMP 端口不可达消息,这会评估插件。如果没有回复,有两种可能性:要么目标端口上的服务没有对请求做出反应,要么防火墙正在过滤网络流量(无论是 UDP 流量本身还是 ICMP 消息)。这就是为什么你永远不能确定特定端口背后的服务器是否真的提供了服务。
为了在可能的情况下强制得到积极的响应,你通常必须向服务器发送包含某种有意义消息的数据,使用-s选项。大多数服务不会对空或无意义的包做出响应。这就是为什么你不能避免了解相应的协议,因为否则你将无法向服务器发送有意义的数据,从而促使它给出回复。
自从 Nagios 插件版本 1.4.4 以来,check_udp一直是check_tcp的符号链接,因此check_udp具有与check_tcp相同的选项(参见 6.6 查询安全外壳服务器)。-p *`port`*、-s *`string`*和-e *`string`*是必填项,尽管集成在线帮助声明这些是可选的。
以下示例测试目标主机192.168.1.13上的服务是否在时间服务器(NTP)端口 123 上活跃。NTP 守护进程只对包含有意义请求的包做出响应(例如,内容以w开头的包):
nagios@linux:nagios/libexec$ **./check_udp -H 192.168.1.13 -p 123 -s "w"** \
**-e""**
UDP OK - 0.001 second response time on port 123 []|time=0.000586s;;;0.00
0000;10.000000
回复保持为空,因此回复字符串被指定为-e ""。NTP 服务器不会对非协议形式的包做出响应。通常,NTP 期望一个相对复杂的包^([61)),其中包含各种信息。这里使用的w是通过试错法找到的:它不包含真正有意义的资料,但它确实能促使服务器做出响应。
上面的命令行命令被实现为一个命令对象:
define command{
command_name **check_udp**
command_line $USER1$/**check_udp** -H $HOSTADDRESS$ -p $ARG1$ -s $ARG2$
}
在这里,我们将端口作为第一个参数传递;所有其他插件的选项都通过$ARG2$访问。
然后以下服务定义接管了检查 NTP 时间服务器:
define service{
service_description
host_name timesrv
**check_command check_tcp!123!-s "w" -e ""**
...
}
如命令行示例所示,Nagios 将字符串w发送到服务以引发一个积极的响应。
^([61]) NTPv3 协议版本在 RFC 1305 中描述:rfc.sunsite.dk/rfc/rfcl305.html。
6.8 监控数据库
Nagios 提供了三个用于监控数据库的插件:check_pgsql用于 PostgreSQL,check_mysql用于 MySQL,以及check_oracle用于 Oracle。最后一项在本书中不会涉及^([62])。它们共同的特点是它们既可以在本地使用,也可以通过网络使用。后者的优点是相关的插件不需要安装到数据库服务器上。缺点是您必须更深入地了解认证主题,因为配置数据库的安全本地访问要简单一些。
对于不太关键的系统,插件的网络访问可以不使用密码进行。为此,用户nagios在要测试的数据库管理系统(DBMS)中设置了自己的数据库,其中不包含任何(重要)数据。通过此用户访问的区域可以通过数据库自身的权限系统与其他数据隔离,存储在 DBMS 中。
当然,您可以为用户nagios设置密码。但如果您无法使用 SSL 加密连接,大多数数据库连接将以明文形式传输。此外,它还在 Nagios 配置文件中未加密存储。在这方面,密码确实提供了一些保护,但并不真正安全。
作为一项额外措施,您当然应该限制用户nagios可以从 Nagios 服务器访问数据库的 IP 地址。
这里介绍的插件对数据库只有读取访问权限。check_mysql插件还允许进行纯连接检查,而不需要读取访问。在提到的任何插件中,数据库的写入访问均不可用。对于 Oracle,Nagios Exchange^([63])上有一个名为check_oracle_writeaccess.sh的插件,它也测试数据库的可写性。
6.8.1 PostgreSQL
使用check_pgsql插件,您可以建立到数据库的本地和网络连接。本地连接由 PostgreSQL 通过 Unix 套接字处理,这是一个纯粹的本地区域机制。如果显式传递目标主机给check_pgsql,则会通过它建立 IP 连接。插件对测试数据库执行纯连接测试,但不从中读取任何数据。
为了使 PostgreSQL 可以通过网络访问,您必须启动postmaster程序,使用-i选项,或者在配置文件postgresql.conf中将参数tcpip_socket设置为true。
配置便于监控的 DBMS
为了更清晰地分离用户nagios(执行插件)可以看到的数据与其他数据,您首先设置一个具有相同名称的数据库用户,并授予此用户访问权限的数据库:
postgres@linux:~$ **createuser --no-adduser --no-createdb nagios**
postgres@linux:~$ **createdb --owner nagios nagdb**
在使用命令 createuser 创建数据库用户时,--no-adduser 选项尤为重要。对于 PostgreSQL 来说,允许自动创建用户的能力意味着你是超级用户,可以轻松绕过各种权限设置.^([64]) 但在任何情况下都不应授予 nagios 超级用户权限。
createdb 最终创建了一个名为 nagdb 的新空数据库,属于 nagios。
数据库访问可以通过文件 pg_hba.conf 进行限制。根据发行版的不同,它可能位于 /etc/postgresql 或数据库本身的子目录 ./data 中(例如,对于 SUSE,为 /var/lib/pgsql/data)。以下摘录限制了数据库用户 nagios 对特定数据库和 Nagios 服务器 IP 地址的访问(而不是由 *`ip-nagios`* 完成的 IP 地址):
#type db user ip-address ip-mask method options
local nagdb nagios ident sameuser
host nagdb nagios *ip-nagios* 255.255.255.255 ident sameuser
第一行是注释,描述了列的功能。第二行允许数据库用户 nagios 通过本地连接访问数据库 nagdb。尽管这里的身份验证方法被称为 ident,但你不需要为 Linux 和 BSD 变体(NetBSD、FreeBSD 等)安装本地身份验证守护进程。
最后一行描述了相同的限制,但这次是针对与 Nagios 服务器建立的 TCP/IP 连接。但现在 PostgreSQL 会询问 Nagios 服务器上的身份验证守护进程,哪个用户触发了连接请求。这意味着必须在 *`ip-nagios`* 上安装一个身份验证守护进程。这样,数据库管理系统就会检查从 Nagios 服务器发起连接的用户是否真的叫做 nagios。它不会允许其他用户(或来自不同主机的连接)。
通常,身份验证协议只部分适用于用户身份验证。但在 Nagios 服务器的情况下,你可以假设涉及的主机是在管理员控制之下,管理员可以确保身份验证守护进程确实运行在端口 113 上。
存在着大量不同的身份验证守护进程。pidentd^([65]) 被广泛使用,并且包含在大多数 Linux 发行版中。通常它已经预先配置好,只需启动即可。但是启动方式取决于发行版;通常由 inetd 或 xinetd 承担这项任务。浏览文档(应该)能让你直接找到答案。
修改 pg_hba.conf 中的配置后,必须停止数据库管理系统,以便它可以重新加载配置文件。这最好通过以下命令完成:
linux:~ # **/etc/init.d/postgresql reload**
(不需要重启)。如果修改了 inetd/xinetd 的配置,此守护进程将以相同的方式重新初始化。
测试插件 check_pgsql
check_pgsql 有以下选项:
-H *`address`* / --hostname=*****`address`*
如果提供了此选项,插件将建立 TCP/IP 连接,而不是通过 Unix 套接字与本地 DBMS 建立联系。
-P *`port`* / --port=*****`port`*
与之前讨论的插件不同,check_pgsql 使用大写 P 来指定 PostgreSQL 运行的端口。默认情况下,它连接到端口 5432。此选项仅在 PostgreSQL 允许 TCP/IP 连接时有用。
-d *`database`* / --database=*****`database`*
指定插件应连接到的数据库名称。如果缺少此详细信息,它将使用标准数据库 template1。
-w *`floating_point_dec`* / --warning=*****`floating_point_dec`*
这是测试性能时间的警告时间(以秒为单位)。
-c *`floating_point_dec`* / --critical=*****`floating_point_dec`*
这是测试性能时间的临界限制(以秒为单位)。
−1 *`user`* / --logname=*****`user`*
这是应该与数据库建立联系的用户名称。
-p *`passwd`* / --password=*****`passwd`*
此开关设置数据库访问密码。由于必须在服务定义中以纯文本形式存储,因此可能存在潜在的安全问题。最好在 PostgreSQL 的用户 nagios 配置中显式定义一个受限的、无密码的数据库访问。
-t *`timeout`* / --timeout=*****`timeout`*
10 秒后过期,插件停止测试并返回 CRITICAL 状态。此选项允许更改默认值。
要测试专门为此目的设置的数据库 nagdb 在网络上的可达性,此参数与目标主机(此处:linux01)一起传递:
nagios@linux:nagios/libexec$ **./check_pgsql -H linux01 -d nagdb**
CRITICAL - no connection to 'nagdb' (FATAL: IDENT authentication failed
for user "nagios")
检查在示例中出错明显是由于 ident 认证。例如,如果你忘记在修改配置后重新加载 ident 守护进程,就会发生这种情况。一旦错误得到纠正,插件——希望——将工作得更好:
nagios@linux:nagios/libexec$ **./check_pgsql -H linux01 -d nagdb**
OK - database nagdb (0 sec.)|time=0,000000s;2,000000;8,000000;0,000000
如果省略数据库参数,check_pgsql 将连接到数据库 template1:
nagios@linux:nagios/libexec$ **./check_pgsql -H linux01**
CRITICAL - no connection to 'template1' (FATAL: no pg_hba.conf entry fo
r host "172.17.129.2", user "nagios", database "template1", SSL off)
如果使用正确的数据库但错误的用户运行测试,也会得到类似的结果:
wob@linux:nagios/libexec$ **./check_pgsql -H linux01 -d nagdb**
CRITICAL - no connection to 'nagdb' (FATAL: no pg_hba.conf entry for ho
st "172.17.129.2", user "wob", database "nagdb", SSL off)
你当然应该运行最后两个测试,只是为了检查 PostgreSQL 数据库是否真的拒绝相应的请求。否则,你将有一个安全漏洞,我们建议你删除配置中过于宽泛的设置。
如果你为检查创建了单独的数据库,就没有理由不在命令定义中明确写出,而不是使用参数,使用 $ARG1$:
define command{
command_name **check_pgsql**
command_line $USER1$/**check_pgsql** -H $HOSTADDRESS$ -d nagdb
}
然后,linux01 的服务定义就像这样简单:
define service{
service_description PostgreSQL
host_name linux01
**check_command check_pgsql**
...
}
6.8.2 MySQL
使用 check_mysql 插件,MySQL 数据库可以在本地和网络上进行测试。对于本地连接,它通过 Unix 套接字进行联系,而不是通过真正的网络连接。
MySQL 配置
为了使数据库可以通过网络访问,必须在配置文件 my.cnf 中取消注释 skip-networking 选项。然后数据库应在 TCP 端口 3306 上运行,可以使用 netstat -ant 等命令进行测试:
user@linux:~$ **netstat -ant | grep 3306**
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN
为了相对安全地设置无密码访问数据库,这里创建了一个单独的 nagdb 数据库,其中不包含任何关键数据,并且用户 nagios 从 Nagios 服务器获得了受限访问。为此,您作为数据库用户 root 连接到数据库 mysql,然后在其中创建数据库 nagdb:
user@linux:~$ **mysql --user=root mysql**
mysql> **CREATE DATABASE nagdb;**
如果命令 mysql --user=root mysql 无需输入 root 密码即可执行,那么您面临一个严重的安全问题。在这种情况下,任何人——至少是从数据库服务器开始——都可以获得对数据库的完全访问权限。如果出现这种情况,您必须阅读 MySQL 文档中的安全注意事项。^([66)]
重新创建用户和访问限制可以一步完成:
mysql> **GRANT select ON nagdb.* TO nagios@ ip-nagios;**
命令设置用户 nagios,如果不存在。它可能只接受来自 IP 地址 *`ip-nagios`* 的 Nagios 服务器的连接,并能够访问数据库 nagdb 中的所有表,但只能执行 SELECT 命令(不允许 INSERT、UPDATE 或 DELETE);也就是说,用户 nagios 只具有读取权限。
测试插件 check_mysql
check_mysql 的选项比其 PostgreSQL 等效选项少——除了 -H 之外,它不实现任何标准标志,并且没有警告或临界性能时间限制。对于特定数据库的选项,它使用与 check_pgsql 相同的语法,除了用户输入:
-H *`address`* / --hostname=*****`address`*
这设置了数据库服务器的计算机名或 IP 地址。如果省略了选项 -H,或者它与参数 localhost 一起使用,check_mysql 不会建立网络连接,而是使用 Unix 套接字。如果您想建立到 localhost 的 IP 连接,您必须明确指定 IP 地址 127.0.0.1。
-P *`port`* / --port=*****`port`*
这是 MySQL 安装的 TCP 端口。默认情况下,使用端口号 3306。
-d *`database`* / --database=*****`database`*
这是插件应建立连接的数据库的名称。如果省略此选项,它仅连接到数据库进程,而不指定特定的数据库。
-u *`user`* / --username=*****`user`*
这是插件应以其名义登录到 DBMS 的用户。
-p *`passwd`* / --password=*****`passwd`*
此开关用于提供登录数据库的密码。
要设置与数据库 nagdb 的连接,以用户 nagios 身份,这两个参数都传递给插件:
nagios@linux:nagios/libexec$ **./check_mysql -H dbhost -u nagios -d nagdb**
Uptime: 19031 Threads: 2 Questions: 80 Slow queries: 0 Opens: 12
Flush tables: 1 Open tables: 6 Queries per second avg: 0.004
与 PostgreSQL 相比,使用 MySQL,您也可以在不连接到特定数据库的情况下建立联系:
nagios@linux:nagios/libexec$ **./check_mysql -H dbhost**
Uptime: 19271 Threads: 1 Questions: 84 Slow queries: 0 Opens: 12
Flush tables: 1 Open tables: 6 Queries per second avg: 0.004
使用 mysql 手动连接到数据库后,您可以使用 MySQL 命令 use 切换到所需的数据库:
user@linux:~$ **mysql -u nagios**
mysql> **use nagdb**;
Database changed
mysql>
使用此插件,后续无法更改数据库。在这里,您必须从一开始就决定您是想联系数据库还是只想建立与 MySQL 数据库系统的连接。
要测试为该目的明确设置的 nagdb 数据库,在创建相应的命令对象时可以不使用参数,并明确指定用户和数据库:
define command{
command_name **check_mysql**
command_line $USER1$/**check_mysql** -H $HOSTADDRESS$ -u nagios -d nagdb
}
这简化了服务定义:
define service{
service_description MySQL
host_name linux01
**check_command check_mysql**
...
}
^([62]) 插件 check_oracle 假设 Nagios 服务器上安装了 Oracle 完整客户端;它与 Instant Client 不兼容,并期望其用户对 Oracle 有广泛的知识。在这里解释所有这些内容远远超出了本书的范围。
^([63]) www.nagiosexchange.org/153;3
^([64]) PostgreSQL 中的权限由数据库命令 GRANT 提供。
^([65]) www.lysator.liu.se/~pen/pidentd/.
^([66]) 可在 dev.mysql.com/doc/mysql/de/Security.html 找到。
6.9 监控 LDAP 目录服务
对于监控 LDAP 目录服务,有 check_ldap 插件可用。它运行一个可以指定为匿名或带认证的搜索查询。为此,它有以下参数:
-H *`address`* / --hostname=*****`address`*
这是 LDAP 服务器的主机名或 IP 地址。
-b *`base_dn`* / --base=*****`base_dn`*
这是 LDAP 目录的顶级元素 (基础域名),例如由域名组件组成:dc=swobspace,dc=de。
-p *`port`* / --port=*****`port`*
这是 LDAP 服务器运行的服务器端口。默认端口是标准端口 389。
-a *`"ldap-attribute"`* / --attr=*****`"ldap-attribute"`*
此开关启用根据特定属性进行搜索。因此 -a "(objectclass=inetOrgPerson)" 搜索目录树中包含对象类 inetOrgPerson 的所有节点(通常用于电话和电子邮件目录,例如)。
在检查中指定属性不如表面上看起来那么有用。如果您在 LDAP 目录中搜索不存在的属性,您通常会收到一个包含零结果但无错误的答案。
-D *`ldap_bind_dn`* / --bin.d=*****`ldap_bind_dn`*
这指定了一个用于认证连接的 bind DN^([67]),例如:
uid=wob,dc=swobspace,dc=de
如果没有此条目,插件将建立匿名连接。
-P *`ldap_passwd`* / --pass=*****`ldap_passwd`*
这是认证连接的密码。它仅在 -D 选项结合使用时才有意义。
-t *`timeout`* / --timeout=*****`timeout`*
在 *`timeout`* 秒(如果没有给出此选项,则为 10 秒)后过期后,插件停止测试并返回 CRITICAL 状态。
−2 / --ver2
使用 LDAP 版本 v2(默认)。如果服务器不支持此协议版本,连接将失败。从 OpenLDAP 2.1 版本开始,默认使用 v3;要激活协议版本 v2,请在配置文件 slapd.conf 中输入以下行:
allow bind_v2
许多客户端,如 Mozilla 和 Thunderbird 地址簿,仍在使用 LDAP 版本 v2。
−3 / --ver3
使用 LDAP 版本 v3。对于许多现代 LDAP 服务器,如 Open-LDAP,这现在是标准,但它们通常也支持旧版本 v2 的并行支持,因为各种客户端还不能实现 v3。
-w *`floating_point_dec`* / --warning=*****`floating_point_dec`*
如果插件的执行时间超过 *`floating_point_dec`* 秒,它将发出警告。
-c *`floating_point_dec`* / --critical=*****`floating_point_dec`*
如果插件的执行时间超过 *`floating_point_dec`* 秒,它将返回 CRITICAL。
-T / --starttls
使用 LDAPv3 中预期的 STARTTLS。^([68])
-S / --ssl
使用 SSL 加密的 LDAP(LDAPS)从 LDAPv2 开始,同时设置用于此的端口,端口 636。在可能的情况下,您应选择 STARTTLS。使用 STARTTLS 的 LDAP 使用与未使用 SSL 加密的 LDAP 相同的端口;在许多情况下,这允许将未加密的 LDAP 访问配置为 STARTTLS 的后备。由于端口不同,这种后备对于 LDAPS 是不可能的。
在最简单的情况下,只需查询 LDAP 服务器是否真的拥有用 -b 指定的基准 DN 即可:
nagios@linux:nagios/libexec$ **./check_ldap -H ldap.swobspace.de** \
**-b "dc=swobspace,c=de"**
LDAP OK - 0,002 seconds response time|time=0,002186s;;;0,000000
此查询对应以下命令对象:
define command{
command_name **check_ldap**
command_line $USER1$/**check_ldap** -H $HOSTADDRESS$ -b $ARG1$
}
由于 LDAP 服务器可以处理具有不同基准 DNs 的多个 LDAP 目录,建议您使用以下参数进行配置:
define service{
service_description LDAP
host_name linux01
**check_command check_ldap!dc=swobspace,dc=de**
...
}
如果涉及身份验证,事情会稍微复杂一些。一方面,插件被赋予nagios用户的绑定 DN,使用-D。另一方面,以下示例通过将此密码存储为文件resource.cfg中的宏$USER3$**来保护必要的密码,该文件可能只有用户**nagios`可以读取(参见 2.14 资源文件 resource.cfg,第 79 页)。
define command{
command_name **check_ldap_auth**
command_line $USER1$/**check_ldap** -H $HOSTADDRESS$ -b $ARG1$ -D $ARG2$
-P $USER3$
}
因此,匹配的服务定义包含基础 DN 和绑定 DN 作为参数,但不包含密码:
define service{
service_description LDAP
host_name linux01
**check_command check_ldap_auth!dc=swobspace,dc=de!uid=nagios,**\
**dc=swobspace,dc=de**
...
}
^([67]) 绑定 DN 用于识别用户,并指向目录树中用户的节点,指定所有上层节点。LDAP 中的绑定 DN 在功能上与在 Unix 下登录时的用户名相对应。
^([68]) 请参阅 6.3.2 POP 和 IMAP 脚注。
6.10 检查 DHCP 服务器
要监控 DHCP 服务,可用的插件是check_dhcp。它通过 UDP 广播发送DHCPDISCOVER到目标端口 67,并等待 DHCP 服务器以DHCPOFFER的形式提供 IP 地址和进一步配置信息。
因为check_dhcp在此之后不会发送DHCPREQUEST,所以服务器不需要保留源并使用DHCPACK确认此保留,也不需要使用DHCPNACK拒绝请求。
授予插件root权限
授予插件root权限
对check_dhcp有进一步的限制:它需要完全访问网络接口,因此必须以root权限运行。
为了让用户nagios能够以root权限运行插件,插件必须属于用户root,并且必须设置 SUID 位。如果您从当前的 tarball 安装插件,权限将被正确设置。一些发行版禁用了 SUID 位,因为它代表潜在的危险——可能通过不干净编程代码中的缓冲区溢出而使一般root权限泄露。在此,程序所有者必须手动更改为用户root,以便可以使用chmod设置 SUID 位。完成此操作后,只有组nagios(除了root之外)被允许运行插件:
linux:nagios/libexec # **chown root.nagios check_dhcp**
linux:nagios/libexec # **chmod 4750 check_dhcp**
linux:nagios/libexec # **ls -l check_dhcp**
-rwsr-x--- 1 root nagios 115095 Jan 8 12:15 check_dhcp
chown命令将插件分配给用户root和组nagios,除了用户nagios本身之外,不应属于其他任何人。(运行 Web 服务器的用户应该是不同组的成员,例如nagcmd,如第一章第 37 页所述。)
此外,chmod确保除了root之外没有人可以读取插件文件,更不用说编辑它。
应用插件
check_dhcp 仅以下选项:
-s *`server_ip`* / --serverip=*****`server_ip`*
这是插件应明确查询的 DHCP 服务器的 IP 地址。如果没有此条目,只要网络中有一个功能正常的 DHCP 服务器,就可以通过测试。因此,您必须决定您是想测试 DHCP 服务的总体可用性还是特定 DHCP 服务器的功能。
-r *`requested_ip`* / --requestedip=*****`requested_ip`*
使用此选项,插件尝试从服务器获取 *`请求的 IP 地址`*。如果由于它已被保留或位于配置区域之外而无法成功,check_dhcp 将以警告响应。
-i *`interface`* / --interface=*****`interface`*
这选择了一个特定的网络接口,通过该接口应通过 DHCP 请求。如果没有此参数,插件始终使用配置的第一个网络卡(在 Linux 中通常是 ethO)。
-m *`mac_address`* / -mac=*****`mac_address`* (从版本 1.4.10 开始)
使用指定的 MAC 地址进行 DHCP 查询,而不是 Nagios 服务器的 MAC 地址。如果 DHCP 服务器只将 IP 地址分配给特定的 MAC 地址,而 Nagios 服务器的 MAC 地址不在此列表中,则需要此明确细节。
-u / --unicast (从版本 1.4.10 开始)
发送单播消息而不是广播.^([69]) DHCP 请求地址的 IP 地址由 -s *`server_ip`* 指定。
-t *`timeout`* / --timeout=*****`timeout`*
经过 10 秒后(默认值),否则 *`超时`* 秒,插件停止测试并返回 CRITICAL 状态。
如果性能时间有一个可配置的警告或临界限制,则插件没有用。在这种情况下,您必须根据需要显式设置超时,这将导致发出 CRITICAL 返回值。
下一个示例显示网络中的 DHCP 服务正在运行:
nagios@linux:nagios/libexec$ **./check_dhcp -i eth0**
DHCP ok: Received 1 DHCPOFFER(s), max lease time = 600 sec.
插件仅包含额外的 *`租期`* 信息,即客户端将被分配 IP 地址的时间。如果您想查看 DHCPOFFER 中包含的所有信息,应使用选项 -v ("详细")。
在下一个示例中,插件明确请求一个特定的 IP 地址(192.168.1.40),但这个地址不可用:
nagios@linux:nagios/libexec$ **./check_dhcp -i ethO -r 192.168.1.40**
DHCP problem: Received 1 DHCPOFFER(s), requested address (192.168.1.40)
was not offered, max lease time = 600 sec.
nagios@linux:nagios/libexec$ **echO $?**
1
结果是一个警告,如状态输出所示,带有 $?。
如果您想测试 DHCP 服务的总体可用性和相关服务器,则需要两个不同的命令:
define command{
command_name **check_dhcp_service**
command_line $USER1$/**check_dhcp** -i etho
}
check_dhcp_service 通过发送任何 DHCP 服务器都可能响应的广播来整体审查 DHCP 服务。
define command{
command_name **check_dhcp_server**
command_line $USER1$/**check_dhcp** -i etho -s $HOSTADDRESS$
}
另一方面,check_dhcp_server 明确测试特定服务器上的 DHCP 服务。
为了匹配这些,你可以定义一个监控整个 DHCP 的服务,以及另一个测试特定主机的 DHCP 的服务。即使第一种变化在原则上不是针对特定主机的,它仍然需要明确分配给一台计算机,以便在 Nagios 中运行:
define service{
service_description DHCP Services
host_name linux01
**check_command check_dhcp_service**
...
}
define service{
service_description DHCP Server
host_name linux01
**check_command check_dhcp_server**
...
}
^([69]) 单播消息针对的是确切的 IP 地址,而广播消息是针对本地网络中所有站点的。
6.11 使用网络不间断电源工具监控 UPS
监控不间断电源(UPS)有两种可能性:网络不间断电源工具 支持几乎所有标准设备。专门针对 APC 公司不间断电源的 apcupsd 守护进程,在 7.10 使用 apcupsd 监控 UPS 一节中描述,见第 182 页。Nagios 中包含的插件 check_ups 只支持第一种实现。
以下规则通常适用:没有插件直接访问 UPS 接口。相反,它们依赖于相应的守护进程,该守护进程监控 UPS 并提供状态信息。此守护进程的主要目的是在电力故障发生时及时关闭连接的服务器。但它也始终提供状态信息,插件可以查询这些信息,并且 Nagios 可以处理这些信息。
网络不间断电源工具包的解决方案和 apcupsd 的解决方案在本质上都是网络兼容的,也就是说,守护进程总是通过 TCP/IP(通过专有协议,或者通过 SNMP)进行查询。但你应该意识到,电力故障可能会影响传输路径,因此相应的信息可能甚至无法到达 Nagios。因此,只有当整个网络路径得到适当的电力故障保护时,通过网络进行监控才有意义。在理想场景中,UPS 直接连接到 Nagios 服务器。在这种情况下调用 check_ups 插件与网络配置没有区别,因为即使对于本地使用,它也是通过 TCP/IP 进行通信的——但在这个情况下,使用主机 localhost。
网络不间断电源工具
网络不间断电源工具
网络不间断电源工具包是一个制造商独立的软件包,包含用于监控不间断电源的工具。不同的特定驱动程序负责硬件访问,因此可以轻松支持新的电源供应,前提是它们的协议是已知的。
剩余的功能也分布在各种程序中:而守护进程 upsd 提供信息,程序 upsmon 以受控方式关闭由不间断电源(UPS)供电的计算机。它既负责通过串行接口连接到 UPS 的机器,也在客户端/服务器模式下负责通过网络供电的计算机。
www.networkupstools.org/列出了目前支持的型号,并提供了有关 UPS 主题的更多信息。标准发行版已经包含了软件,但并不总是包含非常明显的包名:在 SuSE 和 Debian 中,它们以nut命名。
要查询由守护进程upsd提供的信息,有来自 Nagios 插件包的check_ups插件。它通过网络 UPS 工具自己的网络协议查询 UPS 的状态。一个子项目还允许它通过 SNMP 查询电源供应。然而,目前没有对其进行进一步开发。
仅通过 Nagios 进行纯粹监控(不根据测试结果自动关闭计算机),在通过串行线连接 UPS 的主机上配置并启动upsd就足够了。目录/etc/nut中的相关配置文件名为ups.conf。如果您通过网络进行查询,通常需要在(基于 IP 的)访问权限中添加 Nagios 服务器的条目。详细信息可以直接在文件本身或包含的文档中找到,在 Debian 中位于目录/usr/share/doc/nut,在 SuSE 中位于/usr/share/doc/packages/nut。
假设网络 UPS 工具包括用于不间断电源的合适驱动程序,驱动程序和通信接口将输入到ups.conf文件中:
# -- /etc/nut/ups.conf
[upsfw]
driver = apcsmart
port = /dev/ttySO
desc = "Firewalling/DMZ"
在示例中,使用了公司 APC 的 UPS。通信通过串行接口/dev/ttySO进行。在方括号中给出了 UPS 的名称,稍后通过该名称进行寻址:desc可以用来更详细地描述 UPS 的预期用途,但 Nagios 会忽略这一点。
接下来,您必须确保运行网络 UPS 工具的用户(例如来自nut组的用户nut)具有对接口/dev/ttySO的完全访问权限:
user@linux:~$ **chown nut:nut /dev/ttyS0**
user@linux:~$ **chmod 660 /dev/ttyS0**
为了让 Nagios 通过upsd守护进程访问 UPS 的信息,需要在upsd配置文件upsd.conf中输入相应的数据:
# -- /etc/nut/upsd.conf
# ACL *aclname ipblock*
ACL all 0.0.0.0/0
ACL localhost 127.0.0.1/32
ACL nagios 172.17.129.2/32
ACCEPT localhost nagios
REJECT all
使用关键字ACL,您首先定义主机和网络范围及其 IP 地址。您必须始终在此指定一个网络块:/32表示网络掩码的所有 32 位都设置为 1(这对应于 255.255.255.255),因此是一个单独的主机地址。仅指定 IP 地址是不够的。
ACCEPT条目允许在 ACL *`acl-name`*中指定的计算机访问。ACCEPT规则可以多次使用。最后的REJECT条目拒绝所有其他主机的访问。
要完成配置,你应该确保 UPS 守护进程在每次系统启动时启动。在 SuSE 中,这是通过 YaST2 完成的;在 Debian 中,这是在安装过程中处理的。
这是检查 UPS 插件。
监控插件本身有以下选项:
-H *`address`* / --host=*****`address`*
这是安装upsd的计算机。
-u *`identifier`* / --ups=*****`identifier`*
这是ups.conf中 UPS 的名称,用方括号指定。
-p *`port`* / --port=*****`port`*
这是upsd运行的端口号。默认是 TCP 端口 3493。
-w *`whole_number`* / --warning=*****`whole_number`*
此开关定义一个警告极限为整数。如果没有给出变量(参见-v),*`whole_number`*表示秒数响应时间;否则,变量的值范围(例如,80表示BATTPCT中的 80%)。目前无法指定多个警告极限:插件将仅使用最后一个变量和最后一个警告极限。
-c *`whole_number`* / --critical=*****`whole_number`*
此选项指定与变量相关的临界极限(参见-v)。
-v *`variable`* / --variable=*****`variable`*
使用此选项,可以查询 UPS 的特定值。然后引用此参数的极限值。check_ups当前仅支持以下变量:
LINE:
UPS 的输入电压。
TEMP:
USV 的温度。
BATTPCT:
剩余电池容量百分比。
LOADPCT:
UPS 上的负载百分比。
如果缺少此选项,插件将只检查 UPS 的状态(在线或离线)。
由于-v具有另一个值,check_ups不知道强制选项--verbose(参见第 108 页的表 6-2),即使在其长形式中也是如此。
-T /--temperature
此命令以摄氏度而不是华氏度发布温度值。
-t *`timeout`* / --timeout=*****`timeout`*
经过*`timeout`*秒后,插件停止测试并返回 CRITICAL 状态。默认是10秒。
以下示例测试了上面定义的名为upsfw的本地不间断电源(UPS)。-T开关确保温度输出以摄氏度为单位:
user@linux:nagios/libexec$ **./check_ups -H localhost -u upsfw -T**
UPS OK - Status=Online Utility=227.5V Batt=100.0% Load=27.0% Temp=30.6C|
voltage=227500mV;;;0 battery=100%;;;0;100 load=27%;;;0;100 temp=30degF;;
;0
如果一个变量未被使用,当 UPS 关闭(状态=关闭)或已达到低电池容量(状态=0n 电池,低电池)时,插件返回 CRITICAL。check_ups如果至少有一个三个状态电池供电、低电池或更换电池适用,则发出警告,但这不足以达到 CRITICAL 状态(例如,因为相应设置的变量)。在电池供电状态下,电源由电池提供,在低电池状态下,UPS 在线但电池电量低,在更换电池状态下,必须更换电池。
如果这些点都不适用,插件将为以下状态发出 OK:
-
在正常的
在线状态下 -
如果 UPS 正在校准(
校准) -
如果它目前正在旁路,并且电源直接从电源电网提供(
旁路) -
如果 UPS 过载(
过载) -
如果电网电压过高,UPS 将电压限制在正常值(
调整) -
如果电网电压过低,并由 UPS 补充(
提升) -
如果 UPS 目前正在充电(
充电) -
如果不间断电源(UPS)目前正在放电(例如,在计划中的维护程序期间)(
放电)
将上述测试转换为命令对象,对于任何主机看起来是这样的:
define command{
command_name **check_ups**
command_line $USER1$/**check_ups** -H $HOSTADDRESS$ -u $ARG1$ -T
}
对于连接到计算机linux01(UPS 连接的计算机)和上述定义的 UPSupsfw的相应服务定义将如下所示:
define service{
service_description UPS
host_name linux01
**check_command check_ups!upsfw**
...
}
如果check_ups要通过当前负载确定 UPS 状态,则相关信息从变量LOADPCT中获取:
user@linux:nagios/libexec$ **./check_ups -H linux01 -u upsfw -T -v** \
**LOADPCT -W 60 -c 80**
UPS WARNING - Status=Online Utility=227.5V Batt=100.0% Load=61.9%
Temp=30.6C|voltage=227500mV;;;0 battery=100%;;;0;100 load=61%;60000;
80000;0;100 temp=30degC;;;0
UPS 的负载比限制值-w指定的负载重 61%,但尚未达到 80%以上的临界区域,因此只是警告。如果出现两个错误标准,例如查询变量的警告限制被超过和同时处于临界状态,因为 UPS 正在失去电力(电池供电和低电池同时),则最关键的返回值状态具有优先级,因此在这里,check_ups将返回 CRITICAL,而不是由LOADPCT查询产生的 WARNING。
^([70]) eul.networkupstools.org/server-projects/
6.12 使用check_ntp_peer检查 NTP 服务器健康
从插件版本 1.4.11 开始包含的插件check_ntp_peer测试 NTP 服务器的质量。如果您想检查本地服务器与 NTP 服务器的时间偏差,您需要使用在 7.7.1 通过 NTP 检查系统时间页面 177 中描述的插件check_ntp_time。
几个参数表征了质量:偏移描述了与其他 NTP 服务器(参考服务器)的时间差。抖动是测量到远程参考服务器的数据包延迟波动的度量,而分层指定了到下一个原子钟的拓扑距离。分层 0 是原子钟本身,分层 1 指的是直接连接到原子钟的 NTP 服务器。分层 2 是从分层 1 的 NTP 服务器获取时间的 NTP 服务器。NTP 服务器离原子钟越远,分层值就越高。服务器的精度越高,这个值也越高。
这些参数也可以通过程序 ntpq 进行查询,通过提供 NTP 服务器的 IP 地址。选项 -p 显示了查询的 NTP 服务器获取时间详情的参考服务器。选项 -n 防止在参考服务器上进行名称解析,从而加速 ntpq 的执行:
nagios@linux:nagios/libexec$ **ntpq -np 192.168.1.13**
remote refid st t when poll reach delay offset jitter
127.127.1.1 .LOCL. 10 1 26 64 377 0.000 0.000 0.001
*81.169.141.30 81.169.172.219 3 u 1 128 377 27.515 −4.411 1.219
+217.160.215.119 212.82.32.26 3 u 125 128 377 17.834 1.505 1.069
remote 列指定了使用查询的 NTP 服务器的参考服务器。127.127.1.1 是一个特殊情况,代表本地系统时钟。分层值(列 st),10,相对较高,但只有当没有其他 NTP 源可达时,本地系统时钟才起作用。其他两个质量参数,偏移和抖动,位于最后两列。
在最简单的情况下,您可以运行 check_ntp_peer,仅指定要检查的 NTP 服务器(选项 -H):
nagios@linux:nagios/libexec$ **./check_ntp_peer -H 192.168.1.13**
NTP OK: Offset −0.004411 secs|offset=−0.004411s;60.000000;120.000000;
没有进一步详情的情况下,插件会检查与参考服务器的时间偏差,并且不考虑分层和抖动。所有来自 check_ntp_peer 的阈值详情都按照 24.1.5 指定阈值 中描述的格式指定,该格式位于第 557 页。插件有以下选项:
-H *`地址`* / -host=*****`地址`*
这是待检查的 NTP 服务器的名称或 IP 地址。
-p *`端口`* /--端口=*****`端口`*
这是 NTP 服务器监听的 UDP 端口。默认端口是 123。
-q /--静默
如果 NTP 服务器未同步,则返回 UNKNOWN 而不是 WARNING 或 CRITICAL。
-w *`阈值`* / -warning=*****`阈值`*
这是时间偏差的警告阈值。如果 NTP 服务器与至少一个参考服务器的时间偏差大于指定的秒数,则发出警告。默认是 60 秒。
-c *`秒`* / -critical=*****`秒`*
这是时间偏差的临界阈值。如果使用的某个参考服务器的时间与 NTP 服务器的时间偏差超过 *`秒`* 秒(默认为 120),则状态变为 CRITICAL。
-W *`阈值`* / -swarn=*****`阈值`*
这是基于 stratum 值的警告阈值。如果没有可用的参考服务器其 stratum 值与指定的阈值匹配,则发出警告。这意味着-W 1:2如果没有可用的参考服务器具有 stratum 1 或 stratum 2,则引起警告。如果没有此参数的详细信息,则 stratum 值不包括在检查中。
-C *`阈值`* / -scrit=*****`阈值`*
这是基于 stratum 值的临界阈值。见-W。
-j *`阈值`* / -jwarn=*****`阈值`*
这是毫秒级的抖动警告阈值,以阈值格式给出。如果至少有一个参考服务器在指定的范围内显示抖动,则插件返回 OK。如果没有给出此选项,则抖动不包括在评估中;没有默认值。
-k *`阈值`* / -jcrit=*****`阈值`*
这是阈值格式中抖动的临界阈值。
第七章。测试本地资源
本章介绍的插件来自nagios-plugins包,^([71]) 测试没有自己的网络协议的本地资源,因此不能轻易通过网络查询。因此,它们必须安装在被测试的计算机上。Nagios 服务器上的此类插件只能测试服务器本身——命令和服务定义如第六章网络服务插件中所述。
要从中央 Nagios 服务器对远程主机执行此类本地测试,你需要额外的工具:插件通过安全外壳启动,或者你使用Nagios 远程插件执行器(NRPE)。使用安全外壳的描述见第九章通过 SSH 执行插件,以及第十章第十章。Nagios 远程插件执行器(NRPE)(第 213 页)专门介绍了 NRPE。
命令和服务的定义取决于机制的选择。如果你想在安装了check_by_ssh插件的 Nagios 服务器上测试空闲硬盘容量,该插件远程调用目标服务器上的check_disk(见第七章测试本地资源),则需要为此定义一个特殊的命令,这与第六章网络服务插件(第 105 页)中给出的定义有所不同。远程执行本地插件看起来像什么命令和服务定义在前面提到的 NRPE 和 SSH 章节中描述。
对于远程查询某些本地资源,您还可以使用 SNMP(参见第十一章收集与 SNMP 相关的监控信息,从第 227 页开始),但检查将限于使用的 SNMP 守护进程的功能。本地插件通常在这里更灵活,并提供更多查询选项。
7.1 空闲硬盘容量
计算机硬盘可能溢出的时间问题由check_disk插件回答。它有以下选项用于指定阈值:
-w *`limit`* /--warning=*****`limit`*
如果空闲硬盘容量低于此限制,插件将发出警告,该限制可以表示为百分比或整数。如果您指定百分比,则必须包括百分号%;例如12.5%这样的浮点小数是可能的。整数值表示--units开关定义的单位中的绝对空闲空间。默认值为--units=MB,即兆字节。
-c *`limit`* / --critical=*****`limit`*
如果空闲硬盘容量低于此百分比或整数(见-w),check_disk将显示 CRITICAL 状态。临界限制必须小于警告限制。
-W *`limit`* / -iwarning=*****`limit`*
文件系统中空闲 inode 的数量作为百分比;如果此值低于限制,check_disk将发出警告。
-K *`limit`* / -icritical=*****`limit`*
与-W类似,但这是临界阈值。
-u *`unit`* / --units=*****`unit`*
您指定整数限制值时使用什么单位?kB、MB、GB和TB都是可能的。
-k / --kilobytes
使用此开关,-c和-w中给出的整个数字限制值应解释为 KB。这等同于--units=kB。
-m / --megabytes
使用此开关,-c和-w中的整个数字限制值被插件解释为 MB(默认值)。这等同于--units=MB。
在指定以下路径选择器之前,至少必须给出一个阈值(-w、-c、-W或-K)。
-p *`path_or_partition`* / --path=*****`path`*或--partition=*****`partitioin`*
这指定了文件系统的根目录或分区中的物理设备(例如,/dev/sda5)。从版本 1.4 开始,-p可以多次调用。如果没有指定路径,插件将测试所有文件系统(另见-x和-X)。
-E / --exact-match
这要求对于使用-p指定的所有路径或分区,都必须包含文件系统的根目录,否则插件将发出错误:
nagios@linux:nagios/libexec$ **df /usr/local**
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/md2 9843168 7062980 2280172 76% /usr
/usr/local 不是一个文件系统,而是位于分区 /dev/md2 上的 /usr 文件系统中的一个目录。如果您使用 -p /usr/local 和 -E 调用插件,您将收到错误,因为 /usr/local 本身不是所需的文件系统根目录 -E:
nagios@linux:nagios/libexec$ **./check_disk -w 10% -E -p/usr/local**
DISK CRITICAL: /usr/local not found
-x *`path`* / --exclude_device=*****`path`*
此选项排除指定的挂载点 *`path`*,从测试中排除。此选项假定路径使用 -p 指定,并且它们可能在插件调用中多次运行。
-X *`fs_typ`* / --exclude-type=*****`fs_typ`* (从 1.4)
此选项排除特定文件系统类型,其缩写与 mount 命令的 -t 选项中相同。这样,fs_type 可以取 ext3、reiserfs 或 proc 等值(另见 man 8 mount)。此选项可以在插件命令中使用多次。
-R *`regexp`* / --eregi-path=*****`regexp`*,--eregi-partition=*****`regexp`*
从版本 1.4.8 开始:一个正则表达式,用于选择所有与它匹配的路径或分区。这里忽略大小写。以下示例检查所有以 mdO 至 md2 结尾的分区:
nagios@linux:nagios/libexec$ **./check_disk -w 10% -r 'md[0-2]$'**
DISK OK - free space: / 281 MB (31% inode=80%); /usr 2226 MB (24% i
node=77%);| /=626MB;861;;0;957 /usr=6897MB;8650;;0;9612
交换分区 /dev/mdl 在这里被忽略。
-r *`regexp`* / --ereg-path=*****`regexp`*, --ereg-partition=*****`regexp`*
从版本 1.4.8 开始:一个正则表达式,用于检查分区和/或路径。类似于 -R,但现在区分大小写。
-A / --all
从版本 1.4.10 开始:检查所有分区和文件系统。相当于 -R '.*'。
-I *`regexp`* / --ignore-eregi-path=*****`regexp`*, --ignore-eregi-partition=*****`regexp`*
从版本 1.4.10 开始:一个正则表达式,用于排除检查中匹配的路径或分区。这里忽略大小写。
-i *`regexp`* / --ignore-ereg-path=*****`regexp`*, --ignore-ereg-partition=*****`regexp`*
从版本 1.4.10 开始:类似于 -I,但现在区分大小写。
此外,插件还具有以下选项:
-e / --errors-only
使用此选项,插件仅显示处于警告或关键状态的文件系统或分区。
-M / --mountpoint
从版本 1.4 开始,默认情况下,check_disk 显示文件系统路径(例如,/usr)。使用 -M,您将被告知涉及的是哪个物理设备(例如,/dev/sda5)。
-C / --clear
从版本 1.4 开始,-p 可以多次使用。如果您想同时测试多个文件系统,但使用不同的限制值,可以使用 -C 删除已设置的旧限制值:
-w 10% -c 5% -p / -p /usr -C -w 500 -c 100 -p /var
这里的顺序很重要:限制值在文件系统详细信息中有效,直到它们被 -C 重置。然后必须使用 -w 和 -c 设置新的限制值。
−1 / --local
仅检查本地文件系统,例如通过 NFS 挂载的其他文件系统被忽略。
-L / --stat-remote-fs (ab 版本 1.4.10)
检查指定阈值的本地文件系统,但仅检查网络文件系统的可用性。使用此开关,您可以测试例如,通过 NFS 连接的路径是否存在过时的文件句柄。^([72])
-g *`group_name`* / --group-type=*****`group_name`*
指的是所有指定分区和路径的总和的限制值。没有此开关,插件将单独将每个路径和每个分区与限制值进行比较。-g 需要给出一个名称,该插件将其作为附加信息包含在输出中:
nagios@linux:nagios/libexec$ **./check_disk -g CLUSTER -w 10%**\
**-r 'md[0-3]'**
DISK OK - free space: CLUSTER 7437 MB (38% inode=86%);| CLUSTER=11
719MB;18163;;0;20182
此选项必须放置在它所引用的路径指定之前。
-t *`timeout`* / --timeout=*****`timeout`*
在 *`timeout`* 秒后,插件停止测试并返回 CRITICAL 状态。默认为 10 秒。
这里是 check_disk 使用的一个稍微更详细的例子:
user@linux:nagios/libexec$ **./check_disk -w 10% -c 5% -p / -p /usr** \
**-p /var -C -w 5% -c 3% -p /net/emil1/a -p /net/emil1/c -e**
DISK WARNING - free space: /net/emil1/c 915 MB (5%);| /=146MB;458;483;0;
509 /usr=1280MB;3633;3835;0;4037 /var=2452MB;3633;3835;0;4037 /net/emil1
/a=1211MB;21593;22048;0;22730 /net/emil1/c=17584MB;17574;17944;0;18499
文件系统 /, /usr, 和 /var 上一切正常,因为它们上的可用空间比 10%的限制值(用于警告)要多——这一点可以从性能数据中看出,当然也比 5%的限制值(用于关键状态)要多。文件系统 /net/emil1/a 和 /net/emil1/c 包含的数据范围显著更大,这就是为什么在删除之前的限制值后,限制值被设置得更低。
-e 确保 Nagios 只显示真正显示错误状态的文件系统。实际上,插件在 | 符号之前的输出,带有 /net/ emil1/c,只显示一个单独的文件系统。管道之后的性能信息只能在命令行上看到——它包含之前测试的所有文件系统。这有点令人困惑,因为 Nagios 插件将其输出限制为单行,这里为了打印版本而进行了换行。
^([71]) 本版基于 1.4.11 版本。
^([72]) 错误消息 NFS stale file handle 指示 NFS 路径不可用。
7.2 交换空间的使用
check_swap 插件测试本地可用的交换空间:
-w *`limit`* / --warning=*****`limit`*
警告限制可以指定为百分比或整数,就像 check_disk 一样,但整数值以字节为单位指定,而不是以千字节为单位!
如果至少应有 10%的空间空闲,指定 -c 10%。整数指定也指剩余的空闲空间。
-c *`limit`* / --critical=*****`limit`*
临界限值,类似于警告限值。
-a / --allswaps
分别测试每个交换分区的阈值值。
以下示例测试至少一半的交换空间是否可用。如果可用交换空间少于 20%,则插件应返回临界状态。在|符号之后,程序再次提供性能数据,这些数据由 Nagios 记录但不显示在 Web 界面的消息中:
user@linux:nagios/libexec$ **./check_swap -w 50% -c 20%**
swap OK: 100% free (3906 MB out of 3906 MB) |swap=3906MB;1953;781;0;3906
7.3 测试系统负载
系统负载可以通过同时运行的进程数量来观察,这是由check_load插件测试的。借助uptime程序,它确定过去一分钟、过去五分钟和过去十五分钟的平均值。uptime在关键字load average之后按此顺序显示这些值:
user@linux:~$ **uptime**
16:33:35 up 7:05, 18 users, load average: 1.87, 1.38, 0.74
check_loadhas只有两个选项(两个限制值),但它们可以用两种不同的方式指定:
-w *`limit`* / --warning=*****`limit`*
此选项指定警告限值,可以是简单的浮点十进制数(5.0)或包含三个浮点十进制数的逗号分隔的三元组(10.0,8.0,5.0)。
在第一种情况下,指定的限制适用于所有三个平均值。如果(至少)其中一个超过,插件会发出警告。在第二种情况下,三元组允许为每个平均值分别指定限制值。同样,check_load在任何一个平均值超过为其定义的限制时就会发出警告。
-c *`limit`* / --critical=*****`limit`*
这以与-w指定警告限值相同的方式指定了临界限值。这些临界限值应高于-w的值。
-r / --percpu(从版本 1.4.9 开始)
将由现有 CPU 核心数确定的系统负载进行分割,以更好地了解每个 CPU 核心的负载。
在以下示例中,如果在过去一分钟内平均有超过 15 个进程活跃,在过去五分钟内平均有超过 10 个进程活跃,或者在过去 15 分钟内平均有 8 个进程活跃,Nagios 会发出警报。对于十个、八个或五个进程的平均值,都有一个警告:
user@linux:local/libexec$ **./check_load -w 10.0,8.0,5.0 -c 15.0,10.0,8.0**
OK - load average: 1.93, 0.95, 0.50| load1=1.930000;10.000000;15.000000;
0.000000 load5=0.950000;8.000000;10.000000;0.000000 load15=0.500000;
5.000000;8.000000;0.000000
7.4 监控进程
check_procs插件根据各种标准监控进程。通常它用于监控单个程序的运行进程。在这里,也可以指定上限和下限。
nmbd,例如,Samba 的名称服务,始终以守护进程的形式运行,有两个进程。进程表中的nmbd条目数量较多始终是问题的明确迹象;这在较老的 Samba 版本中尤为常见。
如 Nagios 本身这样的服务应该只有一个主进程。这可以通过其父进程的进程 ID 1 来看出,这表明它是init进程的子进程。在 Nagios 2.0 的开发阶段,在失败的重新启动或重新加载后,通常会有几个这样的进程并行活动,这导致了不希望出现的副作用。你可以通过以下方式测试是否只有一个 Nagios 主进程活动:
nagios@linux:nagios/libexec$ **./check_procs -c 1:1 -C nagios -p 1**
PROCS OK: 1 process with command name 'nagios', PPID = 1
需要监控的程序称为nagios(选项-C),其父进程的 ID 应为1(选项-p)。必须恰好有一个 Nagios 进程正在运行,不多也不少;否则插件将发出 CRITICAL 状态。这被指定为一个范围:-c 1:1。
另一个例子:OpenLDAP 复制服务slurpd应该有一个到四个同时运行的进程:
nagios@linux:nagios/libexec$ **./check_procs -w 1:4 -c 1:7 -C slurpd**
PROCS OK: 1 process with command name 'slurpd'
如果实际进程数位于1和4之间,插件将返回 OK,正如这里的情况。如果它发现五个到七个进程,则将发出警告。在此范围之外,check_procs将状态分类为 CRITICAL。如果没有任何进程运行,或者运行超过七个,这种情况就适用。
除了相同程序的进程数量之外,你还可以监控由它引起的 CPU 负载、其内存使用,甚至 CPU 运行时间。check_procs有以下选项:
-w *`start: end`* / --warning=*****`start: end`*
如果实际值位于由起始值和结束值指定的范围内,插件将发出警告。在没有进一步细节的情况下,它假定应该计算进程:-w 2:10意味着如果check_ procs发现少于两个或超过十个进程,它将发出警告。
如果你省略了两个限制值中的一个,则零作为下限,或无限作为上限。这意味着范围:10与0:10; 10:相同,描述任何大于或等于 10 的数字。如果你只输入一个单独的整数而不是范围,这表示最大值。因此,条目5代表0:5。
如果你交换最大值和最小值,如果实际值位于该范围内,插件将发出警告,因此对于-w 10:5,这将是在值为 5、6、7、8、9 或 10 时。你可以始终只指定一个区间。
-c *`start : end`* / --critical=*****`start : end`*
这指定了关键范围,与警告限制的方式相同。
-m *`type`* / --metric=*****`type`*
此开关选择以下指标之一用于测试:
PROCS:
进程数量(如果没有指定特定类型,则为默认值)
VSZ:
进程在内存中的虚拟大小(虚拟内存大小),由进程使用的专用主内存空间和使用的共享库组成。这些库即使被多个不同的进程使用,也只占用一次内存空间。指定以字节为单位。
RSS:
进程实际为自己使用的物理内存的比例(以 KB 为单位)(常驻集大小),即VSZ减去共享内存。
CPU:
CPU 使用百分比。此插件检查每个进程的 CPU 使用情况,以确定早晨和关键限制。如果某个进程超过警告限制,Nagios 将发出警告。在文本输出中,插件还会显示超过警告或关键限制的进程数量。
ELAPSED:
自进程启动以来经过的总时间。
-s *`flags`* / --state=*****`flags`*
这将测试限制为具有指定状态标志的进程。^([73]) 下面的示例插件如果存在多于一个的僵尸进程(状态标志:Z),将发出警告:
nagios/libexec@linux: $ **./check_procs -w 1 -c 5 -s Z**
PROCS OK: 0 processes with STATE = Z
如果多于五个僵尸进程“阻塞”进程表,情况将变得关键。可以通过将单个标志相加同时查询多个状态,例如-s DSZ。现在 Nagios 将取消处于至少一个上述状态之一的进程。
-p *`ppid`* / --ppid=*****`ppid`*
此开关将测试限制为父进程具有父进程 ID(*`ppid`*)的进程。从开始就已知且不会改变的唯一 PPID 是 0(由内核启动,通常仅涉及 init 进程)和 1(init 进程本身)。
-P *`pcpu`* / --pcpu=*****`pcpu`*
此选项根据进程使用的 CPU 百分比过滤进程:
nagios/libexec@linux: $ **./check_procs -w 1 -c 5 -P 10**
PROCS OK: 1 process with PCPU >= 10,00
此示例插件仅考虑至少有 10%CPU 使用率的进程。只要有一个这样的进程(-w 1),它就返回 OK。如果有两个到五个这样的进程,返回值是 WARNING。如果有至少六个进程,每个进程的 CPU 使用率至少为 10%,则情况变得关键。
-r *`rss`* / --rss=*****`rss`*
此选项过滤掉至少占用*`rss`*字节主内存的进程。它像-P一样使用。
-z *`vsz`* / --vsz=*****`vsz`*
此选项过滤掉 VSZ(见上文)至少为vsz字节的进程。它像-P一样使用。
-u *`user`* / --user=*****`user`*
此选项过滤掉属于指定用户的进程(见下文示例)。
-a *`"string"`* / --argument-array=*****`"string"`*
过滤掉其参数列表包含*`string`*的命令。例如,-a. tex指的是所有处理*. tex files的进程;-a -v指的是所有带有-v 标志调用的进程。
-C *`command`* / --command=*****`command`*
这会导致进程列表搜索指定的命令名称。命令必须与指定的*`command`*完全匹配,没有路径(见下例)。
-t *`timeout`* / --timeout=*****`timeout`*
在*`timeout`*秒后过期,插件停止测试并返回 CRITICAL 状态。默认值为10秒。
以下示例检查是否恰好有一个名为master的进程在安装了 Cyrus IMAPd 的邮件服务器上运行。没有进程和多个进程一样都是错误:
user@linux : nagios/libexec$ **./check_procs -w 1 : 1 -c 1 : 1 -C master**
CRITICAL - 2 processes running with command name master
第一次尝试返回两个进程,尽管只有一个 Cyrus Master 进程正在运行。如果你运行ps,可以找到原因:
user@linux : ~$ **ps -fC master**
UID PID PPID C STIME TTY TIME CMD
cyrus 431 1 0 2004 ? 00 : 00 : 28 /usr/lib/cyrus/bin/master
root 1042 1 0 2004 ? 00 : 00 : 57 /usr/lib/postfix/master
Postfix 邮件服务也有一个同名进程。为了仅关注 IMAPd 的主进程,搜索还额外限制为以用户cyrus的权限运行的进程:
user@linux : nagios/libexec$ **./check_procs -w 1 : 1 -c 1:1 -C master -u** \
**cyrus**
OK - 1 processes running with command name master, UID = 96 (cyrus)
^([73]) 在 Linux 中可能存在以下状态:D(不可中断等待,通常是磁盘等待),R(运行进程),S(等待状态),T(进程挂起),W(分页,仅限于内核 2.4),X(已结束、被杀死的进程),以及Z(僵尸进程)。更多信息可由man ps提供。
7.5 检查日志文件
监控日志文件并不是 Nagios 概念的一部分。一方面,syslog 守护进程会立即注意到那里的关键事件,从而可以正确确定错误状态。但如果错误状态持续,在大多数情况下无法在日志文件中看到。
相应地,这里描述的插件只能确定是否在错误事件上添加了其他、新的条目。为了通过日志文件将有关持续错误行为的消息传递给 Nagios,被监控的服务必须定期记录错误状态——至少与 Nagios 读取日志文件的间隔相同,并且重复记录。否则,插件将在返回错误状态和 OK 状态之间交替,这取决于(持续)错误是否在此期间出现在日志中。
在任何情况下,Nagios 都不能重复测试。参数max_check_attempts(见 2.3 定义要监控的机器,带有主机的第 309 页中描述。对于以这种方式定义的服务,系统将每个错误状态都视为第一次发生(例如,每次都会发送消息)。
Nagios 定期使用这里介绍的插件执行(主动)检查。如果所寻求的条目没有再次出现,插件返回 OK。这在许多情况下是期望的,管理员不需要担心早期错误事件。但如果所有情况下都需要处理错误事件,简单的 Nagios 检查就不再足够,因为它很容易因为后续检查的 OK 而被忽略。在第二十三章的第 531 页中介绍了一种稍微不同的方法,其中管理员必须明确确认每个错误结果。
7.5.1 标准插件 check.log
使用check_log,Nagios 提供了一个简单的插件来监控日志文件。每次运行时,它都会创建测试日志文件的一个副本。如果自上次调用以来日志文件已更改,check_log将在新添加的数据中搜索简单的文本模式。该插件没有更长的选项,只有 OK 和 CRITICAL 两种状态:
-F *`logfile`*
这是待测试的日志文件的名称和路径。它必须对用户nagios可读。
-O *`oldlog`*
这是日志文件副本的名称和路径。插件在运行时仅检查*`oldlog`*和*`logfile`*之间的差异。之后,它将当前日志文件复制到*`oldlog. oldlog`*。*`oldlog`*必须包含绝对路径,并且用户nagios可读。
-q *`query`*
这是在检查日志文件时搜索的模式。未找到表示正常;匹配则返回 CRITICAL 状态。
建议您通常不要使用恢复通知类型的信息(错误状态后的 OK)。
重复测试中的 OK 仅意味着自上次测试以来事件中没有出现新的错误。因此,在服务定义中的notification_options参数(见 2.3 定义要监控的机器,包括主机 < Jan 1 18 : 47 : 56 swobspace su[22893]: (pam_unix) authentication
failure; logname=wob uid=200 euid=0 tty=pts/8 ruser=wob rhost= user=root
这会产生一个匹配项。插件在文本中不显示其返回值,但可以在 shell 中使用**`echo $?`**显示。在示例中,返回一个**`2`**表示 CRITICAL。
如果你检查多个不同事件的日志文件,你必须为每个日志文件指定一个单独的**``*`oldlog`*``**:
./check_log -F /var/log/messages -O /tmp/check_log.pluto -q "pluto"
./check_log -F /var/log/messages -O /tmp/check_log.ntpd -q "ntpd"
即使你在同一个原始日志文件中进行搜索,也无法避免使用两个不同的**`oldlogs`**:否则**`check_log`**将无法正确工作。
## 7.5.2 现代变体:**`check_logs.pl`**
作为替代方案,Nagios Exchange^([74])提供了一个用于监控日志文件的全新插件。**`check_logs.pi`**是 Perl 插件**`check_log2.pl`**的进一步发展,该插件包含在 Nagios 插件的**`contrib`**目录中,但不是自动安装的。
**`check_logs.pl`**可以同时检查多个日志文件中的事件,这与**`check_log`**和**`check_log2.pl`**不同。为此,它需要一个配置文件。
它确实有一个简单的命令行模式,但只有在同时指定单个日志文件和单个正则表达式时才会工作。但**`check_logs.pl`**真正有趣的功能是你可以一次进行多次检查。这就是为什么我们不会花更多时间描述命令行模式。
初始时,我们创建一个配置文件,大致内容如下,最好放在目录**`/etc/nagios:`**中。
/etc/nagios/check_logs.cfg
\(seek_file_template='/var/nagios/\)log_file.check_log.seek';
@log_files = (
{'file_name' ⇒ '/var/log/messages',
'reg_exp' ⇒ 'ntpd',
},
{'file_name' ⇒ '/var/log/warn',
'reg_exp' ⇒ '(named|dhcpd)',
},
);
1;
Perl 变量**`$seek_file_template`**包含插件保存最后搜索位置的文件的路径。**`check_logs.pl`**在这里记住下次运行时应该在日志文件的哪个位置继续搜索。这意味着插件不需要处理过的日志文件的副本。而不是使用变量**`$log_file`**,它使用要检查的日志文件名,并为每个日志文件创建一个单独的位置文件。
**`check_logs.pl`**具体要做什么由 Perl 数组**`@log_files`**定义。条目**`file_name`**指向要测试的日志文件(带有绝对路径),而**`reg_exp`**包含**`check_logs.pl`**应在日志文件中搜索的正则表达式^([75))。在上面的例子中,这是**`/var/log/messages`**日志文件中的一个简单文本**`ntpd`**,但在**`/var/log/warn`**的情况下有一个替代方案:正则表达式**`(named | dhcpd)`**匹配包含文本**`named`**或文本**`dhcpd`**的行。
当插件运行时,它本身需要的唯一指定是配置文件(选项**`-c`**):
nagios@linux : local/libexec$ *./check_logs.pl -c *
/etc/nagios/check_logs.cfg
messages ⇒ OK; warn ⇒ OK;
nagios@linux : local/libexec$ *./check_logs.pl -c *
/etc/nagios/check_logs.cfg
messages ⇒ OK; warn ⇒ (4): Jul 2 14 : 33 : 25 swobspace dhcpd: Configuration file
errors encountered -- exiting;
第一条命令展示了基本原理:在文本输出中,每个日志文件的插件会分别宣布是否找到了匹配的事件。在上面的例子中,它没有找到任何内容,因此返回 OK。在第二条命令中,插件在**`warn`**日志文件中发现了四个相关条目,但在**`/var/log/messages`**中没有找到。因此,插件返回警告;只有在检查的任何日志文件中都没有找到相关事件时,才会给出 OK。在其输出行中,在**`(4):`**之后,插件会记住找到的四个行中的最后一个。
## 7.5.3 瑞士军刀:**`check_logfiles`**
如果你有很多来自日志文件的要求,而迄今为止介绍的工具不能满足你的需求,那么你真的应该看看 Gerhard Laußer 开发的插件 **`check_logfiles`**。除了复杂的搜索选项外,它还可以处理任何你想要的轮换方法,以确保轮换后不会丢失任何信息。其功能范围可以通过脚本扩展,这些脚本可以用于重启崩溃的应用程序,发送 SNMP 陷阱,或者通过 **`send_nsca`** 将被动检查结果发送到 NSCA 守护进程(14.4 将测试结果发送到服务器,第 305 页)。
对于简单的任务,插件可以通过命令行轻松操作,但若要更高级地使用它,你需要具备一些 Perl 知识:用于利用所有功能的配置文件使用 Perl 语法。
将插件解压到合适的目录中,例如 **`/usr/local/src`**:
linux: local/src # tar xvzf /pfad-zu/check_logfiles-2.3.1.2.tar.gz
...
linux: local/src # cd check_logfiles-2.3.1.2
linux: check_logfiles-2.3.1.2 # .**/configure **
*--with-seekfiles-dir=/var/tmp *
--with-protocols-dir=/var/tmp
...
linux: check_logfiles-2.3.1.2 # make && make install
...
安装通过三个命令 **`configure && make && make install`** 完成。**`--with-seekf iles-dir`** 指定 **`check_logfiles`** 写入状态信息的目录,而 **`--with-protocol-dir`** 指定 **`check_logfiles`** 明确保留找到的匹配项的目录。在执行此操作时,你应该选择一个在每次重启后不会直接删除的目录。根据定义的检查,可以在配置中关闭日志记录。
在命令行上,**`check_logfiles`** 提供以下选项:
**`--tag=`****``*`designator`*``**
指示单个检查,以便更好地区分它们。性能数据中变量的名称也以此标识符开头,以便以后可以将值重新分配给检查。指定 **`--tag`** 是可选的,但插件作者通常推荐使用它。
**`--logfile=`****``*`logfile`*``**
指定要检查的日志文件名称和路径。**`check_logfiles`** 在每次检查时都会注意文件的最后一行,以便在下一次调用时从相同的位置继续。此外,**`check_logfiles`** 还会保存其他信息,如 inode 和时间戳,以便检测日志文件轮换。
**`--rotation=`****``*`rotation method`*``**
指定日志文件的轮换过程:如果你想将 **``*`logfile`*``** 转换为 **``*`logfile.0`*``** 并将其转换为 **``*`Logfile.1.gz.`*``**,则使用 **`loglog0log1gz`**。
**`loglog0gzlog1gz`** 表示首先将 **``*`logfile`*``** 压缩为 **``*`logfile. 0\. gz`*``**,然后将其重命名为 **``*`logfile.1.gz.`*``**
**`loglogdate8gz`** 表示 **``*`logfile`*``** 将被转换为 **``*`logfile. YYYYMMDD.gz.`*``**。
**`loglog01og1`** 描述了将 **``*`logfile`*``** 转换为 **``*`logfile.0`*``** 并在下一个旋转步骤中创建文件 **``*`logfile.1`*``** 的旋转方法。
hpux 则描述了变体“ **``*`logfile`*``** 转换为 **`OLD`****``*`logfile`*``**”。
如果缺少合适的旋转方法,可以指定一个匹配存档文件的正则表达式。对于 Debian,因此指定 **`--rotation='`** **``*`logfile`*\. (0|[0-9]+\.gz)``**。这是以防在文件的初始旋转过程中错过结尾 **`.0`**,并且如果所有较旧的存档文件都以 **``*`.number`*``****`.gz`** 结尾。
**`--criticalpattern=`****``*`regexp`*``**
Perl 语法中的正则表达式,触发 CRITICAL。更详细的信息由 **`man perlre`** 提供。
**`--warningpattern=`****``*`regexp`*``**
与 **`--criticalpattern`** 类似,但这里的正则表达式触发 WARNING。
**`--noprotocol`**
关闭匹配的记录到单独的文件。
**`--syslogserver`**
将对 syslog 服务器日志文件的评估限制在服务器本身输入的行。
**`--syslogclient=`****``*`clientname`*``**
将对 syslog 服务器日志文件的评估限制在来自 syslog 客户端 **``*`clientname`*``** 的行。
**`-f`** **``*`configfile`*``**
指定一个配置文件,它允许比仅通过几个命令行参数允许的更广泛的配置。对于此功能,Perl 知识是必不可少的(参见 7.5.3 瑞士军刀:check_logfiles)。
**`-d`**
开启调试模式。在查找错误时很有用;此选项不应在正常操作期间使用。
**`check_logfiles`** 在首次调用时初始化,以便它可以定位自身。插件仅考虑随后附加到日志文件的日志条目,因此它无法评估已存在的详细信息。
为了演示目的,我们首先使用 **`logger`** 程序在文件 **`/var/log/messages`** 中生成条目:^([77])
user@linux: ~$ logger -p daemon.info hellowob
日志文件现在包含以下条目:
Dec 16 17 : 46 : 06 swobspace wob: hellowob
简单调用 **`check_logfiles`** 返回以下结果:
nagios@linux : nagios/libexec$ ./check_logfiles --tag=hellowob
--logfile=/var/log/messages --criticalpattern='hellowob'
CRITICAL - (1 errors in check_logfiles.protocol-2007-12-16-17-46-08) - D
ec 16 17 : 46 : 06 swobspace wob: hellowob |hellowob_lines=2 hellowob_warni
ngs=0 hellowob_criticals=1 hellowob_unknowns=0
性能数据中的所有变量都附加到 **`hellowob`** 标签,以便在 **`check_logfiles`** 同时搜索多个不同条目时可以再次引用相应的事件。
再次运行 **`check_logfiles`** 返回 OK,因为新增的 32 条条目(**`hellowob_lines=32`**)中没有任何一条包含要搜索的文本:
nagios@linux : nagios/libexec$ ./check_logfiles --tag=hellowob
--logfile=/var/log/messages --criticalpattern='hellowob'
OK - no errors or warnings |hellowob_lines=32 hellowob_warnings=0 hellow
ob_criticals=0 hellowob_unknowns=0
### 配置文件
**`check_logfiles`** 的配置文件基本上包含一个由搜索指令组成的数组,每个指令都编写为一个匿名散列:
@searches = (
{ search_instruction_1 },
{ search_instruction_2 },
...
{ search_instruction_n },
)
该数组被称为**`@searches`**;每个包含在**`{}`**中的指令都是一个搜索指令。**`hellowob`**示例的配置文件可能看起来像这样:
@searches = (
{
tag ⇒ 'hellowob',
logfile ⇒ '/var/log/messages',
criticalpatterns ⇒ 'hellowob',
rotation ⇒ 'debian',
options ⇒ 'noprotocol,nocase',
},
)
指令标记和**`rotation`**对应于同名命令行参数。指令**`criticalpatterns`**和**`warningpatterns`**在此处标记(与等效命令行参数不同)为复数。配置文件还允许指定多个细节:
criticalpatterns ⇒ ['VIRUS found', 'hellowob'],
除了标量之外,还可以在方括号内指定匿名数组。以下是**`@searches`**的一些更多指令:
**`archivedir`**
轮转日志文件的存档目录。默认是日志文件所在的目录。
**`type`**
指定日志文件的类型:如果设置了参数**`rotation`**,则默认接受**`rotation`**。**`simple`**描述没有轮转的日志文件,**`check_logfiles`**不会继续搜索归档文件。**`virtual`**表示应该从开始搜索的文件,例如 Linux 中的**`/proc`**目录中的套接字或文件。对于 AIX,选项**`errpt`**也可用:插件现在搜索**`errpt`**命令的输出,而不是真实文件。
**`criticalpatterns`**
与命令行选项**`--criticalpattern`**类似,但现在可以指定多个表达式作为数组:
criticalpatterns ⇒ ['.hallowob.', '.hellowob. ', '!dontcryforme'],
感叹号确保如果没有找到包含文本**`dontcryforme`**的行,则状态为 CRITICAL。
**`criticalexceptions`**
与**`criticalpatterns`**类似,但作为例外:如果一行匹配**`criticalpatterns`**中的表达式,则会触发 CRITICAL 状态。如果**`criticalexceptions`**中的表达式也匹配此行,则停止临界状态。该指令用于拦截特殊情况。
**`criticalthreshold`**
设置一个阈值。例如,值**`5`**表示只有来自**`criticalpatterns`**的每第五个匹配项才真正被计为 CRITICAL。低于此阈值,结果保持为 OK。
**`warningpatterns`**
与**`criticalpatterns`**类似,但针对警告。
**`warningexceptions`**
与**`criticalexceptions`**类似,但针对警告。
**`warningthreshold`**
与**`criticalthreshold`**类似,但针对警告。
**`okpatterns`**
有时错误可以自行纠正。在这种情况下,管理员不希望被不必要的警报唤醒。
**`okpatterns`**取消所有之前的 WARNINGs 和 CRITICALs。可以指定多个细节(见**`criticalpatterns`**)。
**`script`**
允许在找到匹配项时执行脚本。以下指令补充了这一点:**`scriptparams`**将额外的命令行选项传递给脚本,**`scriptstdin`**允许指定脚本期望的 STDIN 字符串,而**`scriptdelay`**强制**`check_logfiles`**在脚本执行后暂停。
**`options`**
此指令允许进一步设置选项,其含义可以通过在选项前放置前缀**`no`**来否定:
**`script`**
执行指定的脚本。默认是**`noscript`**。
**`smartscript`**
控制脚本的返回值及其输出是否应包含在匹配列表中。默认是**`nosmartscript`**。
**`supersmartscript`**
定义了脚本的返回值和输出是否应该替换之前的匹配(默认是**`nosupersmartscript`**)。例如,脚本的返回值**`0`**(OK)将抑制一个找到的匹配项,通过覆盖通常由**`check_logfiles`**返回的返回值。
**`protocol`**
控制是否将匹配项保留在单独的日志文件中。(默认是**`protocol`**)。
**`count`**
是否应该计数匹配项?**`count`**是默认值。如果使用**`nocount`**关闭此选项,你仍然可以使用**`check_logfiles`**来仅执行脚本。
**`syslogserver`**
对应于**`--syslogserver`**选项(默认是**`nosyslogserver`**)。
**`syslogclient=string`**
与**`--syslogclient`**类似,但可以指定一个额外的过滤器,例如,仅搜索特定客户端的文件(默认是**`nosyslogclient`**)。
**`perfdata`**
是否应该显示性能数据?默认是**`perfdata`**。
**`logfilenocry`**
如果日志文件不存在,**`check_logfiles`**将输出 UNKNOWN,按照默认的**`logfilenocry`**。参数**`nologfilenocry`**告诉插件如果日志文件缺失则省略错误信息。
**`case nocase`**
忽略大小写。默认情况下,带有大小写的情况与这种情况相反。
**`sticky=seconds`**
使用此选项**`check_logfiles`**会注意到指定时间内的错误状态。通常,后续的检查如果没有找到更多匹配项,将返回 OK,这样管理员可能会忽略一个重要的条目。
假设你只有在日志文件中没有更多匹配项两小时后才接受休战。那么使用**`sticky=7200`**的检查将宣布一个错误状态长达两小时。只有在这一时期过后,如果在此期间没有新的条目重新启动两小时的时间限制,**`check_logfiles`**才会返回 OK。
如果搜索模式包含**`okpattern`**,**`check_logfiles`**将在匹配后直接返回 OK,即在指定时间到期之前。
**`savethresholdcount`**
如果事件没有达到**`*threshold`**选项中要求的匹配数量,则不会宣布错误。这里的问题是整体上应该如何处理匹配。**`savethresholdcount`**(默认值)将匹配数量保存到下一次检查,并将这些数量相加,直到达到阈值并触发错误。**`nosavethresholdcount`**参数防止事件计数器在两次检查之间总是重置为零。
本书不涉及所有可能的**`check_logfiles`**应用。因此,我们参考**`check_logfiles`**网站上的文档,该文档有德语和英语版本.^([78])
* * *
^([74]) [`www.nagiosexchange.org/54;279`](http://www.nagiosexchange.org/54;279)
^([75]) 以 Perl 兼容正则表达式(PCRE,见**`man perlre`**)的形式,因为**`check_logs.pi`**是一个 Perl 脚本。
^([76]) [`www.consol.de/opensource/nagios/check-logfiles`](http://www.consol.de/opensource/nagios/check-logfiles)
^([77]) 我们假设**`daemon`**功能以**`info`**优先级记录在**`/var/log/messages`**中。然而,这取决于发行版。在 Debian 中,此类条目位于**`/var/log/daemon.log`**。
^([78]) [`www.consol.com/opensource/nagios/check-logfiles`](http://www.consol.com/opensource/nagios/check-logfiles)
# 7.6 监控登录用户数量
插件**`check_users`**用于监控登录用户数量:
user@linux:nagios/libexec$ ./check_users -w 5 -c 10
USERS CRITICAL - 20 users currently logged in |users=20;5;10;0
它只有两个选项:
**`-w`** **``*`number`*``** **`/ --warning=`****``*`number`*``**
这是登录用户数量的阈值,超过这个阈值后插件应该发出警告。
**`-c`** **``*`number`*``** **`/ --critical=`****``*`number`*``**
这是临界状态的阈值,通过登录用户数量来衡量。
**`|`**后面的性能数据通常仅在命令行中可见;Nagios 不会将其包含在 Web 界面中。
# 7.7 检查系统时间
## 7.7.1 通过 NTP 检查系统时间
两个插件**`check_ntp`**和**`check_ntp_time`**比较本地计算机的时钟时间与网络中可用的 NTP 服务器的时间。如果 Nagios 服务器通过 NTP 准确到足以作为参考,那么它也可以用作网络插件,前提是网络中要检查的主机已安装 NTP 守护进程。
从插件版本 1.4.11 开始,插件 **`check_ntp_time`** 和 **`check_ntp_peer`** (6.12 使用 check_ntp_peer 检查 NTP 服务器健康, 第 154 页)) 替换了 **`check_ntp`**,它包含两个功能:将本地系统时间与这里描述的 NTP 服务器进行比较,以及检查 NTP 服务器本身的健康状态。这里的选项适用于 **`check_ntp`** 和 **`check_ntp_time`**。
在最简单的情况下,**`check_ntp`** 被调用,指定了计算机(此处:**`ntpserver`**),其时间应与本地计算机的时间进行比较:
nagios@linux:nagios/libexec$ ./check_ntp_time -H ntpserver
NTP OK: Offset −0.009505749214 secs|offset=−0.009506s;60.000000;120.0000
00;
这里确定的偏差仅为 9.5 毫秒,这是一个很好的值。可以容忍的偏差大小取决于特定的用途。如果您想比较几个不同计算机的日志文件条目,它们应该进行 NTP 同步。然后您当然可以使用 **`-w 1 -c 2`**,即分配两秒的偏差作为临界值。在使用 Kerberos 进行身份验证的环境中,所有涉及的主机的时间同步也很重要,但并不那么关键:Windows Server 2003 下的 Microsoft Active Directory 可以容忍最大五分钟的偏差,只有在出现更大的偏差时才会真正出现问题。
**`check_ntp_time`** 和 **`check_ntp`** 具有以下选项:
**`-H`** **``*`地址`*``** **`/ --host=`****``*`地址`*``**
这是插件应该与之比较本地系统时间的 NTP 服务器。
**`-p`** **``*`端口`*``** **`/ --port=`****``*`端口`*``**
NTP 服务器运行的 UDP 端口。默认端口为 **`123`**。
**`-w`** **``*`阈值`*``** **`/ --warning=`****``*`阈值`*``**
这是警告限制,按照标准阈值格式指定(24.1.5 指定阈值, 第 557 页)。如果本地系统时间的波动大于指定的阈值,则发出警告。默认值为 60 秒。
**`-c`** **``*`阈值`*``** **`/ --critical=`****``*`阈值`*``**
以秒为单位的临界阈值,按照标准阈值格式指定(24.1.5 指定阈值, 第 557 页)。如果本地系统时间与 NTP 服务器的时间偏差超过给定的秒数(默认设置 120 秒),状态变为 CRITICAL。
**`-q / --quiet`** (仅 **`check_ntp_time`**)
如果 NTP 服务器由于任何原因不提供偏移量,则返回 UNKNOWN 而不是 CRITICAL。
## 7.7.2 使用时间协议检查系统时间
除了*网络时间协议* NTP 之外,还有另一个更老、更简单的协议:RFC 868 中描述的*时间协议*,其中通信通过 TCP 端口 37 进行。在许多 Unix 系统中,相应的服务器集成到 inet 守护进程,因此您不需要启动单独的守护进程。使用**`check_time`**,Nagios 提供了一个适当的测试插件。
**`check_time`**也可以用作网络插件,类似于**`check_ntp`**,但这也假设每个客户端都可用时间服务。因此,在大多数情况下,它将用作本地插件,将其自己的时钟时间与中央时间服务器的时间进行比较(此处:**`timesrv`**):
nagios@linux:nagios/libexec$ ./check_time -H timesrv -w 10 -c 60
TIME CRITICAL - 1160 second time difference| time=0s;;;0 offset=1160s;10 ;60;0
**`|`**符号后面的性能数据,在 Web 界面中未显示,包含以秒为单位的响应时间,**`time`**(此处:零秒);**`offset`**描述时钟时间与时间服务器时间差异的程度(此处:**`1160`**秒)。其他值,每个值由分号分隔,提供警告限制、关键阈值和最小值(另见 19.1 使用 Nagios 处理插件性能数据,第 404 页)。由于我们没有使用**`-W`**或**`-C`**选项设置任何阈值值,因此**`time`**的相应条目为空。
**`check_time`**有以下选项:
**`-H`** **``*`地址`*``** **`/ --主机名=`****``*`地址`*``**
这是时间服务器的计算机名或 IP 地址。
**`-p`** **``*`端口`*``** **`/ --端口=`****``*`端口`*``**
这是 TCP 端口指定,如果与默认的**`37`**不同。
**`-u / --udp`**
通常通过 TCP 查询时间服务器。使用**`-u`**,如果服务器支持,可以使用 UDP。
**`-w`** **``*`整数`*``** **`/ --警告偏差=`****``*`整数`*``**
如果本地时间与时间服务器的时间差异超过**``*`整数`*``**秒,插件返回 WARNING。**``*`整数`*``**始终为正数,这涵盖了运行速度慢和快的时钟。
**`-c`** **``*`整数`*``** **`/ --关键偏差=`****``*`整数`*``**
如果本地时间和时间服务器时间之间的差异超过**``*`整数`*``**秒,该插件的返回值为 CRITICAL。
**`-W`** **``*`整数`*``** **`/ --警告连接=`****``*`整数`*``**
如果时间服务器需要超过**``*`整数`*``**秒的响应时间,则返回 WARNING。
**`-C`** **``*`整数`*``** **`/ --关键连接=`****``*`整数`*``**
如果时间服务器在**``*`整数`*``**秒内没有响应,插件将以 CRITICAL 返回值响应。
# 7.8 定期检查邮件队列状态
**`check_mailq`** 插件可以用来监控邮件服务器的邮件队列,以监控尚未投递的电子邮件。**`check_mailq`** 运行已安装的邮件服务的 **`mailq`** 程序。不幸的是,每个 MTA 对邮件队列的解释都不同,因此插件只能评估程序员考虑到的邮件服务的邮件队列。这些是:**`sendmail`**、**`qmail`**、**`postfix`** 和 **`exim`**。**`check_mailq`** 插件有以下选项:
**`-w`** **``*`number`*``** **`/ --warning=`****``*`number`*``**
如果邮件队列中至少有 **``*`number`*``** 封邮件,插件会发出警告。
**`-c`** **``*`number`*``** **`/ --critical=`****``*`number`*``**
一旦队列中有至少 **``*`number`*``** 封邮件等待投递,则达到临界状态。
**`-W`** **``*`number_of_domains`*``** **`/ --Warning=`****``*`number_of_domains`*``**
这是关于邮件队列中等待消息的接收者域数量的警告限制。因此 **`-W 3`** 如果队列中有任何邮件被发送到三个或更多不同的接收者域,则会发出警告。
**`-C`** **``*`number_of_domains`*``** **`/ --Critical=`****``*`number_of_domains`*``**
这是关于接收者域数量(如 **`-W`**)的临界阈值。
**`-M`** **``*`daemon`*``** **`/ --mailserver=`****``*`daemon`*``**(从版本 1.4 开始)
这指定了使用的邮件服务。**``*`daemon`*``** 的可能值是 **`sendmail`**(默认值)、**`qmail`**、**`postfix`** 和 **`exim`**。
**`-t`** **``*`timeout`*``** **`/ --timeout=`****``*`timeout`*``**
在 **``*`timeout`*``** 秒后,插件停止测试并返回 CRITICAL 状态。这里作为一个例外,默认值是 **`15`** 秒(通常为 10 秒)。
在以下示例中,如果队列中至少有五封邮件,Nagios 应该发出警告;如果数量达到十封,这里使用的 MTAs Postfix 的状态变为 CRITICAL:
user@linux:nagios/libexec$ ./check_mailq -w 5 -c 10 -M postfix
OK: mailq reports queue is empty|unsent=0;5;10;0
由于队列是空的,**`check_mailq`** 在这里返回 OK。
# 7.9 监控文件的修改日期
使用 **`check_file_age`** 插件,您可以监控文件的最后修改日期,也可以监控其大小。在最简单的情况下,它只是运行要监控的文件名和路径:
user@linux:nagios/libexec$ ./check_file_age /var/log/messages
WARNING - /var/log/syslog/messages is 376 seconds old and 7186250 bytes
在这里,由于设置的警告限制是 240 秒,临界限制是 600 秒,插件发出警告。文件的最后修改是在 376 秒前——即在警告范围内。
只有在显式指定文件大小的警告限制(选项 **`-W`**)时,**`check_file_age`** 才会考虑文件大小。然后,如果文件小于给定的限制(以字节为单位),插件可以发出警告。这里的警告和临界限制的默认值都是零字节。
**`check_file_age`** 具有以下选项:
**`-w`** **``*`整数`*``** **`/ --warning-age=`****``*`整数`*``**
如果文件比 **``*`整数`*``**^([79])(默认为 **`240`**)秒旧,插件会发出警告。
**`-c`** **``*`整数`*``** **`/ --critical-age=`****``*`整数`*``**
如果文件比 **``*`整数`*``**(默认:**`600`**)秒旧,则会发生临界状态。
**`-W`** **``*`大小`*``** **`/ --warning-size=`****``*`大小`*``**
如果文件小于 **``*`大小`*``** 字节,插件会发出警告。如果省略了选项,**`0`** 字节是限制。在这种情况下,**`check_file_age`** 不考虑文件大小。
**`-C`** **``*`大小`*``** **`/ --critical-size=`****``*`大小`*``**
如果文件大小小于 **``*`大小`*``** 字节,则会触发临界状态。默认值为 **`0`** 字节,这意味着文件大小被忽略。
**`-f`** **``*`文件`*``** **`/ --file=`****``*`文件`*``**
要测试的文件名。如果像上面的例子一样,您直接提供文件名作为参数,则可以省略此选项。
* * *
^([79]) 因为 **`check_file_age`** 是一个 Perl 脚本,所以在这种情况下指定整数或浮点小数没有关系。在文件系统中,秒的分数不起作用。
# 7.10 使用 apcupsd 监控不间断电源(UPS)
要监控来自 APC 公司的不间断电源(UPS),除了在 6.11 使用网络 UPS 工具监控 UPS 中描述的网络 UPS 工具外,还可以使用专门针对这些 UPS 优化的 **`apcupsd`** 守护进程。软件可以从 [`www.apcupsd.com/`](http://www.apcupsd.com/) 获取,并且尽管它依赖于供应商,但遵循 GPL 许可。
主要功能是在断电事件发生时能够关闭系统,而不仅仅是 Nagios 的监控功能。对于后者,配置网络 UPS 工具更容易。
几乎所有 Linux 发行版都包含一个可用的 **`apcupsd`** 软件包,^([80]) 因此您无需担心安装问题。Nagios 不包含 **`apcupsd`** 插件,但有一个非常简单且有效的脚本可供下载,网址为 [`www.negativel.org/check_apc/`](http://www.negativel.org/check_apc/):**`check_apc`**.^([81]) 它也遵循 GPL 许可,但没有网络功能。插件运行时不能指定主机,也不支持任何其他类型的选项。相反,内部命令控制其功能,这些命令作为第一个参数给出。
执行 **`check_apc status`** 测试 UPS 是否在线。如果是这样,插件返回 OK 状态,在其他所有情况下返回 CRITICAL:
user@linux:nagios/libexec$ ./check_apc status
UPS OK - ONLINE
**`check_apc load`** **``*`warn crit`*``** 检查 UPS 当前的负载,并以最大容量的百分比显示。如果负载超过**``*`warn`*``**(以下示例中为 60%)指定的警告限制,则发出警告;如果负载超过**``*`crit`*``**(此处为 80%),则发出 CRITICAL。
user@linux:nagios/libexec$ ./check_apc load 60 80
UPS OK - LOAD: 39%
UPS 的负载状态通过命令**`check_apc bcharge`** **``*`warn crit`*``**进行检查。在这里,警告限制**``*`warn`*``**和临界限制**``*`crit`*``**也以百分比给出。值**`100`**表示“完全加载”。插件相应地如果负载小于警告限制则发出警告,如果负载小于临界限制则发出 CRITICAL。
user@linux:nagios/libexec$ ./check_apc bcharge 50 30
UPS OK - Battery Charge: 100%
你可以使用**`check_apc time`** **``*`warn crit`*``**来找出存储的电能可以维持多长时间。在这里,如果剩余时间少于**``*`warn`*``**分钟,则**`check_apc`**发出警告;如果剩余时间少于**``*`crit`*``**分钟,则发出 CRITICAL。
user@linux:nagios/libexec$ ./check_apc time 20 10
UPS OK - Time Left: 30 mins
* * *
^([80]) 至少 SuSE 和 Debian 使用这个包名。
^([81]) 它也可以在以下位置获得:[`www.nagiosexchange.org/54;615`](http://www.nagiosexchange.org/54;615)。
# 7.11 Nagios 自我监控
如果需要,Nagios 甚至可以自我监控:包含的插件**`check_nagios`**一方面测试 Nagios 进程是否正在运行,另一方面测试 Nagios **`var`** 目录中日志文件**`nagios.log`**的年龄,例如,**`/var/nagios/nagios.log`**。
尽管如此,这个问题需要被提出:如果 Nagios 本身没有运行,那么系统就无法执行插件,进而无法传递错误信息。解决这个问题的方法是拥有两个 Nagios 服务器,每个服务器都通过 NRPE(见第十章,第 213 页的“Nagios 远程插件执行器(NRPE)”)来处理对方服务器上本地安装的插件。
如果你只有一个 Nagios 服务器,你也可以通过 cron 单独运行**`check_nagios`**,并使用 shell 脚本来检查返回值。在这种情况下,你自己采取行动,如 7.11.1 使用脚本手动运行插件中所示,以便你得到适当的告知。
插件有以下选项:
**`-C`** **``*`/path/to/nagios`*``** **`/ --command=`****``*`/path/to/nagios`*``**
这是完整的 nagios 命令,包括路径(例如,**`-C /usr/local/nagios/bin/nagios`**)。
**`-F`** **``*`/path/to/logfile`*``** **`/ --filename=`****``*`/path/to/logfile`*``**
这是 Nagios 日志文件**`nagios.log`**的保存路径。该文件位于 Nagios 的**`var`**目录中。
**`-e`** **``*`integer`*``** **`/ --expires=`****``*`integer`*``**
这是日志文件的最大年龄。如果文件在超过**``*`integer`*``**分钟内没有发生变化,**`check_nagios`**将发出警告。
你应该确保这个时间指定足够大:如果没有当前错误发生,Nagios 不会在日志文件中记录任何内容。获取常规条目的唯一可靠方法是使用配置文件**`nagios.cfg`**中的参数**`retention_update_interval`**(见 A.1 主配置文件 nagios.cfg)。默认值是 60 分钟。
在以下示例中,日志文件不应超过 60 分钟(这对应于默认的*保留更新间隔*;见 A.1 主配置文件 nagios.cfg):
user@linux:nagios/libexec$ *./check_nagios -e 60 *
-F /var/nagios/nagios.log -C /usr/local/nagios/bin/nagios
NAGIOS OK: 1 process, status log updated 184 seconds ago
在一个运行中的 Nagios 进程和一个最后更改了 183 秒(大约三分钟)的日志文件的情况下,这里一切正常。如果省略了**`-e`**参数,插件总是给出警告。
## 7.11.1 使用脚本手动运行插件
以下示例脚本演示了如何在 Nagios 环境外调用插件。它最初像 Nagios 一样启动**`check_nagios`**,然后评估返回值。如果状态不是**`0`**,它将使用外部**`mailx`**程序给管理员 nagios-admin@example.com 发送电子邮件:
!/bin/bash
NAGCHK="/usr/local/nagios/libexec/check_nagios"
PARAMS="-e 60 -F /var/nagios/nagios.log -C /usr/local/nagios/bin/nagios"
INFO='$NAGCHK \(PARAMS' STATUS=\)?
case $STATUS in
0) echo "OK : " $INFO
;;
*) echo "ERROR : " $INFO |
/usr/bin/mailx -s "Nagios Error" nagios-admin@example.com
;;
esac
可以通过 cron 作业定期运行此脚本——例如每 15 分钟一次。但这样它也会每隔一刻钟就通过电子邮件“打扰”管理员。在这方面肯定有改进的空间——但这将超出本书的范围。
# 7.12 使用 LM Sensors 进行硬件检查
现代主板配备了传感器,允许你检查系统的“健康”状态。在**`lm-sensors`**^([82])项目中,在 Linux 中也可以通过 I2C 或 SMBus(*系统管理总线*,I2C 的一个特殊情况)查询这些数据。
要启用此功能,内核必须有一个合适的驱动程序。2.4.x 内核通常需要额外的模块,这些模块包含在软件中.^([83]) 有一些运气的话,你的发行版可能包含预编译的模块(例如,SUSE)。然而,2.6 内核已经包含了许多驱动程序;在这里,你只需编译以下整个分支**`I2C Hardware Sensors Chip support`**。
在这里详细说明必要模块的安装会占用太多空间。因此,我们只对**`check_sensors`**插件进行详细说明,并假设相应的内核驱动程序已经作为模块加载。在操作过程中,**`lm-sensors`**包中的**`sensors-detect`**程序会提供帮助,该程序执行一系列测试,然后告诉您需要加载哪些模块。如果所有要求都得到满足,运行**`sensors`**程序将产生类似于以下输出的结果,并显示板载传感器正在提供数据:
user@linux:~$ sensors
fscher-i2c-0-73
Adapter: SMBus I801 adapter at 2400
Temp1/CPU: +41.00 C
Temp2/MB: +45.00 C
Temp3/AUX: failed
Fan1/PS: 1440 RPM
Fan2/CPU: 0 RPM
Fan3/AUX: 0 RPM
+12V: +11.86 V
+5V: +5.10 V
Battery: +3.07 V
输出取决于硬件,因此对于每台计算机都会略有不同。例如,您可以看到 CPU 和主板温度(41 和 45 摄氏度),风扇的转速,以及 12 伏和 5 伏电路和电池上的电压。根据板设计和生产商的不同,某些详细信息可能缺失;在这个例子中,只有电源风扇**`FAN1/PS`**^([84])提供了信息;**`Fan3/AUX`**指的是计算机箱内的额外风扇,尽管它在运行,但芯片组没有记录。
除了标准选项**`-h`**(帮助功能)、**`-v`**(详细),它显示传感器的响应,以及**`-V`**,它显示插件版本之外,插件本身没有特殊选项。警告和临界限制必须通过**`lm-sensors`**配置设置。**`check_sensors`**只返回板载传感器的状态:
user@linux:nagios/libexec$ ./check_sensors
sensor ok
如果使用**`-v`**选项调用,您可以更清楚地看到测试是否工作:
user@linux:nagios/libexec$ ./check_sensors -v
fscher-i2c-0-73 Adapter: SMBus I801 adapter at 2400 Temp1/CPU: +40.00 C Temp2/MB:
+45.00 C Temp3/AUX: failed Fan1/PS: 1440 RPM Fan2/CPU: 0 RPM
Fan3/AUX: 0 RPM +12V: +11.86 V +5V: +5.10 V Battery: +3.07 V
sensor ok
输出行仅为了打印目的而换行;插件在单行上显示详细信息。
或者,您可以使用 SNMP 来访问传感器数据:NET-SNMP 软件包(见第 234 页的 11.2 NET-SNMP)提供了**`lm-sensors`**提供的数据,并且通过 SNMP 插件**`check_snmp`**,还可以从 Nagios 设置警告限制。这种解决方案在 11.3.1 通用 SNMP 插件 check_snmp 中描述,见第 246 页。
* * *
^([82]) [`www.lm-sensors.nu/`](http://www.lm-sensors.nu/)
^([83]) [`secure.netroedge.com/˜lm78/download.html`](http://secure.netroedge.com/%CB%9Clm78/download.html)
^([84]) PS 代表**电源供应**;但显示的名称可以在**`/etc/sensors.conf`**中进行编辑。
# 第八章. 特殊任务插件
许多插件实际上并不适合本地检查与远程检查的分类,因为它们本身不检测操作系统状态,而是操作其他检查的结果或将它们总结成新的结果。这些包括始终返回固定结果的插件**`check_dummy`**,以创建一个为测试场景定义良好的环境。
**`negate`**(取消返回值)和**`urlize`**(将超链接添加到文本输出)操作输出。总结和处理检查结果是**`check_cluster`**和**`check_multi`**的任务。其中**`check_cluster`**仅组合和评估现有状态,而**`check_multi`**则直接调用指定的插件并组合其结果。
# 8.1 用于测试的虚拟插件
对于预期以定义响应结束的测试,可以使用**`check_dummy`**插件。它被赋予一个返回值和所需的响应文本作为参数,并精确地提供这两个响应作为结果:
nagios@linux:nagios/libexec$ ./check_dummy 1 "Debugging"
WARNING: Debugging
nagios@linux:nagios/libexec$ echo $?
1
输出行包含定义的响应,前面是文本形式的状况。返回值可以通过**`echo $?: 1`**再次检查,其中**`1`**代表 WARNING。
或者,你可以给**`check_dummy`**一个**`0`**(OK)、**`2`**(CRITICAL)或**`3`**(UNKNOWN)作为第一个参数。第二个参数,响应文本,是可选的。
# 8.2 取消插件结果
在某些情况下,你可能想测试标准插件通常测试的相反情况,例如一个不应激活的接口,一个不应通常可达的网页或主机。在这些情况下,Nagios 插件中包含的**`negate`**程序提供了一种取消原始检查返回值的方法。
与插件类似,**`negate`**有一个选项可以指定秒数作为超时时间,使用**`-t`**,之后应终止操作。实际的命令行必须始终包含插件的全路径:
negate plugin command
negate -t timeout plugin command
**`negate`**将**`2`**(CRITICAL)的返回值改为**`0`**(OK),反之亦然。返回代码**`1`**(WARNING)和**`3`**(UNKNOWN)保持不变。
以下示例在主机**`192.0.2.1`**上执行**`check_icmp`**,在正常情况下不应可达:
nagios@linux:nagios/libexec$ ./negate
/usr/local/nagios/libexec/check_icmp -H 192.0.2.1
CRITICAL - 192.0.2.1: rta nan, lost 100%| rta=0.000ms;200.000;500.000;0;
pl=100%;40;80;;
nagios@linux:nagios/libexec$ echo $?
0
在这种情况下,插件本身返回一个 CRITICAL 状态和相应的文本。**`negate`**“反转”返回值;**`2`**(CRITICAL)变为**`0`**(OK)。由于文本来自插件且未更改,因此信息**`CRITICAL`**仍然在这里。然而,对于 Nagios 本身来说,只有返回值才是任何感兴趣的。
# 8.3 使用**`urlize`**插入超链接
如果需要,程序**`urlize`**将插件文本输出表示为超链接,这样在 Nagios Web 界面上点击测试结果就会带你到另一个网页。与**`negate`**类似,**`urlize`**作为正常插件命令的包装器,包含在其他 Nagios 插件中。
作为第一个参数,它期望一个有效的 URL,该 URL 是超链接应指向的位置。之后是插件命令,包括其路径:
urlize url plugin command
为了避免插件参数中的空格问题,您可以设置完整的
**``*`插件命令`*``**用双引号括起来。
当手动运行命令时,可以轻松地识别围绕正常插件输出的超链接:
nagios@linux:nagios/libexec$ ./urlize http://www.swobspace.de \ /usr/local/nagios/
libexec/check_http -H www.swobspace.de
HTTP OK HTTP/1.1 200 OK - 2802 bytes
in 0.132 seconds |time=0.132491s;;;0.000000 size=2802B;;;0
在版本 1.4 中,**`urlize`**也将性能输出嵌入到链接文本中,但 Nagios 在 Web 界面的表示之前将其截断,包括结束标签。但大多数浏览器对缺失的**`</A>`**没有问题。
# 8.4 将主机或服务集群作为一个实体进行检查
插件通常检查单个主机或服务,将结果与指定的阈值进行比较,然后返回适当的结果。在冗余设计系统(如集群)中,您也可以单独检查相应的主机或服务。此外,对虚拟主机或服务的检查可以提供有关整个虚拟系统是否可访问的线索。插件**`check_cluster`**允许查询更复杂的价值。
例如,我们将以一个由五个相同单系统组成的主机集群为例。这些主机中的一个可能没有任何问题就失败了,但如果第二个失败了,插件应该发出 WARNING。如果第三个主机应该失败,则肯定应该发出 CRITICAL 信号。
**`check_cluster`**的特殊之处在于它本身不主动执行检查,而是从所需的主机或服务已存在的状态值中确定返回值。为此,它使用按需宏(参见第 632 页的 D.2 按需宏)。与标准宏始终引用当前主机或服务相比,这对于**`check_cluster`**显然意义不大,按需宏允许访问其他主机或服务的所有现有信息。
对于**`check_cluster`**,我们需要各种主机或服务的状态。这些可以通过按需宏**`$HOSTSTATEID:`**和**`$SERVICESTATEID:`**确定。它们都提供相应的状态,以数值形式表示:**`0`**表示 OK;对于主机,**`1`**表示 DOWN,**`2`**表示 UNREACHABLE;对于服务,**`1`**表示 WARNING,**`2`**表示 CRITICAL,**`3`**表示 UNKNOWN).^([85]) 在每种情况下,都必须指定主机名,并且对于**`$SERVICESTATEID$`**,还必须给出从 Nagios 获取值的宿主或服务的服务描述。
插件有以下选项:
**`-s / --service`**
将状态值作为服务检查的结果处理,即**`0`**表示 OK,**`1`**表示 WARNING,**`2`**表示 CRITICAL
**`-h / --host`**
将状态值作为主机检查的结果处理,即**`0`**表示 UP,**`1`**表示 DOWN,**`2`**表示 UNREACHABLE
**`-l`** **``*`label`*``** **`/ --label=`****``*`label`*``**
将指定的文本 **``*`label`*``** 插入到文本输出中
**`-d`** **``*`statusliste`*``** **`/ --data=`****``*`statusliste`*``**
以逗号分隔的状态列表,从这些状态中确定总结果;这里使用已提到的宏:
--data=\(HOSTSTATEID:srv1\),\(HOSTSTATEID:srv2\),\(HOSTSTATEID:srv3\)
**`-w`** **``*`schwellwert`*``** **`/ --warning=`****``*`schwellwert`*``**
警告阈值在阈值格式中,^([86]) 与错误状态的数量相关。所以通过指定 **`-w 0:2`**,允许最多两个错误状态为 OK 结果。从第三个错误状态开始,将发出警告。
**`-c`** **``*`threshold`*``** **`/ --critical=`****``*`threshold`*``**
与 **`--warning`** 类似,但指的是关键阈值
以下调用模拟了五个现有 Web 服务器中两个发生故障的情况。第三个服务器显示警告。这意味着我们总共有三个错误状态:
nagios@linux:local/libexec$ ./check cluster -s -d 0,2,1,0,2 -w 0:2 -c 0:3
CLUSTER WARNING: Service cluster: 2 ok, 1 warning, 0 unknown, 2 critical
检查发出警告,因为超过了警告阈值(即使关键阈值没有)。**`check_cluster`** 命令的定义保持简单:
define command{
command_name check_cluster
command_line \(USER1\)/check_cluster -l \(ARG1\) \(ARG2\)
}
命令期望一个标签作为第一个参数,并将插件将其添加到文本输出之前。其他所有内容都在第二个参数中定义,在主机或服务定义中:
define service{
host_name mycluster
service_description Web Cluster
command check_cluster!Web Cluster!--service -d \(SERVICESTATEID:srv1:
HTTP\), \(SERVICESTATEID:srv2:HTTP\) -w 0:0 -c 0:1
}
服务 **`Web Cluster`** 检查两个服务 **`srv1:HTTP`** 和 **`srv2:HTTP`** 的服务状态。只要它们都工作正常且无错误,命令将返回 OK。如果存在错误状态,结果将是警告,如果两个服务都有错误,则返回 CRITICAL。
这完成了 **`check_cluster`** 的可能性。如果您对仅仅评估现有错误状态的数量不满意,您应该更仔细地查看插件 **`check_multi`**,它还允许 AND 和 OR 操作。
* * *
^([85]) 请参阅第 625 页的附录 D。
^([86]) 关于阈值的指定,请参阅第 557 页的 24.1.5 指定阈值。
# 8.5 使用 **`check_multi`** 汇总检查
将不同的检查组合成一个的原因有很多。一方面,它简化了 Nagios 的工作,因为现在系统只需要管理 1,000 个程序,而不是可能 20,000 个——这在许多情况下显著提高了性能。如果您远程汇总检查,Nagios 现在执行 1 次而不是 20 次网络查询,这导致更好的网络性能。Nagios 管理员也可能更容易配置,因为配置更简洁。
原计划用于负载分配和减少检查的方法是通过分布式 Nagios 实例。当然,有一些生产安装中,一个 Nagios 实例只执行 50 个检查并将这些检查传输到中央 Nagios 安装。如果有几百个 Nagios 实例,这种方法确实可以减轻中央 Nagios 安装的负载,但不会减轻管理员的工作负担,因为管理员需要管理大量的此类配置。
Matthias Flacke 编写的插件**`check_multi`**采取了不同的方法。它以去中心化的方式执行(几乎)任何数量的检查,并将结果的汇总仅返回给 Nagios 服务器(图 8-1)。该插件在远程执行;它可以通过 NRPE(第十章,第 213 页)或通过插件**`check_by_ssh`**(9.1 check_by_ssh 插件,第 206 页)来调用。

图 8-1. 使用`check_multi`汇总检查
在此过程中会丢失信息——最终,每个**`check_multi`**调用只能有一个返回值。但通过配置服务,你可以获得清晰度,并且意外地获得了一个很好的功能:必须执行的检查列在**`check_multi`**也安装的对应目标系统上的类似 NRPE 的配置文件中。这使得可以将某些任务,例如阈值维护,委托给其他(非 Nagios)管理员。他们需要访问相关的**`check_multi`**配置文件的写权限,但不需要继续与 Nagios 配置纠缠——除了正确运行所使用的插件之外。
为了传递尽可能多的信息,**`check_multi`**经常使用 Nagios 3.0 引入的多行插件输出格式(见 8.5.1 多行插件输出)。这基本上限制了**`check_multi`**的使用范围到 Nagios 3.0。从**`check_multi`**版本 0.14 开始,已经有一些方法来支持 Nagios 2.x。然而,这些方法的使用有限,因为 Nagios 2.x 中插件的所有信息大约有 300 字节,并且只使用了插件输出的第一行。
## 8.5.1 多行插件输出
从 Nagios 3.0 开始,引入了插件扩展输出格式。而不是将所有内容挤在单行上,输出可以扩展到多行:
normal text output | optional performance data
longtext, 1st line
longtext, 2nd line
...
longtext, n-th line | performance data, 2nd line
performance data, 3rd line
...
performance data, n-th line
第一行包含标准文本输出,如果需要,还会补充性能数据。这一行仍然可以被 Nagios 2.x 处理,因此它不应该超过 300 字节。在随后的行中,插件可以提供其他文本信息,直到字符 **`|`** 关闭文本输出,并允许写入其他性能数据。Nagios 3.0 在 Web 界面上的 **`extinfo.cgi`** 生成的状态信息中显示整个文本信息(参见第 339 页的 16.2.2 额外信息和控制中心:extinfo.cgi)。
当通过宏访问文本信息时(参见第 627 页的 D.1 标准宏),Nagios 将信息分成两个宏:**`$HOSTOUTPUT$`** 包含主机检查的文本信息的第一行(即占位符 **``*`normal text output`*``** 的内容),而 **`$LONGHOSTOUTPUT$`** 只包含长文本。对于服务检查,宏称为 **`$SERVICEOUTPUT$`** 和 **`$LONGSERVICEOUTPUT$`**。宏的 **`LONG*`** 变体仅在 Nagios 3.0 及以后版本中可用;Nagios 2.x 只知道短版本。
Nagios 3.0 将第一行和末尾的性能数据汇总到宏 **`$HOSTPERFDATA$`** 和 **`$SERVICEPERFDATA$`** 中。没有 **`LONG*`** 变体,正如输出那样。
在 Nagios 3.0 中,整个输出(包括性能数据)最长为 8 KB。如果 Nagios 直接运行插件,而不是间接运行(例如,通过 NRPE 或 **`check_by_ssh`**),你必须确保整个 8 KB 确实通过了整个传输路径。这已在 8.5.2 安装要求 中说明。
## 8.5.2 安装要求
**`check_multi`** 对其输出的尺寸没有限制。为了支持足够的检查,你应该确保所有使用的资源都允许至少 8 KB 的插件输出。对于 Nagios 3.0 版本,开发人员已将缓冲区大小增加到 8 KB,因此不需要调整。对于涉及 NRPE 或 **`check_by_ssh`** 的远程使用场景,你可能需要手动调整。
### 调整 NRPE 的缓冲区大小
默认情况下,NRPE (第十章"), 第 213 页) 传输不超过 1,024 个字符。为了正确使用 **`check_multi`**,你需要调整源代码中的缓冲区大小。为此,你需要在文件 **`include/common.h`** 中设置适当的值为 **`8192`**:
define MAX_INPUT_BUFFER 8192
define MAX_PACKETBUFFER_LENGTH 8192
之后,你必须重新编译和重新安装 NRPE 守护进程和 **`check_nrpe`** 插件。
### 调整 **`check_by_ssh`** 的缓冲区大小
插件**`check_by_ssh`**(9.1 check_by_ssh 插件,第 206 页)可以处理版本 1.4.10 及更高版本的插件的多行输出,因此可以不修改直接使用。对于旧版本,需要补丁,可以在**`check_multi`**主页上找到.^([87])
## 8.5.3 安装和测试
在从非常详尽的、有良好文档的首页下载插件后,^([88])你应该在任何目录中解压缩它,然后切换到该目录以执行初始测试。在源代码的**`contrib`**子目录中有一个预配置的文件,**`check_multi.cmd`**,其中包含几个示例检查。在运行插件时,使用选项**`-f`**指定此文件;**`check_multi`**将一次性执行那里定义的所有检查。此输出让你对插件的功能有了一定的感觉:
user@linux:~$ ./check_multi -f contrib/check_multi.cmd
MULTI CRITICAL - 35 plugins checked, 7 critical (network_rsync, proc_acp id,
proc_httpd, system_syslog, system_users, nagios_system, dummy_critical), 2 warning
(nagios_tac, dummy_warning), 2 unknown (network_if_ethl, dummy_unknown), 24 ok
[1] network_ping PING OK - Packet loss = 0%, RTA = 0.06 ms
[2] network_interfaces OK: host 'localhost', interfaces up: 6, down: 0, dormant: 0,
excluded: 0, unused: 0
[3] network_if_eth1 Either a valid snmpkey key (-k) or a ifDescr (-d) must be
provided)
...
[16] system_load OK - load average: 0.89, 0.71, 0.71
[17] system_mail TCP OK - 0.000 second response time on port 25
[18] system_mailqueue OK: mailq is empty
[19] system_mysql Uptime: 5573 Threads: 1 Questions: 140 Slow queries
: 0 Opens: 137 Flush tables: 1 Open tables: 19 Queries per second avg
: 0.025
[20] system_ntp NTP OK: Offset −0.07118669868 secs
[21] system_portmapper OK: RPC program portmapper version 2 udp running
[22] system_rootdisk DISK OK - free space: / 287 MB (31% inode=81%);
[23] system_ssh SSH OK - OpenSSH_4.3p2 Debian-9 (protocol 2.0)
...
|MULTI::check_multi::plugins=35 time=10.92 network_interfaces::check_ifs tatus::
up=6,down=0,dormant=0,excluded=0,unused=0 system_load::check_load ::
load1=0.890;5.000;10.000;0; load5=0.710;4.000;8.000;0; load15=0.710;3. 000;6.000;0;
system_mail::
check_tcp::time=0.000225s;;;0.000000;10.000000 system_mailqueue::check_mailq::
unsent=0;2;4;0
system_ntp::check_ntp::off set=−0.071187s;60.000000;120.000000; system_rootdisk::
check_disk::
/=620M B;909;937;0;957 system_swap::check_swap::swap=3906MB;0;0;0;3906 system_u sers::
check_users::users=25;5;10;0 nagios.org_dns::check_dns::time=0.039 187s;;;
0.000000 nagios.org_http::check_http::time=0.674044s;;;0.000000 s ize=21530B;;;0
输出的第一行——以**`MULTI CRITICAL`**开头——总结了所有已执行的检查。这些行(为了显示目的而换行)也由 Nagios 2.x 处理。单个检查的输出从第 2 行开始(以**`[ 1]`**开头),这与当前正在运行的插件的单次调用输出完全相同。性能数据由**`check_multi`**总结,但仅在末尾的总计行中——以**`| MULTI::check_multi::plugins`**开头。各个变量由空格分隔。变量名称的目的,以及它们的格式(需要一些时间来适应),在 8.5.6 性能数据和 PNP 的第 198 页中解释。
## 8.5.4 配置文件
配置文件的格式基于 NRPE 的格式(10.3 监控计算机上的 NRPE 配置,第 218 页)。然而,对于**`check_multi`**,只定义了命令。以下是包含的示例文件摘录,**`check_multi.cmd`**:
...
command[ network_interfaces ] = check_ifstatus -H localhost
command[ system_load ] = check_load -w 5,4,3 -c 10,8,6
command[ system_mail ] = check_tcp -H localhost -p 25
command[ system_mailqueue ] = check_mailq -w 2 -c 4
command[ system_mysql ] = check_mysql -u admin
command[ system_ntp ] = check_ntp -H ntp1.fau.de
command[ system_portmapper ] = check_rpc -H localhost -C portmapper
command[ system_rootdisk ] = check_disk -w 5% -c 2% -p /
command[ system_ssh ] = check_ssh localhost
...
命令**`command[`** **``*`Name_of_check`* ]``**指定了相应检查的名称。这在文本输出和性能数据中使用。
等号后面是执行的检查。在调用插件时,如果插件位于默认路径**`/usr/local/nagios/libexec`**,则可以省略路径细节。或者,在运行**`check_multi`**时,可以使用选项**`−1`**包含插件路径。当然,你还可以在配置文件中指定绝对路径。
## 8.5.5 命令行参数
**`check_multi`**有以下选项:
**`-f`** **``*`/path/to/config/file`*``** **`/ --filename=`****``*`/path/to/config/file`*``**
这指定了配置文件。为了使 Nagios 能够找到它,您应该始终指定完整的路径。此选项没有默认值;它可以多次指定。
**`-l`** **``*`/path/to/the/plugins`*``** **`/ --libexec=`****``*`/path/to/the/plugins`*``**
调用插件的默认路径是 **`/usr/local/nagios/libexec`**。如果它们位于不同的目录中,可以使用 **`-l`** 选项在这里指定。
**`-n`** **``*`name`*``** **`/ --name=`****``*`name`*``**
这是 **`check_multi`** 在文本输出和性能数据中输出的检查名称。默认为空字符串。如果您在机器上多次运行 **`check_multi`** 并使用不同的检查,这里最好使用不同的名称,以便它们之间更加清晰地区分开来。
**`-t`** **``*`sekunden`*``** **`/ --timeout=`****``*`seconds`*``**
这指定了单个检查的超时时间。默认为 **`10`** 秒。
**`-T`** **``*`seconds`*``** **`/ --TIMEOUT=`****``*`seconds`*``**
对于所有检查一起,**`check_multi`** 需要一个额外的超时参数,该参数通过 **`-T`** (默认为 **`60`** 秒) 定义。
这确保了 **`check_multi`** 的调用将在指定的时间内结束。如果单个插件启动时间和超时超过了整个 **`check_multi`** 调用的超时,插件将不会启动任何新的检查。^([[89]) 这样的单个检查将被赋予未知状态;在输出中,**`check_multi`** 将它们分配给消息 **`plugin cancelled due to global timeout`**。
**`-r`** **``*`integer`*``** **`/ --report=`****``*`integer`*``**
此选项控制 **`check_multi`** 的输出行为。占位符 **``*`integer`*``** 可以取以下值:
+ **`1`** 在插件输出中包含括号内的服务名称以表示错误状态:
```
..., 2 critical (network_rsync, proc_acpid), 1 warning (nagios_tac), 1 unknown
(if_eth1), dummy_unknown), 24 ok
```
+ **`2`** 将输出格式化为 HTML。在这里,存储了单个检查的编号(例如,[ **`3`**])以及相应的返回值颜色(绿色表示 OK,黄色表示 WARNING,红色表示 CRITICAL,橙色表示 UNKNOWN)。
如果您递归地使用 **`check_multi`**(一个 **`check_multi`** 本身调用其他 **`check_multi`** 实例),则下属检查的输出将缩进(见第 202 页的图 8-3)。
+ **`4`** 如果存在,则在 STD-ERR 上显示单个检查的输出。
+ **`8`** 以多格式输出性能数据(见第 8.5.6 节“性能数据和 PNP”,第 198 页)。
+ **`16`** 与 **`1`** 有相同的功能,除了对于没有检查结果的状态(例如,**`0 unknown`**)也会包括在内。
+ **`32`** 以经典格式输出性能数据(见 8.5.6 性能数据和 PNP)。
+ **`128`** 通过包含一个指向已安装的 PNP 的超链接来扩展了**`2`**所需的 HTML 格式,如果可用性能数据且输出为多格式(**`8`**)。PNP 在 19.6 使用 PNP 进行平滑绘图的第 446 页进行描述。
+ **`256`** 以 XML 格式显示输出。
+ **`512`** 确保输出与 Nagios 2.x 兼容,以便将输出控制在 300 字节限制以下。
可以组合单个值;默认为 13(8 + 4 + 1)。
**`-w`** **``*`expression`*``** **`/ --warning=`****``*`expression`*``**
如果**``*`expression`*``**为真,则设置状态为 WARNING,例如**`COUNT (WARNING) > 0`**(默认)。对于所有状态,**`check_multi`**分别检查相应的状态是否已确定。最终,具有最高优先级的状态获胜:CRITICAL 胜过 WARNING,胜过 UNKNOWN,胜过 OK。表达式定义和使用的说明见 8.5.7 简单业务流程监控的第 199 页。
**`-c`** **``*`ausdruck`*``** **`/ --critical=`****``*`expression`*``**
如果表达式为真,则将状态设置为 CRITICAL。最终,具有最高优先级的状态获胜(见**`--warning`**和 8.5.7 简单业务流程监控)。
**`-u`** **``*`expression`*``** **`/ --unknown=`****``*`expression`*``**
如果表达式为真,则设置状态 UNKNOWN。具有最高优先级的状态(见**`--warning`**和 8.5.7 简单业务流程监控)获胜。
**`-o`** **``*`expression`*``** **`/ --ok=`****``*`expression`*``**
如果**``*`ausdruck`*``**为真,则设置状态 OK。在这里,具有最高优先级的状态也获胜(见**`--warning`**和 8.5.7 简单业务流程监控)。
**`-v / --verbose`**
这增加了插件的详细程度,以便进行调试。此选项最多可以使用三次;如果指定了三次,您将获得最详细的信息。
## 8.5.6 性能数据和 PNP
在性能数据的简单输出形式(可以通过选项**``*`-r`*``** **`32`**设置)中,**`check_multi`**简单地列出插件提供的所有变量:
...|rta=0.111ms;500.000;1000.000;0; pl=0%;5;10;; offset=0.002980s;60.000 000;
120.000000;
在这个例子中,插件 **`check_icmp`**(平均响应时间 **``*`r`*``****`ta`** 和丢包率 **`pl`**)的性能数据无缝地跟随 **`check_ntp`** 的性能数据,形式为与本地系统时间的偏差(**`offset`**)。一开始你无法判断信息来自哪个插件——你必须查阅配置文件的顺序和各个检查的输出。
这并不特别适合自动处理。因此,**`check_multi`** 提供了默认选项 **``*`-r`*``****`8`** 的扩展输出,该选项专门修改以处理 PNP(参见第 446 页的 19.6 使用 PNP 进行平滑绘图)。在这种情况下,插件会将服务描述和所使用的插件名称添加到变量名称中。没有偏离标准化格式;标签只是给出了更广泛的形式:
servicedescription:: plugin:: label = values [label = calues]
PNP 需要有关已执行插件的详细信息,以便它可以选择一个合适的模板来处理图形(参见第 454 页的 19.6.5 图形应该如何显示?)。此外,**`check_multi`** 现在也提供了关于整体处理的性能数据:
|MULTI::check_multi::plugins=5 time=0.18 net_ping::check_icmp::rta=0.048 ms;
500.000;1000.000;0; pl=0%;5;10;; system_ntp::check_ntp::offset=0.0022 66s;60.000000;
120.000000;
首先 **`check_multi`** 宣布它已调用 **`5`** 个插件,并用了总共 0.18 秒来处理。随后是其他插件的性能数据,每个都补充了服务描述和插件名称。如果一个插件发出多个变量,则服务描述和插件名称不会重复。
## 8.5.7 简单业务流程监控
为了评估业务流程,你通常想知道某个特定流程是否在运行——例如,客户是否能够进行在线银行操作。所有涉及的主机和服务的个别信息从这个角度来看并不相关,而且在系统以不同形式冗余设计的情况下也并不总是有用的。

图 8-2. 要从互联网访问终端服务器农场,必须提供 OpenVPN 访问和终端服务器。
一个例子显示在 图 8-2 中:在家办公的用户通过 OpenVPN 访问终端服务器农场。对于从互联网的访问,有两个连接可用,并且有 **`gate1`** 和 **`gate2`**,两个 OpenVPN 网关可用。终端服务器农场由八个终端服务器 **`ts01`** 到 **`ts08`** 组成。
为了让在家办公的用户能够工作,至少必须有一个互联网连接(包括伴随的网关)可用,并且服务器场必须可访问。业务流程可以分为两个过程:我们的例子将互联网访问与服务器场分开,然后可以使用一个过程将两个结果连接起来。
互联网访问处于关键状态的条件可以表述如下:
(gate1 > 1 || provider1 > 1) && (gate2 > 1 || provider2 > 1)
如果提供者不可达或(**`||`**)网关上没有可用的 OpenVPN 服务,则访问不可用。但如果两个接入点中的任何一个正在工作(因此使用 && 逻辑运算符),则足够了。语法来自 Perl,并且可以由 **`check_multi`** 同样处理。因此,用于互联网检查的配置文件包含四个命令和逻辑运算符:
openvpn.cmd
command[ gate1 ] = check_nrpe -H gate1 -c check_openvpn
command[ provider1 ] = check_icmp -H provider1 -c 1000.0,60%
command[ gate2 ] = check_nrpe -H gate2 -c check_openvpn
command[ provider2 ] = check_icmp -H provider2 -c 1000.0,60%
state[warning] = count(CRITICAL) > 0 || count(UNKNOWN) > 0
state[critical] = (gate1 > 1 || provider1 > 1) && (gate2 > 1 || provider
2 > 1)
两个 **`gate*`** 命令各自检查(通过 NRPE)OpenVPN 服务的网关是否正在运行。提供者测试向各自提供者的拨号路由器发送 ICMP 回显数据包。在这里,你应该非常小心,确保路由设置正确,即向各自提供者的 ICMP 数据包确实是通过伴随的连接发送的。
对于业务流程,配置文件中定义了单个状态的布尔表达式,因此根据需要,可能会有一个用于 CRITICAL,一个用于 WARNING,如果需要,还有一个用于 UNKNOWN。语法和运算符按照指定传递给 Perl,并在 Perl 在线文档(**`man`** **``*`per`*``****`lop`**)中详细描述。在评估表达式之前,**`check_multi`** 执行以下替换:
+ 如果表达式中包含之前使用 **`command`** 定义的检查的名称,则将使用该检查的返回值。假设检查 **`gatel`** 返回 **`2`**,检查 **`providerl`** 返回 **`1`**。那么上述部分表达式将变为
```
state [critical] = (2 > 1 || 1 > 1) ...
```
在括号内,第一个条件为真,并通过随后的 OR(Perl 语法中的 **`||`**)操作,部分表达式评估为真。
+ 函数 **`count`** 确定所有提供作为参数给出的返回值的检查的数量。
+ 在表达式中,除了状态数值之外,还可以包含文本形式(UNKNOWN、WARNING、CRITICAL、WARNING、OK),(因此可以写类似 **`gate1 > WARNING`** 的内容)。这个细节在表达式评估之前由 **`check_multi`** 替换为数值。
当至少发生一个关键状态、至少一个检查返回未知或至少一个检查返回警告时,警告状态将在**`openvpn.cmd`**中设置。如果两个访问都应失败(因为括号中两个部分表达式之间的 AND 逻辑运算符),则会出现关键状态。如果**`gate`**或**`provider`**检查中的任何一个返回关键(返回值**`2`**)或未知(返回值**`3`**),则部分表达式本身为真。由于未知结果总是导致警告状态,因此可以省略未知状态的条件。
第二个部分过程——终端服务器农场的功能——在配置文件**`terminalserver.cmd`**中描述:
terminalserver.cmd
command[ ts01 ] = check_tcp -H ts01 -p 3389
command[ ts02 ] = check_tcp -H ts02 -p 3389
command[ ts03 ] = check_tcp -H ts03 -p 3389
command[ ts04 ] = check_tcp -H ts04 -p 3389
command[ ts05 ] = check_tcp -H ts05 -p 3389
command[ ts06 ] = check_tcp -H ts06 -p 3389
command[ ts07 ] = check_tcp -H ts07 -p 3389
command[ ts08 ] = check_tcp -H ts08 -p 3389
state[ warning ] = count(CRITICAL) > 0 || count(UNKNOWN) > 0 || count(WA
RNING) > 0
state[ critical ] = ts01 >= CRITICAL || count(CRITICAL) > 3
这里单独的检查仅包括对 RDP 端口 3389 的原始 TCP 检查,以保持示例相对简单。如果至少发生一个关键或至少一个未知,应指示警告,以便管理员有机会在早期修复问题。对于关键状态的条件规定,**`ts01`**不得为关键,因为那里运行着一个非常特定的应用程序,其他服务器上没有。此外,不超过三个终端服务器可能失败,否则其他服务器的负载可能会增加得如此之高,以至于无法进行有用的工作。

图 8-3. Nagios Web 界面扩展信息页面上的`chech_multi`递归输出
部分过程的两个检查通过一个**`check_multi`**调用汇总为一个单一的结果(以下行是为了显示目的而换行的):
homeoffice.cmd
command[ openvpn ] = check_multi -f /etc/nagios/check_multi/openvpn.cmd
-r31
command[ terminalserver ] = check_multi -f /etc/nagios/check_multi/termi
nalserver.cmd -r31
为了使 Nagios 的扩展信息页面(图 8-3)更具可读性,省略了各自的插件名称的细节(通过缺失的选项**`-n`**;**`check_multi`**的递归 HTML 输出添加了无论如何被调用的检查名称)。**`-r 31`**细节设置所有报告功能从 1 到 16,包括 HTML 格式(**``*`-r`*``** **`2`**)。没有为状态的特殊条件制定公式,因此部分过程的警告会导致上层检查的警告,而关键会导致关键。
图 8-3 清楚地显示了两个部分流程。检查的序列号与相应的状态颜色一起存储,遗憾的是,这些颜色在这本黑白书中不可见。在插件主页上可以找到复杂颜色示例的递归显示在扩展信息 Web 页面上.^([90])
为了完整性,以下是 Nagios 的命令和服务的定义。前者被故意保持简单,并且所有命令行的详细信息都在服务定义中重复:
define command{
command_name check_multi
command_line \(USER1\)/check_multi \(ARG1\)
}
define service{
host_name elix01
service_description homeoffice
check_command check_multi!-f /etc/nagios/check_multi/homeoffice.cmd -n
homeoffice -r 31
...
}
如果使用**`check_multi`**对业务流程的映射不足以满足您的需求,您应该查看来自德国纽伦堡的 Sparda-Datenverarbeitung eG 提供的相对更复杂的插件*Nagios Business Process View and Nagios Business Impact Analysis*,该插件可在 Nagios-Exchange 上找到.^([91])
与仅作为唯一 Nagios 服务出现且只需由 Nagios 管理一次的**`check_multi`**不同,此插件使用 Nagios 中已定义的服务,这意味着 Nagios 会像往常一样执行每个单个检查。它检索单个检查的结果,将这些结果链接起来,并在自己的 Web 界面上显示。
在这样做的时候,这些链接(即业务流程)的结果可以在 Nagios 中重新定义为单独的服务,这样就可以使用 Nagios 的通知逻辑。此外,该插件还包括一个模式,可以模拟“如果发生什么情况”的情景。单个服务被设置为预期的状态,并且可以通过 Web 界面查看其效果。
因此,**`check_multi`**和 Nagios Business Process View 以及 Nagios Business Impact Analysis 插件并不相互竞争。根据预期的用途,**`check_multi`**将减少 Nagios 中表示的服务复杂性,从而减少执行的检查数量,或者插件将允许更详细地查看整体事件,尽管它要求在 Nagios 中单独映射所有服务。
* * *
^([87]) [`www.my-plugin.de/wiki/de/projects/check_multi/installation#c heck_by_ssh`](http://www.my-plugin.de/wiki/de/projects/check_multi/installation#c%20heck_by_ssh)
^([88]) [`www.my-plugin.de/wiki/de/projects/check_multi/start`](http://www.my-plugin.de/wiki/de/projects/check_multi/start)
^([89]) 假设自**`check_multi`**被调用以来已经过去了 53 分钟,但并非所有计划的单个检查都已完成。从开始时间和单个超时(53 + 10 = 63)的总和超过了**`check_multi`**调用的超时时间,因此**`check_multi`**不会启动任何进一步的检查。
^([90]) [`www.my-plugin.de/wiki/de/projects/check_multi/screenshot#ser-vice_extended_info_rekursiv`](http://www.my-plugin.de/wiki/de/projects/check_multi/screenshot#ser-vice_extended_info_rekursiv)
^([91]) [`www.nagioserchange.org/22;1088`](http://www.nagioserchange.org/22;1088)
# 第九章。通过 SSH 执行插件
本地插件,即仅在本地上运行测试的程序,因为不存在网络协议,必须在目标系统上安装并启动。它们检查进程、CPU 负载或剩余多少空闲硬盘容量,等等。
但是,如果您仍然想从 Nagios 服务器执行这些插件,建议您使用安全外壳,特别是如果测试的机器上安装了任何类型的 Unix 系统——在这样的目标系统上,Secure Shell 守护进程几乎总是运行的,并且您不需要任何特殊权限来运行大多数插件。Nagios 管理员只需要一个账户,他可以从 Nagios 服务器使用这个账户。在服务器本身,必须安装**`check_by_ssh`**插件。
在异构环境中,Secure Shell 本身常常会创建可能导致问题的条件:根据操作系统,可能正在使用一个返回错误返回代码^([92])的 SSH 守护进程,或者它太旧,无法处理 SSH 协议版本 2.0。在这种情况下,最好安装当前的 OpenSSH 版本.^([93]) 在纯 Linux 环境中,如果安装最新且维护良好,这些问题通常不会发生。
# 9.1 **`check_by_ssh`**插件
**`check_by_ssh`**在 Nagios 服务器上运行,并建立一个到远程计算机的 Secure Shell 连接,以便可以在其上执行本地测试。在远程机器上运行的程序在很大程度上是本地插件(参见第七章测试本地资源,第 157 页);然而,**`check_by_ssh`**的使用并不仅限于这些。
插件向远程计算机发送完整的命令行,然后等待插件兼容的响应:一个介于**`0`**(OK)和**`3`**(UNKNOWN)之间的响应状态,以及一行文本信息供管理员使用(第六章)。
如果您通过**`check_by_ssh`**运行网络插件以在其他计算机上执行测试,这些被称为*间接检查*,将在 10.6 间接检查中解释,见第 224 页。
以下示例展示了如何使用**`check_by_ssh`**来检查目标计算机上的交换分区:
nagios@linux:nagios/libexec$ ./check_by_ssh -H target_computer
*-i /etc/nagios/.ssh/id_dsa *
-C "/usr/local/nagios/libexec/check_swap -w 50% -c 10%"
SWAP OK: 100% free (972 MB out of 972 MB) |swap=972MB;486;97;0;972
命令与安全外壳的命令类似,形式为
ssh -i private_key target_computer "command"
使用单独的私钥(不是主目录中的默认私钥)是可选的,并在 9.2 配置 SSH 中详细描述,从第 208 页开始。要运行的命令在 **`check_by_ssh`** 中指定——与安全的 shell **`ssh`** 相比——使用带有选项 **`-C`** 的命令,插件始终使用绝对路径。
**`check_by_sshhas`** 具有以下选项:
**`-H`** **``*`address`*``** **`/ --hostname=`****``*`address`*``**
插件应建立 SSH 连接的计算机的主机名或 IP 地址。
**`-C`** **``*`command`*``** **`/--command=`****``*`command`*``**
在远程计算机上运行的命令,即带有完整路径和所有必要参数的插件:
-C "/usr/local/nagios/libexec/check_disk -w 10% -c 5% -e -m"
**`−1 /--proto1`**
强制使用 secure shell 协议的第 1 版。
**`−2 /--proto2`**
强制使用 secure shell 协议的第 2 版。
**`-o`** **``*`ssh_option`*``** **`/--ssh-option=`****``*`ssh_option`*``** (从版本 1.4.6)
将 SSH 选项传递给目标主机上的 Secure Shell。要指定多个选项,请重复使用开关。
**`-i`** **``*`keyfile`*``** **`/--ldentlty=`****``*`keyfile`*``**
应使用哪个文件代替包含用户 **`nagios`** 的私钥的标准密钥文件。有关一个推荐选项,请参阅 9.2.3 检查 SSH 连接和 check_by_ssh,第 210 页。
**`-p`** **``*`port`*``** **`/--port=`****``*`port`*``**
如果目标服务器上的 Secure Shell 守护进程没有监听标准 TCP 端口 22,则指定端口号。
**`-l`** **``*`user`*``** **`/--logname=`****``*`user`*``**
目标主机上的用户名。 [**`-S`** **``*`number`*``** /**``--skip-stdout=*`number`*``** (从版本 1.4.9)]
忽略 STDOUT 输出的指定行数。如果省略此选项,则忽略整个输出。
**`-E`** **``*`number`*``** **`/--skip-stderr=`****``*`lines`*``** (从版本 1.4.9)
与 **`--skip-stdout`** 类似,但仅指 STDERR 的输出。
**`-w`** **``*`floating_point_decimal`*``** **`/--warning=`****``*`floating_point_decimal`*``**
如果执行命令的响应时间超过 *浮点小数* 秒,插件将发出警告。
**`-c`** **``*`floating_point_decimal`*``** **`/--critical=`****``*`floating_point_decimal`*``**
关于要执行的命令响应时间的临界值(以秒为单位)。
**`-f`**^([94])
在不打开交互式终端(tty)的情况下启动后台进程。
**`-t`** *超时时间* /**`--timeout=`***超时时间*
超过 *超时时间* 秒后,插件停止测试并返回 CRITICAL 状态。默认为 **`10`** 秒。
除了这个之外,**`check_by_ssh`** 还有一些可用的参数,**`-o`**,**`-s`** 和 **`-n`**,这使得它能够以**被动模式**将结果写入**外部命令接口**(参见第 292 页的 13.1 外部命令接口)。这种模式之所以被命名为这种方式,是因为 Nagios 本身并不直接接收信息,而是从接口间接读取。
此过程的优势在于能够在单个 SSH 连接上同时运行多个独立的命令。然而,这可能会使命令定义相当复杂。由于插件本身是在目标服务器上作为程序调用和执行的,所以 SSH 连接建立一次或三次几乎无关紧要。因此,最好使用简单的命令定义而不是被动模式。
但是,如果您仍然想了解更多关于这个的信息,您可以在在线帮助中查找,该帮助是通过 **`check_by_ssh -h`** 调用的。
* * *
^([92]) 在 **`nagios-users`** 邮件列表中报告说 **`Sun_SSH_1.0`** 返回代码为 255 而不是 0,这使得它不适合此处描述的部署。
^([93]) [`www.openssh.org/`](http://www.openssh.org/)
^([94]) 目前没有此选项的长格式。
# 9.2 配置 SSH
为了使 Nagios 能够在远程和自动的情况下通过安全外壳运行插件,它——或者更严格地说,Nagios 服务器上的用户 **`nagios`**——不能被任何密码查询所打扰。这通过通过公钥机制进行登录来避免。
## 9.2.1 在 Nagios 服务器上生成 SSH 密钥对
执行此操作所需的关键对默认由密钥生成器 **`ssh-keygen`** 存储在相应用户主目录的子目录 **`.ssh`** 中(对于用户 **`nagios`**,这因此对应于第 39 页的 1.2 编译源代码中的安装指南,即 **`/usr/local/nagios`**)。如果它还通过 **`-f`** **`private_keyfile`** 选项(不指定路径)发送,它将落在当前工作目录中,在下面的例子中是 **`/etc/nagios/.ssh`**:
nagios@linux:~$ mkdir /etc/nagios/.ssh
nagios@linux:~$ cd /etc/nagios/.ssh
nagios@linux:/etc/nagios/.ssh$ ssh-keygen -b 1024 -f id_dsa -t dsa -N"
Generating public/private dsa key pair.
Your identification has been saved in id_dsa.
Your public key has been saved in id_dsa.pub.
The key fingerprint is:
02:0b:5a:16:9c:b4:fe:54:24:9c:fd:c3:12:8f:69:5c nagios@nagserv
这里密钥的长度是 1024 位,使用 DSA 加密密钥。**`-N' '`** 确保私钥在 **`id_dsa`** 中不接收单独的密码保护:此选项强制使用空密码。
## 9.2.2 在目标主机上设置用户 **`nagios`**
与 Nagios 服务器上的配置类似,被监控计算机上的组和用户 **`nagios`** 也被设置:
target_computer:~ # groupadd -g 9000 nagios
target_computer:~ # *useradd -u 9000 -g nagios -d /home/nagios -m *
-c "Nagios Admin" nagios
target_computer:~ # mkdir /home/nagios/.ssh
目标计算机被分配了目录 **`/home/nagios`** 作为主目录,其中创建了一个子目录 **`.ssh`**。在这里,管理员(或另一个用户^([95])) 将在 Nagios 服务器上生成的公钥保存在名为 **`authorized_keys`** 的文件中:
linux:~ # scp /etc/nagios/.ssh/id_dsa.pub
target_computer:/home/nagios/.ssh/authorized_keys
现在用户 **`nagios`** 在目标服务器上不需要自己的密码。您只需确保在目标服务器上,**`.ssh`** 目录以及 **`authorized_keys`** 文件属于用户 **`nagios`**:
target_computer:~ # chown -R nagios.nagios /home/nagios/.ssh
target_computer:~ # chmod 700 /home/nagios/.ssh
## 9.2.3 检查 SSH 连接和 **`check_by_ssh`**
使用此配置,您首先应该检查安全壳连接是否正常工作。测试是以用户 **`nagios`** 的身份进行的,因为 Nagios 在检查过程中会使用它:
nagios@linux:~$ ssh -i /etc/nagios/.ssh/id_dsa target_computer w
18:02:09 up 128 days, 10:03, 8 users, load average: 0.01, 0.02, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
wob pts/1 linux01:S.1 08Sep04 1:27 4.27s 0.03s -bin/tcsh
...
**`-i`** 选项明确指定了私钥文件的路径。如果要在目标计算机上运行的命令 **`w`** 没有提供任何输出,或者相反的 SSH 守护进程请求密码,那么通过公钥的登录将不起作用。在这种情况下,您必须首先找到并消除错误,然后才能继续测试 **`check_by_ssh`**。
在此下一步中,您在目标计算机上运行本地插件,使用 **`check_by_ssh`**,稍后它将自动从 Nagios 服务器的命令行运行。确保每种情况下插件路径都是正确的。服务器上用户 **`nagios`** 的私钥文件路径使用 **`-i`** 指定:
nagios@linux:~$ /usr/local/nagios/libexec/check_by_ssh
-H target_computer -i /etc/nagios/.ssh/id_dsa
-C "/usr/local/nagios/libexec/check_disk -w 10% -c 5% -e -m"
DISK CRITICAL [2588840 kB (5%) free on /net/linux04/b] [937152 kB (5%)
free on /net/linux04/c]
在示例中,**`check_by_ssh`** 应该在目标计算机上以选项 **`-w 10% -c 5% -e -m`** 启动 **`/usr/local/nagios/libexec/check_disk`** 插件。如果这不起作用,那么它首先在目标主机上以相同的参数本地运行。通过这样做,您可以排除问题出在插件命令本身,而不是在安全壳连接上。
* * *
^([95]) ... 但不是用户 **`nagios`**,因为当创建账户时,**`useradd`** 首先在这里设置了一个无效密码,我们没有将其更改为有效密码。这意味着您目前无法以 **`nagios`** 身份登录到目标计算机。
# 9.3 Nagios 配置
匹配的命令对象再次在文件 **`checkcommands.cfg`** 中定义;类似于 **`check_local_disk`**,它应该命名为 **`check_ssh_disk`**:
check_ssh_disk command definition
define command{
command_name check_ssh_disk
command_line \(USER1\)/check_by_ssh -H \(HOSTADDRESS\)
-i /etc/nagios/.ssh/id_dsa
-C "\(USER1\)/check_disk -w \(ARG1\) -c \(ARG2\) -p \(ARG3\)"
}
存储在 **`command_line`** 中的命令行首先运行 **`check_by_ssh; $USER1$`**,其中包含 Nagios 服务器上的本地插件路径。接下来是参数——目标主机的 IP 地址(参数 **`-H`**)、私钥文件(参数 **`-i`**)以及最后,使用 **`-C`** 参数,目标主机应执行的全部命令。如果目标主机和 Nagios 服务器上的插件路径相同,那么您也可以在其中使用 **`$USER1$`** 宏;否则,目标计算机上的插件路径将明确给出。
设置命令与 7.1 硬盘剩余空间中的**`check_local_disk`**(第 158 页)中的命令没有不同。这意味着除了警告和临界限制之外,我们明确指定了一个文件系统或硬盘分区,使用**`-p`**参数。
以这种方式定义的命令**`check_ssh_disk`**如下应用,这里在一个名为**`linux02`**的计算机上:
define service{
host_name linux02
service_description FS_root
...
check_command check_ssh_disk!10%!5%!/
...
}
以这种方式定义的服务对象确保 Nagios 检查其**`/`**文件系统。警告限制在 10%,临界限制在 5%。
如果你使用**`check_by_ssh`**插件与**`check_ssh_disk`**一起,如本例所示,你必须确保所有目标主机上的插件路径相同。出于简单起见,这也值得做,尽管在实践中并不总是可能。以下服务定义因此将插件路径作为附加参数提供给目标计算机:
define service{
host_name linux02
service_description FS_root
...
check_command check_ssh_disk!/usr/lib/nagios/plugins!10%!5%!/
...
}
为了使这成为可能,你必须更改命令定义中的命令行,通过**`-C`**传递,如下所示:
-C "\(ARG1\)/check_disk -w \(ARG2\) -c \(ARG3\) -p \(ARG4\)"
注意:这会导致**`$ARGx`**宏的每个**`-w`**、**`-c`**和**`-p`**的数字都向右移动一位。
# 第十章. Nagios 远程插件执行器(NRPE)
如其名所示,*Nagios 远程插件执行器*(或简称 NRPE)在远程主机上执行程序。这些通常是本地测试相应计算机的插件,因此必须安装在其上。NRPE 的使用不仅限于本地插件;任何插件都可以执行,包括那些旨在测试网络服务的插件——例如,间接测试无法从 Nagios 服务器访问的计算机(如第 224 页的 10.6 间接检查所示)。
当使用安全外壳时,远程计算机上必须有一个真正的用户账户(见第九章),这也可以用来做除了启动插件之外的其他事情,但 NRPE 仅限于显式配置的测试。如果你愿意或被迫在目标主机上不使用登录外壳,那么使用 NRPE 会更好,尽管与安全外壳相比,这需要更多的配置工作。除了 Nagios 配置和在 Nagios 服务器上安装**`check_nrpe`**插件之外,以下任务仍然在目标系统上:
+ 必须安装程序**`nrpe`**。
+ 那里的 inet 守护进程(**`inetd`**或**`xinetd`**)必须以管理员权限配置。
+ 所有通过 NRPE 调用的插件都必须安装。
# 10.1 安装
NRPE 和插件可以从源代码安装,或者您也可以使用发行商提供的软件包。您应该使用至少 2.0 版本的 NRPE,因为这与它的前辈不兼容。从 2.6 版本开始,NRPE 具有开关 **`-u`**。如果目标系统上的 NRPE 服务不可达,Nagios 服务器上的插件 **`check_nrpe`** 会为此开关返回一个 UNKNOWN。从 2.8 版本开始,NRPE 支持与 Nagios 3.0 一起引入的多行插件输出(参见第 193 页的 8.5.1 多行插件输出)。在本书付印时,当前版本为 2.12,日期为 2008 年 3 月 26 日。
所有已建立的发行版至少包含从 1.4 版本开始的插件集合。您是否需要最新版本取决于您对相应插件的期望。
## 10.1.1 特定发行版的软件包
SuSE Linux 10.3 包含以下软件包:**`nagios-nrpe-2.10-4.1.i586.rpm, nagios-plugins-1.4.10-12.1.i586.rpm`**,以及 **`nagios-plugins-extras −1.4.10-12.1.i586.rpm.nagios-nrpe`** 包含了守护进程和插件 **`check_nrpe`**,该插件安装了几个额外的插件,例如数据库检查、FPing 测试或 Radius 测试,这些可以根据您的具体监控需求省略。
为了简化,设计软件包通过 YAST2^([96]) 或 **`rpm -ihv`** **``*`package`*``** 安装。第二种方法也适用于 Fedora 用户。
对于 Fedora Core 和 Red Hat Enterprise Linux,Dag Wieers 已经提供了几个版本的相应 Nagios 软件包.^([97])
Debian/Sarge 将 NRPE 守护进程和 NRPE 插件 **`check_nrpe`** 分装在两个不同的软件包中,分别称为 **`nagios-nrpe-server`** 和 **`nagios-nrpe-plugin`**,可以通过 **`apt-get install`** **``*`package`*``** 独立安装。如果您不想安装本地文档,可以省略软件包 **`nagios-nrpe-doc`**,只需将插件软件包 **`nagios-plugins`** 添加到目标主机即可。
程序 **`nrpe`**、配置文件 **`nrpe.cfg`** 和插件目录的路径列在 表 10-1 中。
表 10-1. NRPE 和插件的安装路径
| 发行版 | NRPE 程序 | 配置文件 | 插件 |
| --- | --- | --- | --- |
| ^([a]) |
| ^([b]) |
| 自编译^([a]) | **`/usr/local/sbin/nrpe`** | **`/etc/nagios/nrpe.cfg`** | **`/usr/local/nagios/libexec`** |
| SuSE | **`/usr/bin/nrpe`** | **`/etc/nagios/nrpe.cfg`** | **`/usr/lib/nagios/plugins`** |
| Debian | **`/usr/sbin/nrpe`** | **`/etc/nagios/nrpe.cfg`** | **`/usr/lib/nagios/plugins`** |
| Fedora^([b]) | **`/usr/sbin/nrpe`** | **`/etc/nagios/nrpe.cfg`** | **`/usr/lib/nagios/plugins`** |
|
^([a]) 推荐。
^([b]) 来自 Dag Wieers 提供的包。
|
## 10.1.2 从源代码安装
插件按照 1.4 安装和测试插件中从第 43 页描述的 Nagios 服务器上的方式安装在要监控的计算机上。
NRPE 源代码可以从 Nagios 主页获取.^([98]) 目录**`/usr/local/src`**^([99]) 是卸载源代码的理想选择。
linux:~ # mkdir /usr/local/src
linux:~ # cd /usr/local/src
linux:local/src # tar xvzf /path/to/nrpe-2.11.tar.gz
在已创建的新目录中,您运行**`configure`**命令:
linux:local/src # cd nrpe-2.11
linux:src/rnpe-2.11 # ./configure --sysconfdir=/etc/nagios --enable-ssl
推荐的路径规范列在表 10-1 中。与默认设置唯一不同的是 NRPE 配置文件存储的目录(**`configure`**选项**`--sysconfdir`**)。
因此,我们可以在**`configure`**命令中省略**`--with-nrpe-user`**和**`--with-nrpe-group`**的条目。这两个选项仅在**`nrpe`**程序作为守护进程运行时相关,并且可以在配置文件中覆盖。如果使用 inet 守护进程,您应该在 inet 守护进程的配置文件中指定**`nrpe`**应该以何种权限启动的用户。
**`--enable-ssl`** 确保 NRPE 通过 SSL 加密通道进行通信。当然,这只有在目标主机上的**`nrpe`**和 Nagios 服务器上的**`check_nrpe`**都相应编译的情况下才能工作。
命令**`make all`**编译程序**`nrpe`**和**`check_nrpe`**,但它**不会**将它们从**`/usr/local/src/nrpe-2.11/src`**复制到相应的系统目录中。由于没有**`make install`**,您必须自己完成此操作,具体细节请参考表 10-1:您需要在要监控的计算机上安装**`nrpe`**,并在 Nagios 服务器上安装**`check_nrpe`**插件。
如果 Nagios 服务器和目标主机使用相同的平台,您可以在一台计算机(例如服务器)上编译这两个程序,然后将**`nrpe`**及其配置文件复制到要监控的计算机上,而不是在 Nagios 服务器上单独编译**`check_nrpe`**,在目标系统上单独编译**`nrpe`**。
* * *
^([96]) 在命令行上,使用**`yast -i`** **``*`package`*``**。
^([97]) [`dag.wieers.com/`](http://dag.wieers.com/)
^([98]) [`www.nagios.org/download/`](http://www.nagios.org/download/)
^([99]) 可能需要首先创建子目录**`src`**。
# 10.2 通过 inet 守护进程启动
最好通过 inet 守护进程在要监控的机器上启动程序 **`nrpe`**,而不是作为单独的守护进程,因为 Nagios 服务器只是偶尔执行测试,而 **`nrpe`** 不需要加载任何大型资源。
如果你有选择,你应该使用更现代的 **`xinetd`**。但为了将工作减少到最低限度,通常将使用 inet 守护进程,因为它已经在目标系统上运行。为了使 NRPE 可以通过 **`inetd`** 或 **`xinetd`** 作为服务启动,**`nrpe`** 服务在文件 **`/etc/services`** 中定义:
nrpe 5666/tcp # Nagios Remote Plugin Executor NRPE
即使这是作为软件包安装的,你也应该检查此条目是否存在。默认情况下,NRPE 使用 TCP 端口 5666。
## 10.2.1 **`xinetd`** 配置
如果使用 **`xinetd`**,则每个要启动的服务都会在目录 **`/etc/xinetd.d`** 中存储一个单独的文件。对于 **`nrpe`**,最好创建一个名为 **`nrpe`** 或 **`nagios-nrpe`** 的文件:
/etc/xinetd.d/nrpe
description: NRPE
default: on
service nrpe
{
flags = REUSE
socket_type = stream
wait = no
user = nobody
group = nogroup
server = /usr/local/sbin/nrpe
server_args = -c /etc/nagios/nrpe.cfg --inetd
log_on_failure += USERID
disable = no
only_from = 127.0.0.1 ip_of_the_nagios_server
}
以斜体打印的值会传递到你的环境中;对于 **`only_from`**,例如,你应该输入你的 Nagios 服务器的 IP 地址,而不是占位符 **``*`ip_of_the_nagios_server`*``**。NRPE 从外部访问将仅限于这台计算机和 **`local-host`** (**`127.0.0.1`**)。后者地址允许本地测试;多个 IP 地址由空格分隔。然而,此限制性配置仅在 **`xinetd`** 编译了 TCP 包装器支持的情况下才有效。
在任何情况下都不应该使用具有特权的用户权限运行 NRPE——因此 **`nobody`** 是一个合理的值。**`server`** 参数指定了程序 **`nrpe;`** 的完整路径,对于 **`server_args`**,你应该输入配置文件的匹配路径。在此修改后,重新加载 **`xinetd`** 的配置,使用
linux:~ # /etc/init.d/xinetd reload
## 10.2.2 **`inetd`** 配置
在标准的 **`inetd`** 中,以下行被添加到配置文件 **`/etc/inetd.conf`** 中:
nrpe stream tcp nowait nobody /usr/sbin/tcpd /usr/local/sbin/nrpe -c/
etc/nagios/nrpe.cfg --inetd
这一行被拆分是为了空间原因,但在配置文件中,所有这些必须在单行中。这里使用 TCP 包装器 **`tcpd`**。如果不打算使用它,只需省略此条目^([100])。在这里,你还应该明确输入用户 **`nobody`**、二进制文件的完整路径 **`nrpe`** 和配置文件,以及其完整路径。上述斜体打印的字符串应根据你的系统进行必要的调整。配置更改后,重新加载 **`inetd`**:
linux:~ # /etc/init.d/inetd reload
## 10.2.3 Inet 守护进程是否正在监视 NRPE 端口?
一个简单的测试可以显示 inet 守护进程是否想要在端口 5666 上响应查询:
linux:~ # netstat -lnt | grep ':5666'
...
tcp 0 0 0.0.0.0:5666 0.0.0.0:* LISTEN
...
程序 **`netstat`** 使用选项 **`−1`** 显示服务等待接收查询的所有端口,即处于 **`LISTEN`** 状态的服务。选项 **`-n`** 抑制主机和端口的名称解析,并加快信息显示速度,而 **`-t`** 限制输出为 TCP 端口。
测试仅显示 inet 守护进程是否正确配置并已重新启动,例如,是否在 **`/etc/services`** 中正确地输入了 **`nrpe`** 服务。它不明确指出 NRPE 守护进程及其配置文件的路径是否正确。这种错误仅在具体尝试访问 NRPE 端口 5666 时由 inet 守护进程宣布。只有在 NRPE 守护进程配置完成后,才会进行后续的完整功能测试。这在本节的 10.4 NRPE 功能测试 页 221 中描述。
* * *
^([100]) **`inetd`** 没有内置方法仅允许来自特定 IP 地址的服务访问。此功能是在 TCP 包装器 **`tcpd`** 中添加的。然后,访问配置由文件 **`/etc/hosts.allow`** 和 **`/etc/hosts.deny`** 担任。关于此的更多信息,请参阅 **`man host_access`**。
# 10.3 监控计算机上的 NRPE 配置
在编译 NRPE 时,源目录中会创建 **`nrpe.cfg`** 文件,其中包含几个参数以及运行 NRPE 的命令。这些命令需要手动复制到配置目录,通常首先需要在目标计算机上创建该目录:
linux:src/rnpe-2.11 # mkdir /etc/nagios
linux:src/rnpe-2.11 # cp nrpe.cfg /etc/nagios/.
特定于发行版的软件包从第 215 页 表 10-1 中指定的位置解包。
**`nrpe`** 在运行时被赋予 inet 守护进程配置中指定的用户权限,在我们的例子中是 **`nobody`**。因此,**`nrpe.cfg`** 需要对该用户可读。只要文件不包含任何密码(这些实际上不应该使用)或其他关键信息,则可以允许所有用户读取权限。
配置文件包含许多注释;以下命令显示活动参数:^([101])
user@linux:~$ egrep -v '#|$' nrpe.cfg | less
server_port=5666
allowed_hosts=127.0.0.1
nrpe_user=nobody
nrpe_group=nogroup
dont_blame_nrpe=0
debug=0
command_timeout=60
...
参数 **`server_port`**、**`allowed_hosts`**、**`nrpe_user`** 和 **`nrpe_group`** 仅在 **`nrpe`** 作为守护进程运行时相关。当使用 inet 守护进程时,程序会忽略这些值,因为它们已经被 **`(x) indetd`** 配置确定。
条目**`dont_blame_nrpe=0`**阻止**`nrpe`**接受参数,从而关闭了一个潜在的安全漏洞。**`debug=l`**允许详细的日志记录,这在查找错误时很有用(**`debug=0`**关闭调试信息的输出),而**`command_timeout`**指定了秒数,在此之后**`nrpe`**会突然中断挂起的插件。配置文件中的注释解释了所有这些参数。
在此之后,定义了将被 NRPE 执行的命令。配置文件**`nrpe.cfg`**已经包含了一些,但首先它们都必须被注释掉,并且只有那些真正打算使用的命令被激活。
关键字**`command`**后面跟着方括号中的名称,这是**`check_nrpe`**应该调用的命令的名称。在等号(=)之后,指定相应的插件命令,包括其完整路径:^([102])
command[check_users]=/usr/local/nagios/libexec/check_users -w 5 -c 10
command[check_load]=/usr/lib/nagios/libexec/check_load -w 8,5,3 -c 15,10,7
command[check_zombies]=/usr/lib/nagios/libexec/check_procs -w :1 -c :2 -s Z
在路径方面,必须注意这确实指向了本地插件目录。在这里指定的目录中,**`/usr/local/nagios/libexec`**,自编译的插件位于^([103]);而对于来自发行版包的安装,路径通常是**`/usr/lib/nagios/plugins`**。
从 Nagios 服务器,现在通过**`check_nrpe`**在**目标计算机**上运行刚刚定义的命令**`check_users`**:
nagios@linux:nagios/libexec$ ./check_nrpe -H target_host -c check_users
## 10.3.1 将参数传递给本地插件
到目前为止描述的方法有一个缺点:对于目标系统上的每个测试,都需要一个单独定义的命令。以下是一个需要监控九个文件系统的服务器的示例,其中插件**`check_disk`**(参见第 158 页的 7.1 硬盘剩余空间)是必需的:
command[check_disk_a]=path/to/check_disk -w 5% -c 2% -p /net/linux01/a
command[check_disk_b]=path/to/check_disk -w 4% -c 2% -p /net/linux01/b
command[check_disk_c]=path/to/check_disk -w 5% -c 2% -p /net/linux01/c
command[check_disk_d]=path/to/check_disk -w 5% -c 2% -p /net/linux01/d
command[check_disk_root]=path/to/check_disk -w 10% -c 5% -p /
command[check_disk_usr]=path/to/check_disk -w 10% -c 5% -p /usr
command[check_disk_var]=path/to/check_disk -w 10% -c 5% -p /var
command[check_disk_home]=path/to/check_disk -w 10% -c 5% -p /home
command[check_disk_tmp]=path/to/check_disk -w 10% -c 5% -p /tmp
为了避免所有这些工作,NRPE 也可以配置为将参数传递给**`check_nrpe`**:
dont_blame_nrpe=1
...
command[check_disk]=path/to/check_disk -w \(ARG1\) -c \(ARG2\) -p \(ARG3\)
为了使这生效,必须使用带有选项的 NRPE **`configure`** 脚本运行:
**`--enable-command-args`**。这种不便的程序的原因是传递参数是一个基本的风险,因为不能排除某些参数选择可能导致(尚未知)的缓冲区溢出,从而允许目标系统被渗透。
尽管存在所有安全风险,如果你仍然决定这样做,应该使用 TCP 包装器(参见 10.2.2 inetd 配置,第 217 页),以确保只有 Nagios 服务器本身被允许向 NRPE 发送命令。
如果插件提供了相应的选项,有时还有第三种方法:上述问题也可以通过获取**`check_disk`**来解决,如果需要,可以使用一个单独的命令测试所有文件系统:
user@linux:nagios/libexec$ ./check_disk -w 10% -c 4% -e -m
DISK WARNING [2588840 kB (5%) free on /net/linux1/b] [937160 kB (5%) free on
/net/linux1/c]
**`-e`**参数说服插件只显示那些产生警告或错误的文件系统。一个限制仍然存在:警告和临界限制对于所有文件系统来说,必然是相同的。
* * *
^([101]) 正则表达式**`^#|^$`**匹配所有以注释符号**`#`**开头或由空行组成的行。选项**`-v`**确保**`egrep`**显示所有不匹配这些行的行。
^([102]) **`check_users`**命令在 7.6 监控登录用户数量的第 177 页进行了解释,**`check_load`**在 7.3 测试系统负载的第 162 页进行了解释,而 7.4 监控进程的第 163 页涉及**`check_procs`**。
^([103]) ...前提是你已经遵循了书中的说明。
# 10.4 NRPE 功能测试
为了进行一个总结性的功能测试,Nagios 服务器上的插件**`check_nrpe`**被调用。命令**`-H`** **``*`目标`*``** **`主机`**返回刚刚安装 NRPE 服务的服务器上指定的 IP 地址:
nagios@linux:nagios/libexec$ ./check_nrpe -H swobspace
CHECK_NRPE: Error - Could not complete SSL handshake.
这里给出的错误信息非常频繁地发生,并且几乎同样频繁地引起混淆,因为尽管 SSL 握手可能会出现问题,但在大多数情况下,原因在其他地方。只有当插件**`check_nrpe`**和所指向的**`NRPE 守护进程`**使用的 SSL 版本不兼容,或者两个软件包中有一个没有使用 SSL 编译,而另一个使用了 SSL 时,你才有一个 SSL 问题。
否则,原因将在于其他地方:问题可能是由于配置文件中的错误引起的,或者 inet 守护进程无法找到 NRPE 程序或配置文件,或者文件**`nrpe.cfg`**的访问权限不足。如果 Nagios 服务器无法通过 inetd 配置访问 NRPE 服务,你也会收到提到的错误信息。在这种情况下,你需要检查**`xinetd`**的**`only_from`**参数或通过**`tcpd`**为**`inetd`**设置的相同限制。
你可以在 syslog 文件中查找错误的精确原因,特别是文件**`messages`**,根据发行版的不同,也可能在**`warn.log`**、**`daemon.log`**或另一个日志文件中:
linux:~ # grep nrpe /var/log/messages
...
nrpe[19844]: Unable to open config file '/etc/nagios/nrpe.cfg' for reading
nrpe[19844]: Config file '/etc/nagios/nrpe.cfg' contained errors, aborting...
...
在这个例子中,文件**`nrpe.cfg`**要么不在搜索的路径中,要么**`nrpe`**无法打开它。由于**`nrpe`**以**`nobody`**用户的权限运行,它也必须能够读取配置文件。
然后一个成功的**`check_nrpe`**调用将提供已安装 NRPE 服务的版本:
nagios@linux:nagios/libexec$ ./check_nrpe -H swobspace
NRPE v2.11
# 10.5 Nagios 配置
通过 **`check_nrpe`** 在远程计算机上“触发”本地插件的命令,在 Nagios 服务器上的 **`checkcommands.cfg`** 文件中定义为之前所述。
## 10.5.1 不传递参数的 NRPE
如果没有将参数传递给目标插件,情况将如下所示:
define command{
command_name check_nrpe
command_line \(USER1\)/check_nrpe -H \(HOSTADDRESS\) -c \(ARG1\)
}
作为唯一的参数,Nagios 在这里传递给 NRPE 执行的命令。如果 Nagios 服务器上的 **`check_nrpe`** 插件位于与其他插件不同的目录中,你必须输入正确的路径而不是 **`$USER1$`**。
要通过 NRPE 测试的服务使用刚刚定义的命令 **`check_nrpe`** 作为 **`check_command`**。作为参数,指定了在目标系统(此处:**`linux04`**)上的 **`nrpe.cfg`** 中定义的命令:
define service{
host_name linux04
service_description FS_var
...
check_command check_nrpe!check_disk_var
...
}
## 10.5.2 NRPE 中的参数传递
为了解决第 220 页 10.3.1 将参数传递给本地插件 中定义的命令
command[check_disk]=path/to/check_disk -w \(ARG1\) -c \(ARG2\) -p \(ARG3\)
从 Nagios 服务器,通过选项 **`-a`** 将相应的参数传递给 **`check_nrpe`**:
define command{
command_name check_nrpe
command_line \(USER1\)/check_nrpe -H \(HOSTADDRESS\) -c \(ARG1\) -a \(ARG2\)
}
以便 **`$ARG2$`** 可以正确地传输远程插件的参数,这些参数在服务定义中以空格分隔。此外,你应该确保顺序正确:
define service{
host_name linux04
service_description FS_var
...
check_command check_nrpe!check_disk!10% 5% /var
...
}
本地安装在 **`linux04`** 上的 **`check_disk`** 将三个字符串 **`10%,5%`** 和 /var 分配给其自己的三个宏 **`$ARG1$`**、**`$ARG2$`** 和 **`$ARG3$**,用于 **`nrpe.cfg`** 中定义的命令。
## 10.5.3 优化配置
如果在所有目标系统上给 NRPE 命令相同的名称,则可以将具有相同名称的所有 NRPE 命令包含在单个服务定义中。在这种情况下,你可以利用指定多个主机或甚至整个主机组的可能性:
define service{
host_name linux04,linux02,linux11
service_description FS_var
...
check_command check_nrpe!check_disk_var
...
}
使用在 10.3.1 将参数传递给本地插件 的第 220 页开头定义的命令 **`check_disk_var`**,Nagios 现在检查计算机 **`linux04`**、**`linux02`** 和 **`linux11`** 上的 **`/var`** 文件系统。如果要将其他文件系统包含在测试中,则为每个文件系统创建单独的服务,从而避免传递参数时涉及的安全问题。如果你使用测试所有文件系统的同时的选项,使用 **`check_disk`** 插件(见 7.1 硬盘剩余空间),那么最终,一个单一的服务定义就足够监控所有 Linux 服务器上的所有文件系统——前提是你有目标系统上的相应 NRPE 配置:
define service{
hostgroup_name linux-servers
service_description Disks
...
check_command check_nrpe!check_disk
...
}
# 10.6 间接检查
NRPE 不仅执行本地插件,还执行任何可用的插件。如果你通过 NRPE 使用网络插件,这些插件被称为*间接检查*,如图图 10-1 所示。

图 10-1. 使用 NRPE 进行间接检查
如果每个网络服务都直接通过防火墙进行测试,那么就必须打开所有所需的端口。在示例中,这些端口将是 SMTP、HTTP、LDAP、PostgreSQL 和 SSH 的端口。另一方面,如果检查是从防火墙后面的计算机间接进行的,那么只需要在防火墙上打开 NRPE(TCP 端口 5666)的端口就足够了。只要通过 NRPE 进行配置,防火墙后面的 NRPE 服务器就可以执行它想要的任何测试。
间接检查所涉及的努力是否大于直接检查的努力取决于具体的实现:如果这意味着你必须在防火墙上“打洞”,那么在 NRPE 服务器上的额外工作可能是值得的。但如果涉及的端口已经打开,那么通常可以直接进行测试;这会使在 NRPE 主机上进行额外配置工作变得不必要。
# 第十一章. 使用 SNMP 收集与监控相关的信息
SNMP 代表*简单网络管理协议*,这是一个定义在所有之上的协议,用于监控和管理网络设备。这意味着不仅能够读取网络设备,还能够写入网络设备,因此你可以打开或关闭交换机上的特定端口,或以其他方式干预。
几乎所有可以通过 TCP/IP 进行寻址的网络设备都可以处理 SNMP,而不仅仅是交换机和路由器。对于 Unix 系统,有 SNMP 守护进程;即使是 Windows 服务器在其标准发行版中也包含 SNMP 实现,尽管这必须明确安装。但即使是不间断电源(UPS)或网络传感器也具有 SNMP 功能。
如果你使用 Nagios,那么在某个时候你不可避免地会接触到 SNMP,因为尽管你通常有很多查询 Unix 和 Windows 系统的技术选择,但当涉及到没有自己复杂操作系统的硬件特定组件,如交换机时,SNMP 通常是获取网络设备信息的唯一方式。SNMP 并不以易于理解而闻名,这与其他因素有关,例如它旨在程序之间的通信,机器处理是主要的。此外,你通常不会直接与协议和原始信息接触,因为即使是调制解调器或路由器也提供了一个简单易用的界面,掩盖了底层 SNMP 的复杂性。
如果你想在 Nagios 中使用 SNMP,你不可避免地要涉及到协议的信息结构。11.1 SNMP 简介因此提供了对 SNMP 的简要介绍。11.2 NET-SNMP 从第 234 页介绍了 NET-SNMP,这可能是 Unix 系统上最广泛使用的 SNMP 实现。一方面,它展示了如何使用命令行工具获取网络设备信息结构的概览,另一方面,它描述了 Linux 中 SNMP 守护进程的配置。最后,11.3 Nagios 自带的 SNMP 插件从第 246 页专门讨论了 SNMP 与 Nagios 的具体使用。
# 11.1 SNMP 简介
虽然 SNMP 的名字中包含了“协议”的 P,但这不仅仅代表一个协议,而是作为*互联网标准管理框架*的同义词使用。这包括以下组件:
+ 可管理的网络节点,可以通过 SNMP 远程控制。一个特定的 SNMP 引擎实现,无论是软件还是硬件,被称为*代理*。
+ 至少一个由可以管理代理的应用程序组成的 SNMP 单元。这个单元被称为*管理者*。
+ 一个代理和管理者可以交换信息的协议:*简单网络管理协议*(SNMP)。
+ 一个明确的信息结构,以便任何管理者和代理都能相互理解:所谓的*管理信息库*,简称 MIB。
框架将管理者的角色定义为主动。代理本身只是被动地等待接收命令。此外,所谓的*陷阱*扩展了 SNMP 的应用可能性:这些是代理主动发送给单个管理者或一组管理者的消息,例如当预定义的极限值被超过或当网络设备的函数失败时。
作为代理,制造商实现的 SNMP 引擎用于特定硬件设备(交换机、路由器)。对于 Linux 和通用 Unix 系统,有 NET-SNMP 实现可用(见 11.2 NET-SNMP),对于 Windows 服务器,操作系统已经包含了等效的软件。
与 Nagios 结合使用时,有两种可能性。在 Nagios 扮演主动角色的方面,相应的 Nagios 插件,作为管理者,会向代理请求所需信息。反过来,Nagios 也可以使用工具被动接收传入的 SNMP 陷阱并处理它们。14.6 应用示例 II:处理 SNMP 陷阱从第 312 页专门讨论了这一主题。
如果你想成功使用 Nagios 与 SNMP,理解 SNMP 信息结构,所谓的 *管理信息库* (MIB) 是至关重要的。因此,本节将专注于这一点。协议本身只是简要提及,以说明不同协议版本之间的差异。
如果你想要更深入地了解 SNMP,我们建议你查阅描述 SNMP 的众多 *请求评论* (RFCs)。最佳起点是 RFC 3410,“互联网标准管理框架的介绍和适用性声明”和 RFC 3411:“描述简单网络管理协议(SNMP)管理框架的架构”。除了介绍和许多交叉链接外,你还可以在那里找到对较旧版本原始文档的引用,今天被称为 SNMPv1 和 SNMPv2。
## 11.1.1 管理信息库
SNMP 信息结构由数字的分层命名空间构造组成。图 11-1 展示了这一结构的摘录。树结构类似于其他分层目录服务,如 DNS 或 LDAP。
它的根被称为 **`1 (iso)`**,代表 *国际标准化组织*。下一级,如图 图 11-1 所示的 **`3 (org)`**,为一般、国家和国际组织提供空间。在其下方是 **`6 (dod)`**,代表美国的 *国防部*。基于 IP 的一般(互联网)**`internet`** 被分配为 **`dod`** 的子项 **`1 (internet)`**,这归因于其作为军事项目的起源。
如果你从左到右将相应的数字组合起来并用点分隔,那么对于树中的 **`internet`** 节点,你将得到标识 **`1.3.6.1`**。这类节点通常被称为 *对象标识符* (OID)。它们的语法不仅用于 SNMP,也用于定义 LDAP 对象和属性,例如。
OID **`1.3.6.1`** 对于人类来说并不容易阅读,这就是为什么其他表示方法已经得到认可:**`iso.org.dod.internet`** 和组合 **`iso(1).org(3).dod(6).internet(1)`** 都是允许的。因为如果树足够深,这会迅速使可读描述变得无限长,因此另一种缩写表示方法已经建立:只要术语保持唯一,你只需简单地写 **`internet`** 而不是 **`1.3.6.1`**。
这里重要的是,管理器和代理之间的通信完全是数值性的。管理器是否也允许文本输入或能否以文本形式而不是以数值 OID 发布信息取决于每种情况下的实现。有关各个节点的信息由 SNMP 代理的制造商以文件形式提供,作为管理信息库(MIB)。

图 11-1. 使用 MIB-II 接口示例的 SNMP 命名空间
存储在 MIB 中的数据包括联系信息(谁设计了 MIB;通常设备制造商将被提供在这里),各个子节点和属性的定义,以及使用的数据类型。如果 MIB 文件还描述了各个子节点和属性,这将使管理器能够向用户提供有关所讨论条目意义和目的的附加信息。
在**`internet`**下面,下一级被划分为各种命名空间。对于 SNMP 来说,管理节点**`1.3.6.1.2`**特别重要,即**`iso(1) .org(3) .dod(6) .internet(1) .mgmt(2)`**。这里的命名空间由 RFC 1155,“基于 TCP/IP 互联网的管理信息的结构和标识”所描述。
为了使管理器和代理能够相互理解,管理器需要知道代理如何结构化其数据。这就是**管理信息库,版本 II**发挥作用的地方。SNMP 从代理那里请求有关其实施的信息;通过这种方式,每个管理器都可以访问代理的最重要参数,而无需之前的 MIB 定义交换。**管理信息库 II**,或简称为 MIB-II(或 mib-2),可以在**`1.3.6.1.2.1`**或**`iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1)`**命名空间中找到。由于它是明确定义且唯一的,因此位于其下的 OID 通常简短描述,以 MIB-II 或 mib-2 开头。
您也可以在自己的管理信息库中定义制造商特定的信息。相应的 MIB 位于**`internet.private.enterprise`**之下。一旦在 MIB 中描述了一个 OID,该条目的含义就永远不能更改。MIB 的描述格式由 RFC 1212 标准化,这也是为什么供应商为代理提供的特殊 MIB 几乎可以集成到任何管理器中。
### MIB-II
MIB-II,即所有 SNMP 代理都必须遵守的管理信息库,包含几个信息组。其中最重要的总结在表 11-1")中。表示法**`mib-2.`****``*`x`*``**代表**`1.3.6.1.2.1.`****``*`x`*``**。
表 11-1. MIB-II 组(部分选择)
| 组 | OID | 描述 |
| --- | --- | --- |
| system | mib-2.1 | 设备信息(例如,位置、联系人或运行时间) |
| 接口 | mib-2.2 | 网络接口信息(名称、接口类型、状态、统计信息等) |
| at | mib-2.3 | 将物理地址(例如,MAC 地址)分配给 IP 地址(地址转换表) |
| ip | mib-2.4 | 路由表和 IP 数据包统计信息 |
| icmp | mib-2.5 | 单个 ICMP 数据包类型的统计信息 |
| tcp | mib-2.6 | 打开的端口和现有的 TCP 连接 |
| udp | mib-2.7 | 对于 UDP 也是如此 |
| host | mib-2.25 | 存储介质、设备、运行进程及其资源使用的信息 |
如何具体处理存储在 MIB-II 中的信息可以通过*接口*组的例子来解释:图 11-1 展示了它们如何分为两个 OID **`interfaces.if Number`** 和 **`interfaces.if Table`**。这是因为一个网络节点最初会显示未知数量的接口。这个数量由**`ifNumber`**来表示。在更详细地查看这些接口之前,管理者可以从**`ifNumber`**获取有关实际接口数量的信息。
**`ifTable`** 包含了不同接口的实际信息。为了获取特定接口的信息,管理者查询所有最后一位数字相同的条目,如下所示:
ifEntry.ifIndex.1 = INTEGER: 1
ifEntry.ifDescr.1 = STRING: eth0
ifEntry.ifType.1 = INTEGER: ethernetCsmacd(6)
ifEntry.ifMtu.1 = INTEGER: 1500
ifEntry.ifSpeed.1 = Gauge32: 100000000
ifEntry.ifPhysAddress.1 = STRING: 0:30:5:6b:70:70
ifEntry.ifAdminStatus.1 = INTEGER: up(1)
ifEntry.ifOperStatus.1 = INTEGER: up(1)
**`ifIndex`** 描述了设备内部的索引——SNMP 总是从**`1`**开始计数,交换机从这里开始计数为**`100`**。**`ifDescr`** 包含接口的名称,这里为**`eth0`**——这显然是一台 Linux 机器。从接下来的四个条目可以推断出,这里涉及到的是一个普通的 100-Mbit 以太网接口。
接口类型**`ifType`**给出为**`ethernetCsmacd`**,即以太网。**`ifMtu`**指定了*最大传输单元*,在本地网络中,以太网总是 1,500 字节。接口速度**`ifSpeed`**为 100,000,000 位,即 100 Mbit。而**`ifPhysAddress`**包含物理网络地址,也称为 MAC 地址。
**`ifAdminStatus`** 揭示了管理员是否通过配置将接口打开(**`up`**)或关闭(**`down`**)。另一方面,**`ifOperStatus`** 指定了实际状态,因为即使由管理员激活的接口也不一定连接到设备,或者甚至打开。
第二个接口也有类似的图示:
ifEntry.ifIndex.2 = INTEGER: 2
ifEntry.ifDescr.2 = STRING: lo
ifEntry.ifType.2 = INTEGER: softwareLoopback(24)
ifEntry.ifMtu.2 = INTEGER: 16436
ifEntry.ifSpeed.2 = Gauge32: 10000000
ifEntry.ifPhysAddress.2 = STRING:
ifEntry.ifAdminStatus.2 = INTEGER: up(1)
ifEntry.ifOperStatus.2 = INTEGER: up(1)
...
然而,这里不是以太网卡,而是一个本地回环设备。
## 11.1.2 SNMP 协议版本
第一个 SNMP 版本和**互联网标准管理框架**最早在 1988 年的 RFC 1065–1067 中描述;关于这个版本(命名为 SNMPv1)的当前文档可以在 RFC 1155–1157 中找到。它今天仍在使用,因为更高版本在本质上与旧版本向后兼容。
SNMPv1 的主要缺点是这个版本只允许在精确的三阶段中进行令人不满意的认证:无访问权限、读取访问权限和读写操作的完全访问权限。两个简单的密码,所谓的**社区**,在这里提供了一点保护:它们将用户分为具有读取权限的一个社区,以及具有读取和写入权限的第二个社区。不可能进行进一步的区分。如果这还不够,社区是以明文形式传输的,这使得它很容易成为嗅探工具的目标。
第二个版本 SNMPv2 的进一步开发旨在解决有关值范围显示、错误事件以及大量请求时的性能问题(RFC 1905)。然而,这个 RFC 从未完全实现。在实践中使用的唯一相对完整的实现被称为**基于社区的 SNMPv2**,或简称为 SNMPv2c(RFC 1901-1908)。当前版本 SNMPv3(RFC 3411–3418)具有互联网标准的地位。具有 SNMPv3 实现的代理始终理解来自 SNMPv1 的请求。
除了扩展协议操作外,SNMPv1 和 SNMPv2c 之间没有根本性的区别。这也可能是 SNMPv2 无法真正站稳脚跟的原因。在这个版本中,期望的安全性的提高显然是缺失的。只有 SNMPv3 中框架的扩展允许更精确的访问控制,但这比 SNMPv1 中的两个社区字符串要复杂得多。RFC 3414 描述了基于用户的**安全模型**(USM),RFC 3415 描述了基于视图的**访问控制模型**(VACM)。
当访问 SNMP 代理时,你必须告诉所有工具,包括插件,要使用哪个协议版本。在 Nagios 中,你只需要读取访问。如果这仅限于所需的信息,并且你只允许来自 Nagios 服务器的访问,那么你无需担心没有 SNMPv3 的扩展认证。重要的是,如果你可能的话,配置代理以完全防止写访问,或者至少要求密码。你永远不应该使用这个:因为它以明文形式传输,总有人可能会监听,并可能在以后滥用密码。
在 NET-SNMP 中,可以完全防止写访问,访问可以限制到特定的主机,并且可以限制公开的信息。对于其他在硬件中实现的代理,例如交换机和路由器,你必须权衡是否真的需要 SNMPv3,假设制造商已经提供了这项功能。然而,SNMPv1 对于所有 SNMP 设备都是可用的。
因此,我们下面将仅解释通过 SNMPv1 的访问方式,并假设这通常是只读访问。如果您仍然想涉足 SNMPv3,我们建议您查阅 NET-SNMP 文档.^([105])
* * *
^([104]) *载波侦听* (CS) 指的是每个网络接口根据网络信号(例如与令牌环网相比,网络卡可能只有明确接收到令牌时才能使用线路)检查线路是否空闲;*多路访问* (MA) 指的是多个网络卡可以同时访问一个公共网络介质。
^([105]) [`net-snmp.sourceforge.net/docs/FAQ.html#How_do_I_use_SNMPv`](http://net-snmp.sourceforge.net/docs/FAQ.html#How_do_I_use_SNMPv)
# 11.2 NET-SNMP
可能是 Linux 和其他 UNIX 系统上最广泛使用的 SNMP 实现是 NET-SNMP ^([106]),最初由卡内基梅隆大学的 Wes Hardaker,加州大学戴维斯分校的系统管理员构想,他继续开发代码,并首次以 UCD-SNMP(版本 3.0)的名义发布。
在 5.0 版本中,该项目最终得到了 NET-SNMP 这个名字。但各种发行版仍然称这个包为 UCD-SNMP,部分原因是因为它包含了 4.2 版本,部分原因是因为维护者简单地还没有时间将其重命名。
NET-SNMP 由一组命令行工具、一个图形浏览器(**`tkmib`**)、一个代理(**`snmpd`**,见第 238 页的 11.2.2 NET-SNMP 守护进程)和一个库组成,现在它几乎成为开源领域几乎所有 SNMP 实现的基石。
所有常见的发行版都包括相应的包。在 SuSE 中,这被称为**`net-snmp`**,包含所有组件;Debian 将工具打包在**`snmp`**包中,并将守护进程打包在**`snmpd`**包中。在印刷时,5.4.1 是当前版本,但较老的 5.x 版本也能满足我们的需求。它们的输出在某种程度上有所不同,但具体选项可以在必要的 man 页面上查找。
## 11.2.1 SNMP 请求工具
对于读取访问,使用**`snmpget`**、**`snmpgetnext`**和**`snmpwalk`**程序。**`snmpget`**特别请求一个 OID 并从中返回一个值。**`snmpgetnext`**显示管理信息库中存在的下一个变量,包括其值:
user@linux:~$ snmpget -v1 -c public localhost ifDescr.1
IF-MIB::ifDescr.1 = STRING: eth0
user@linux:~$ snmpgetnext -v1 -c public localhost ifDescr.1
IF-MIB::ifDescr.2 = STRING: lo
user@linux:~$ snmpgetnext -v1 -c public localhost ifDescr.3
IF-MIB::ifType.1 = INTEGER: ethernetCsmacd(6)
选项**`-v1`**指示**`snmpget`**使用 SNMPv1 作为协议。使用**`-c`**指定读取社区;在这种情况下,密码是**`public`**。接下来是查询的计算机,这里为**`localhost`**,最后是我们要查找值的 OID。
NET-SNMP 工具是 OID 缩写的专家:没有特殊指令,它们总是假设涉及的 OID 位于 MIB-II 内部。对于如**`ifDescr.1`**这样的唯一条目,这已经足够了。但各种 Nagios SNMP 插件是否也能处理这种情况取决于具体的实现;最好逐个尝试。为了安全起见,最好使用完整的 OID,可以是数值形式,也可以是可读形式。后者是在你指示**`snmpget`**显示完整 OID 时获得的:
user@linux:~$ snmpget -v1 -On -c public localhost ifDescr.1
.1.3.6.1.2.1.2.2.1.2.1 = STRING: eth0
user@linux:~$ snmpget -v1 -Of -c public localhost ifDescr.1
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifDescr.1 = STRING: eth0
**`-On`**选项提供数值 OID,**`-Of`**提供文本版本。这样,你可以轻松地找到完整的 OID,对于无法处理缩写的插件来说。这里重要的是要记住:每个 OID 总是以一个点开始。如果你省略了它,总会有一个插件无法正常工作。
为了获取 MIB-II 中存储的所有信息,最好使用**`snmpwalk`**。正如其名称所暗示的,该程序会遍历整个管理信息库,要么是全部,要么是树的一部分。如果你想要了解节点**`mib-2.interfaces`**(图 11-1 在第 230 页)下的所有条目,你只需给**`snmpwalk`**提供所需的 OID:
user@linux:~$ snmpwalk -v1 -c public localhost mib-2.interfaces
IF-MIB::ifNumber.0 = INTEGER: 3
IF-MIB::ifIndex.1 = INTEGER: 1
IF-MIB::ifIndex.2 = INTEGER: 2
IF-MIB::ifIndex.3 = INTEGER: 3
IF-MIB::ifDescr.1 = STRING: eth0
IF-MIB::ifDescr.2 = STRING: lo
IF-MIB::ifDescr.3 = STRING: eth1
IF-MIB::ifType.1 = INTEGER: ethernetCsmacd(6)
...
**`snmpwalk`**略微隐藏了确切的结构(例如,缺少到**`ifTable`**和**`ifEntry`**的链接,例如,参见图 11-1),因此最好使用**`-Of:`**
user@linux:~$ snmpwalk -v1 -Of -c public localhost mib-2.interfaces
...mib-2.interfaces.ifNumber.0 = INTEGER: 3
...mib-2.interfaces.ifTable.ifEntry.ifIndex.1 = INTEGER: 1
...mib-2.interfaces.ifTable.ifEntry.ifIndex.2 = INTEGER: 2
...mib-2.interfaces.ifTable.ifEntry.ifIndex.3 = INTEGER: 3
...mib-2.interfaces.ifTable.ifEntry.ifDescr.1 = STRING: eth0
...mib-2.interfaces.ifTable.ifEntry.ifDescr.2 = STRING: lo
...mib-2.interfaces.ifTable.ifEntry.ifDescr.3 = STRING: eth1
...mib-2.interfaces.ifTable.ifEntry.ifType.1 = INTEGER: ethernetCsmacd(6)
这里简写用于打印的三个点...代表**`.iso.org.dod.internet.mgmt`**。
作为下一步,你可以查看自己的网络并查询那里可用的管理信息库。通常,使用读取社区**`public`**可以走得很远,因为这是常见的默认设置。因此,你也应该尝试社区字符串**`private`**,这是许多厂商默认设置的。顺便说一句,这是一种极其可疑的做法:任何对 SNMP 有点了解并且有权访问网络的人都可以使用它来操纵设备设置,例如关闭某些端口或整个交换机。但即使对于所有其他默认密码,你也应该麻烦去更改它们。整个密码列表可以在互联网上找到,按厂商和设备分类——通过 Google 很容易找到。
无论你是否也更改了预设的读取社区(例如**`public`**),这取决于该社区上的信息以及你自己的安全需求。但读写社区在任何情况下都不应保留默认设置。此外,对于既不通过 SNMP 查询也不通过 SNMP 管理的设备,建议您完全关闭 SNMP,以确保安全。
### 使用**`mbrowse`**进行图形遍历
图形界面通常推荐用于交互式研究和管理信息库的初始探索,例如 SNMP 浏览器**`mbrowse`**^([107])(见图 11-2)。这不是 NET-SNMP 的组件,但大多数 Linux 发行版都提供了**`mbrowse`**包以供安装。

图 11-2. SNMP 浏览器 `mbrowse`
如果你突出显示一个条目并点击**`Walk`**按钮,下方的窗口将显示与**`snmpwalk`**相同的输出。然而,图形显示允许更好的定位——更容易看到你目前位于哪个部分树中。而且,**`mbrowse`**还会在**`Object Identifier`**中显示每个选定对象的数值 OID。
## 11.2.2 NET-SNMP 守护进程
NET-SNMP 守护进程**`snmpd`**作为 Linux 和其他 Unix 系统的 SNMP 代理工作;也就是说,它响应管理器的请求,同时也提供了一种通过写入访问来设置 Linux 系统的方式,例如操作路由表。
### 支持的管理信息库
代理最初提供关于 RFC 1213 中描述的 MIB-II 的信息(11.1.1 管理信息库,以及属于此的 RFC 2790(主机 MIB)的扩展。表 11-2")总结了主机 MIB 的组,并在表 11-1(第 231 页)中介绍了最重要的 MIB-II 组。
如果你感兴趣 MIB-II 的详细描述,包括主机 MIB,我们推荐你访问[`www.snmplink.org/`](http://www.snmplink.org/)。在那里你可以浏览大量的 MIB,如果你愿意,还可以下载它们。
除了基本的 MIB-II 之外,NET-SNMP 实现在其**`private.enterprises.ucdavis`**(UCD-SNMP-MIB)处有自己的扩展。在表 11-3 中给出的指令指的是配置文件**`snmpd.conf`**(见支持的管理信息库)中的指令。这里的一些信息也包含在主机资源 MIB 中。
表 11-2. 主机资源 MIB `MIB mib-2.host`(RFC 2790)
| 组 | OID | 描述 |
| --- | --- | --- |
| hrSystem | host.1 | 主机系统时间和运行时间,登录用户和活动进程数量 |
| hrStorage | host.2 | 所有存储媒体的详细信息,如交换、硬盘驱动器、可移动媒体和主内存 |
| hrDevice | host.3 | 可用设备及其属性的列表:除了处理器、网络接口、打印机和 DVD-/CD-ROM 驱动器的详细信息外,还包括硬盘驱动器、它们的分区、文件系统、挂载点和文件系统类型 |
| hrSWRun | host.4 | 包括 PID 和命令行参数的所有运行进程 |
| hrSWRunPerf | host.5 | 来自 hrSWRun 的进程的 CPU 使用率和内存使用率 |
| hrSWInstalled | host.6 | 已安装的软件;信息来源于 RPM 数据库(不幸的是,这在 Debian 中不起作用)。 |
表 11-3. UCD-SNMP-MIB 的摘录
| **`Group`** | **`OID`** | **`Directive`** | **`description`** |
| --- | --- | --- | --- |
| prTable | ucdavis.2 | **`proc`** | 运行进程的详细信息 |
| memory | ucdavis.4 | - | 内存和交换空间负载,如程序**`free`**所示 |
| extTable | ucdavis.8 | **`exec`** | 关于配置文件中自定义命令的信息 ^([a]) |
| dskTable | ucdavis.9 | **`disk`** | 关于文件系统的信息,请参见文本中的示例 |
| laTable | ucdavis.10 | **`load`** | 系统负载 |
| ucdExper- | ucdavis.13 | - | 包含 lm-sensor 信息条目的实验性扩展,等等 |
| fileTable | ucdavis.15 | **`file`** | 关于要显式监控的文件的信息 |
| version | ucdavis.100 - | - | 关于 NET-SNMP 版本和编译守护进程的参数的详细信息 |
|
^([a]) 这里可以使用任何可执行程序。
|
虽然**`mib-2.host`**仅指定绝对值,例如文件系统,但 UCD-SNMP-MIB 还允许为代理页面设置阈值值,然后明确生成一个错误值(**`dskErrorFlag`**)和错误文本(**`dskErrorMsg`**):
user@linux:~$ snmpwalk -v1 -c public localhost ucdavis.dskTable |\ grep '.2 ='
UCD-SNMP-MIB::dskIndex.2 = INTEGER: 2
UCD-SNMP-MIB::dskPath.2 = STRING: /net/swobspace/b
UCD-SNMP-MIB::dskDevice.2 = STRING: /dev/md6
UCD-SNMP-MIB::dskMinimum.2 = INTEGER: −1
UCD-SNMP-MIB::dskMinPercent.2 = INTEGER: 10
UCD-SNMP-MIB::dskTotal.2 = INTEGER: 39373624
UCD-SNMP-MIB::dskAvail.2 = INTEGER: 1694904
UCD-SNMP-MIB::dskUsed.2 = INTEGER: 35678636
UCD-SNMP-MIB::dskPercent.2 = INTEGER: 95
UCD-SNMP-MIB::dskPercentNode.2 = INTEGER: 1
UCD-SNMP-MIB::dskErrorFlag.2 = INTEGER: 1
UCD-SNMP-MIB::dskErrorMsg.2 = STRING: /net/swobspace/b: less than 10% free (= 95%)
**`grep '. 2 ='`**过滤器从**`snmpwalk`**输出中过滤出第二台设备的所有条目,Linux 软件 RAID **`/dev/md6`**。条目**`dskPercent`**显示此数据媒体的当前负载。如果**`dskErrorFlag`**包含值 1 而不是 0,则存在错误;**`dskErrorMsg`**向错误消息添加可读的消息。可以假设代理正在配置为在可用容量低于 10%时宣布错误。
### **`snmpd.conf`**配置文件
代理的配置在文件**`snmpd.conf`**中完成,该文件位于目录**`/etc`**中(适用于 SUSE 的情况)或**`/etc/snmp`**(Debian),具体取决于发行版。
`身份验证和安全` 作为精细访问控制的第一步,您首先需要定义谁应该有权访问哪个社区:
(1) source addressesQuelladressen
com2sec localnet 192.168.1.0/24 public
com2sec localhost 127.0.0.1 public
com2sec nagiossrv 192.168.1.9 public
**`com2sec`** 将源 IP 地址链接到一个社区字符串(SNMP 密码)。此关键字后跟 IP 地址范围的别名,地址范围本身,然后是一个自由选择的社区字符串,我们将使用 **`public`** 以保持简单.^([108])。**`192.168.1.0/24`** 指的是本地网络;Nagios 服务器本身的 IP 地址为 **`192.168.1.9`**。如果您稍后设置别名 **`localnet`** 的访问权限,它们将应用于整个本地网络 **`192.168.1.0/24`**,但如果您引用 **`nagiossrv`**,则它们仅应用于 Nagios 服务器本身。
然后将定义的计算机和网络通过它们的别名分配给具有不同安全模型的组:
(2) assignment of group - security model - source-IP alias
group Local v1 localhost
group Nagios v1 nagiossrv
关键词 **`group`** 首先跟一个自由选择的组名:在这里我们定义了名为 **`Local`** 的组,其安全模型为 **`v1`**,属于地址范围 **`localhost`**,以及具有相同安全模型的 **`Nagios`** 组,该组包含在 Nagios 服务器中。
您可以选择 **`v1`**(SNMPv1)、**`v2c`**(基于社区的 SNMPv2)和 **`usm`**(SNMPv3 的 *用户模型*)作为安全模型。如果您同时分配给计算机或网络多个安全模型,则需要具有相同组名的单独条目:
group Nagios v1 nagiossrv
group Nagios usm nagiossrv
通过定义视图(关键字 **`view`**),可以从外部精确限制对管理信息库的部分树的视图。每个视图也都有一个名称用于引用:
(3) View definition for partial trees of the SNMP namespace
view all included .1
view system included .iso.org.dod.internet.mgmt.mib-2.system
引用 **`included`** 包含视图中的以下部分树。因此视图 **`all`** 覆盖整个树(**`.1`**)。如果您想排除某些部分树,则使用关键字 **`excluded`**:
view all included .1
view all excluded .iso.org.dod.internet.private
在 **`all`** 下的 **`private`** 下的部分树现在已被阻止,例如 MIB **`ucdavis (private.enterprises.ucdavis`**)。
一个有趣的功能是掩码;它以十六进制表示法指定哪些节点正好对应于子树:
view all included .iso.org.dod.internet.mgmt F8
对于查询的 OID 的所有位置,如果掩码以二进制表示法包含 1,则必须在查询的部分树中与这里指定的 OID **`.iso.org.dod.internet.mgmt`** 相同,否则守护进程将拒绝访问且不提供任何信息。**`.iso.org.dod.internet.mgmt`** 以数值形式表示为 **`.1.3.6.1.2`**。
多亏了掩码 **`F8`**,^([109]) 二进制 11111000,OID 的最左边五个位置必须始终是 **`.iso.org.dod.internet.mgmt`**。如果有人查询了一个 OID(例如 **`private`** 树 **`.1.3.6.1.4`**),它偏离了这一点,代理将保持沉默且不提供任何信息。如果您省略掩码细节,将使用 **`FF`**。
如果您已定义了别名、社区、安全模型和视图,您只需将它们组合起来用于访问控制。这是通过 **`access`** 指令完成的。
(4) Definition of the access control
access Local any noauth exact all none none
access NagiosGrp any noauth exact all none none
访问限制绑定到组。**`context`** 列保持为空(**`'""`**),因为只有 SNMPv3 需要它.^([110])。作为安全模型,你通常选择 **`any`**,但你也可以使用 **`v1`**、**`v2c`** 或 **`usm`** 定义一个特定的模型,因为可能将多个不同的安全模型分配给一个组,如本节开头“身份验证和安全”讨论中所示。第五列指定了安全级别,这对于 SNMPv3 也是感兴趣的。在其他两种安全模型(我们只使用 **`v1`**)中,**`noauth`** 被给出。第四列最后一列在 SNMPv3 中也有唯一的意义。但由于你必须为 SNMPv1 和 SNMPv2c 输入有效的值,因此这里选择 **`exact`**。
最后两列指定了哪种视图应该用于哪种访问(读取或写入)。在示例中,组 **`Local`** 和 **`NagiosGrp`** 获得了对视图 **`all`** 的读取访问,但没有写入访问。最后一列定义了代理是否应该为视图有效范围内发生的事件向管理器发送 SNMP 陷阱——即主动消息。14.6 应用示例 II:处理 SNMP 陷阱 从第 312 页更详细地介绍了 SNMP 陷阱。
使用这里描述的配置,你现在可以通过 SNMPv1 独家访问 Nagios 服务器和 **`localhost`** 以获取信息。可以通过定义一个只使 MIB 的部分可见的视图进一步限制服务器访问。但你应该在配置描述正常工作后尝试此操作,以避免逻辑错误和耗时的调试。
`系统与本地信息` 部分树 **`mib-2.system`** 提供了关于系统本身以及可用的(即已实现的)MIBs 的信息。使用 **`syslocation`** 你可以指定系统在公司或校园中的位置,并在关键字 **`syscontact`** 后输入负责管理员的电子邮件地址:
(5) mib-2.system
syslocation Server room Martinstr., 2nd rack from the left
syscontact root wob@swobspace.de
只要在此处不重新定义参数 **`sysname`** 和 **`sysdescr`**,默认情况下相应的 MIBs 将揭示主机名和/或系统和内核规范,对应于 **`uname -a`**:
user@linux:~$ snmpwalk -v1 -c public localhost system
system.sysDescr.0 = STRING: Linux swobspace 2.6.10 #20 SMP Mon Dec 27 11:55:25 CET
2004 i686
system.sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
system.sysUpTime.0 = Timeticks: (1393474) 3:52:14.74
system.sysContact.0 = STRING: root wob@swobspace.de
system.sysName.0 = STRING: swobspace
system.sysLocation.0 = STRING: Serverraum Martinstr., 2. Rack von links
`定义要监控的进程` 使用 SNMP 监控的进程通过 **`proc`** 指令指定,如果需要,你可以指定进程的最小或最大数量:
(6) Processes: enterprises.ucdavis.procTable
proc process maximum minimum
proc process maximum
proc process
proc sshd
proc nmbd 2 1
proc smbd
proc slapd
如果缺少最大和最小值的条目,至少必须有一个进程正在运行。如果只省略了最小值,NET-SNMP 将使用零进程定义此值。相应的条目最终会出现在 MIB **`ucdavis.prTable`** 中;在出错的情况下,你会收到一个错误标志(**`prError-Flag`** 和错误描述(**`prErrMessage`**)(遗憾的是,你不能自己定义它)):
user@linux:~$ snmpwalk -v1 -c public localhost prTable
...
prTable.prIndex.4 = INTEGER: 4
prTable.prNames.4 = STRING: slapd
prTable.prMin.4 = INTEGER: 0
prTable.prMax.4 = INTEGER: 0
prTable.prCount.4 = INTEGER: 0
prTable.prErrorFlag.4 = INTEGER: 1
prTable.prErrMessage.4 = STRING: No slapd process running.
...
**`ucdavis. prTable`** 仅显示已配置的进程;另一方面,它允许 **`mib-2.host.hrSWRun`** 和 **`mib-2.host.hrSWRunPerf`** 通常查询所有运行进程。如果您想防止这种情况,视图必须排除您不希望包含的区域。
`您的自定义命令` 使用 **`exec`** 指令,您可以在扩展 **`ucdavis.extTable`** 中指定命令,代理将在相应的查询中执行这些命令。结果随后将出现在相关条目中。在以下示例中,如果代理被要求查询 **`ucdavis.extTable`**,它将调用 **`/bin/echo`**:
(7) your own commands: enterprises.ucdavis.extTable
exec name command arguments
exec echotest /bin/echo hello world
要执行的程序必须在配置中以其绝对路径出现。运行 **`snmpwalk`** 只提供以下信息:
user@linux:~$ snmpwalk -v1 -c public localhost extTable
extTable.extEntry.extIndex.1 = INTEGER: 1
extTable.extEntry.extNames.1 = STRING: echotest
extTable.extEntry.extCommand.1 = STRING: /bin/echo hello world
extTable.extEntry.extResult.1 = INTEGER: 0
extTable.extEntry.extOutput.1 = STRING: hello world
...
**`extTable.extEntry.extResult`** 包含执行命令的返回值,而 **`extTable.extEntry.extOutput`** 包含文本输出。
因此,使用 **`exec`** 指令可以查询本地脚本或程序可以找到的所有信息。然而,这可能会成为一个安全问题:如果使用的程序容易受到缓冲区溢出的影响,这个功能可能会被误用作为拒绝服务攻击的起点。
监控硬盘容量:**`disk`** 指令适用于监控文件系统。关键字 **`disk`** 后跟挂载点的路径,然后是应可用的最小硬盘空间(以 KB 或百分比表示)。如果您省略容量条目,至少必须有 100 MB 可用;否则将给出错误消息。
在以下示例中,**`/`** 文件系统的空闲容量不应低于 **`10%`**,在 **`/usr`** 上,至少应保留 800 MB 的空闲空间 ^([111]):
(8) File systems: enterprises.ucdavis.dskTable
disk mount point
disk mount point minimum_capacity_in_KB
disk mountpoint minimum_capacity_in_percent%
disk / 10%
disk /usr 819200
disk /data 50%
就数据分区 **`/data`** 而言,如果空闲容量低于 **`50%. dskErrorFlag`**,则应发出警报:在这种情况下,`dskErrorFlag` 的值应为 1 而不是 0,`dskErrorMsg` 包含错误文本:
...
UCD-SNMP-MIB::dskPercent.3 = INTEGER: 65
UCD-SNMP-MIB::dskErrorFlag.3 = INTEGER: 1
UCD-SNMP-MIB::dskErrorMsg.3 = STRING: /data: less than 50% free (= 65%)
**`dskPercent`** 显示当前负载为 **`65%`**。除了此处配置的部分树外,**`ucdavis.dskTable, mib-2.host.hrStorage`** 还提供了所有文件系统的概述,包括那些未明确定义的文件系统。然而,这些文件系统缺少百分比细节,并且您不会收到 **`ucdavis.dskTable`** 提供的错误状态或错误消息。
您应该仔细考虑是否在 NET-SNMP 或 Nagios 配置中设置警告限制。在前一种情况下,您必须在每个单独的主机上配置值。但是,如果您使用 **`check_snmp`** 插件(见第 246 页的 11.3.1 通用 SNMP 插件 check_snmp)查询百分比负载,那么您将在 Nagios 服务器上集中设置警告和临界限制,如果以后进行更改,这将节省您大量工作。**`includeAHDisks`** 指令将所有现有文件系统添加到 **`dskTable`** 表中:
includeAllDisks 10%
它需要指定一个最小限制值(以百分比表示),并返回错误值。在这里无法进行绝对 KB 的指定。如果您为**`check_snmp`**集中设置警告和错误限制;(参见 11.3.1 通用 SNMP 插件 check_snmp,从第 246 页开始)则不会查询错误属性**`dskErrorFlag`**和**`dskErrorMsg`**,因此这里设置的最低限制值可以忽略。
`系统负载` **`load`** 指令查询 CPU 负载。作为限制值,您指定一分钟的平均值,可选的五分钟和十五分钟的平均值:
(9) System Load: enterprises.ucdavis.laTable
load max1
load max1 max5
load max1 max5 max15
load 5 3 2
如果值超出范围,**`laErrorFlag`** 将包含状态 **`1`**(否则:**`0`**),而 **`laErrMessage`** 将包含错误信息的文本。
在超过指定限制的系统上,**`snmpwalk`** 返回以下内容:
user@linux:~$ snmpwalk -v1 -c public localhost laTable
...
UCD-SNMP-MIB::laNames.1 = STRING: Load-1
UCD-SNMP-MIB::laNames.2 = STRING: Load-5
UCD-SNMP-MIB::laNames.3 = STRING: Load-15
UCD-SNMP-MIB::laLoad.1 = STRING: 5.31
UCD-SNMP-MIB::laLoad.2 = STRING: 2.11
UCD-SNMP-MIB::laLoad.3 = STRING: 0.77
...
UCD-SNMP-MIB::laLoadInt.1 = INTEGER: 530
UCD-SNMP-MIB::laLoadInt.2 = INTEGER: 210
UCD-SNMP-MIB::laLoadInt.3 = INTEGER: 77
UCD-SNMP-MIB::laLoadFloat.1 = Opaque: Float: 5.310000
UCD-SNMP-MIB::laLoadFloat.2 = Opaque: Float: 2.110000
UCD-SNMP-MIB::laLoadFloat.3 = Opaque: Float: 0.770000
UCD-SNMP-MIB::laErrorFlag.1 = INTEGER: 1
UCD-SNMP-MIB::laErrorFlag.2 = INTEGER: 0
UCD-SNMP-MIB::laErrorFlag.3 = INTEGER: 0
UCD-SNMP-MIB::laErrMessage.1 = STRING: 1 min Load Average too high (=5.31)
UCD-SNMP-MIB::laErrMessage.2 = STRING:
UCD-SNMP-MIB::laErrMessage.3 = STRING:
从 **`laLoadlnt.1`** 我们得知系统 **`load`** 的一分钟平均值为整数,从 **`laLoad.l`** 作为字符串,从 **`laLoadFloat.1`** 作为浮点十进制。**`laErrorFlag.1`** 包含相应的错误状态,**`laErrMessage.1`** 包含相应的错误信息。其他两个平均值也适用同样的规则。
您也可以在这里使用**`check_snmp`**插件,以极高的精度查询浮点十进制值,并集中指定限制值。
* * *
^([106]) [`net-snmp.sourceforge.net/`](http://net-snmp.sourceforge.net/)
^([107]) [`www.kill-9.org/mbrowse/`](http://www.kill-9.org/mbrowse/)
^([108]) 参见第 236 页
^([109]) F= 1.2³+1.2²+1.2¹ +1.2⁰ = 1111, 8=1000
^([110]) 关于 SNMPv3 的相应描述将超出本书的范围
^([111]) 1024KB * 800
# 11.3 Nagios 自带的 SNMP 插件
在标准 Nagios 插件中,有三个程序可以通过 SNMP 获取数据:一个通用的插件可以查询您想要的任何 OID,以及两个专门处理网络卡接口数据和交换机、路由器等端口信息的 Perl 脚本。此外,**`contrib`** 目录包含其他未自动安装的 SNMP 插件源代码。显然,这些插件已经不再维护,并且需要代码的重大调整才能运行。
[`www.nagiosexchange.org/`](http://www.nagiosexchange.org/) 也提供了一些有用的专用插件,其中一些在 11.4 其他基于 SNMP 的插件中介绍,从第 255 页开始。由于篇幅限制,以下描述仅限于 SNMPv1/2 查询;对于 SNMPv3 特定的选项,请参阅相应插件的在线帮助。
## 11.3.1 通用 SNMP 插件 **`check_snmp`**
使用**`check_snmp`**,有一个通用的插件可以查询所有可用的信息,根据您的要求。然而,它的操作确实需要一定的谨慎,因为作为一个通用插件,它不知道它具体查询的是什么数据。
因此,其输出看起来相当简陋;专门的插件在这里提供了更多便利。但是,由于并非每个目的都有这些插件,因此**`check_snmp`**的使用是相当合理的。它调用程序**`snmpget`**,这意味着必须安装 NET-SNMP 工具。
它提供了以下选项:
**`-H`** **``*`address`*``**/ **`--host=`****``*`address`*``**
这是将被查询的 SNMP 代理的主机名或 IP 地址。
**`-o`** **``*`OID`*``** /**`--oid=`****``*`OID`*``**
这是将被查询的对象标识符,可以是完整的数值 OID,也可以是字符串,由**`snmpget`**解释(例如,**`system.sysName.O`**)。
注意:与**`snmpwalk`**不同,您必须始终指定包含信息的端节点。
**`-p`** **``*`port`*``** **`/ --port=`****``*`port`*``**
这是 SNMP 代理运行的备用端口。默认为 UDP 端口 161。
**`-C`** **``*`password`*``** **`/ --community=`****``*`password`*``**
这是读取访问的社区字符串。默认值为**`public`**。
**`-w`** **``*`start:end`*``** **`/ --warning=`****``*`start:end`*``**
如果查询值在由*start*和*end*指定的范围内,**`check_snmp`**不会输出警告。因此,对于**`-w 0:90`**,它必须大于 0 且小于 90。
**`-c`** **``*`start:end`*``** **`/ --critical=`****``*`start:end`*``**
如果查询值超出范围,插件将输出 CRITICAL。如果警告和临界限制重叠,则临界限制始终具有优先级
**`-s`** **``*`string`*``** **`/ --string=`****``*`string`*``**
查询的 OID 内容必须与指定的*字符串*完全匹配,否则**`check_snmp`**将输出错误。
**`-r`** **``*`regexp`*``** **`/ --ereg=`****``*`regexp`*``**
此选项检查查询的 OID 内容,以查看是否匹配正则表达式*regexp*^([112])。如果是这样,插件返回 OK,否则返回 CRITICAL。
**`-R`** **``*`regexp`*``** **`/ --erexi=`****``*`regexp`*``**
与**`-r`**类似,但没有任何大小写区分。
**`−1`** **``*`prefix`*``** **`/ --label=`****``*`prefix`*``**
放在插件响应前面的字符串。默认为**`SNMP`**。
**`-u`** **``*`string`*``** **`/ --units=`****``*`string`*``**
SNMP 只有简单值,没有单位。指定的字符串代替*string*被插件扩展到文本输出中,以便作为值使用单位。因为这里只涉及文本,所以您也可以指定**`apples`**或**`pears`**等作为“单位”。
**`-d`** **``*`delimiter`*``** **`/ --delimiter=`****``*`delimiter`*``**
这个字符将**`snmpget`**输出中的 OID 与值分开。默认是=。
**`-D`** **``*`分隔符`*``** **`/ --output-`** **`delimiter=`****``*`分隔符`*``**
插件能够同时查询多个 OID。结果值由*分隔符*分隔,默认是一个空格。
**`-m`** **``*`mibs`*``** **`/ --miblist=`****``*`mibs`*``**
这指定了**`snmpget`**应该加载的 MIB。默认是**`ALL.-m +UCD-DEMO-MIB`**^([113])。加载*附加的*,**`-m UCD-DEMO-MIB`**(没有**`+`**符号)*仅*加载指定的 MIB.^([114])。
**`-P`** **``*`version`*``** **`/ --protocol=`****``*`version`*``**
定义 SNMP 协议版本。*版本*的值是**`1`**或**`3`**。如果没有此选项,则使用 SNMPv1。
SNMP 提供了几乎无限的可能性,所以以下示例只能传达对其他插件使用的感觉。
### 通过 SNMP 测试硬盘容量
以下命令查询文件系统的负载,为此访问本地运行的 NET-SNMP 代理的局部树**`ucdavis.dskTable`**:
nagios@linux:local/libexec$ ./**check_snmp -H swobspace -C public **
-o dskTable.dskEntry.dskPercent.2 -w 0:90 -c 0:95 -u percent SNMP WARNING
- 95 percent
查询适用于索引号为 2 的文件系统的百分比负载。只要硬盘空间使用率不超过 90%,测试应该返回 OK;如果它在 91%到 95%之间,则返回警告,如果超过这个范围,则返回关键状态。多亏了**`-u`**选项,**`check_snmp`**将**`percent`**描述添加到确定的数值输出中。
然而,插件并没有说出全部真相:使用**`df`**进行的测试检查显示 96%的负载,这是因为该程序正确地将实际的 95.8%负载向上取整,而 SNMP 中的整数值很少向上取整,而是简单地截断。所以只要 MIB 不提供任何浮点小数,你就只能忍受轻微的不准确。
如果你想让内容更详细,可以使用选项**`−1: −1 'SNMP-DISK: /net/swobspace/b'`**,这会导致其他,自定义的信息被添加到上述命令的输出中:
SNMP-DISK: /net/swobspace/b WARNING - 95 percent
上述查询可以通过以下命令对象更一般地运行:
define command{
command_name check_snmp
command_line \(USER1\)/check_snmp -H \(HOSTADDRESS\) -C \(USER3\) -P 1 -o \(ARG1\)
-w \(ARG2\) -c \(ARG3\) -l \(ARG4\)
}
此定义假定要查询的值是数值,而不是布尔值(参见监控网络接口),否则同时指定警告和关键值就没有意义。我们在这里将社区存储在宏**`$USER3$`**中.^([115])。这后面跟着协议版本(**`-P 1`**代表 SNMPv1),OID,警告和关键限制,以及一个前缀。
在服务定义中对该命令的调用形式是
check_snmp! oid! warn! critical !prefix
如果你想要通过 **`dskTable`** 特定地监控计算机 **`swobspace`** 上索引号为 2 的文件系统的负载,那么以下定义将被使用:
define service{
service_description SNMP-DISK-a
host_name swobspace
check_command check_snmp!dskTable.dskEntry.dskPercent.2!0:90!0:95!DIS
K: /net/swobspace/a
...
}
尽管这里的 **`check_command`** 行被换行了,但在实际操作中,所有参数必须位于同一行,由感叹号 **`!`**(分隔符前后没有空格)分隔。
### 通过 **`lm-sensors`** 测量温度
下一个测试检查主机的 CPU 温度。对于传感器,这里使用的是 **`lm-sensors`** 软件包^([116]), 它访问现代主板上相应的芯片。一旦 **`lm-sensors`** 激活,它允许 NET-SNMP 代理从部分树 **`ucdavis.ucdExperimental.lmSensors:`** 中读取相应的信息。
nagios@linux:local/libexec$ ./check_snmp -H localhost -C public \ -o
lmTempSensorsValue.1 -w 25000:45000 -c 20000:48000 \ -u 'degrees Celsius (* 1000)'
-l 'Temp1/CPU'
Temp1/CPU OK - 41000 degrees Celsius (* 1000)
输出取决于芯片组:在这里你必须将查询值乘以 1000 的系数。因此,你别无选择,只能将警告和临界限制调整到你使用的主板。在示例中,CPU 温度为 41 摄氏度,处于“绿灯”状态:如果它低于 25 摄氏度或高于 45 摄氏度,将会触发警告,而低于 20 摄氏度或高于 48 摄氏度,则会被视为临界。
### 正则表达式和比较固定字符串
你可以检查文本 **`swobspace`** 是否出现在系统名称中,方法如下:
nagios@linux:local/libexec$ ./check_snmp -H localhost -C public \ -o system.sysName.0
-r swobspace
SNMP OK - "swobspace"
除了使用 **`-r`** 作为正则表达式来定义要搜索的字符串外,你也可以使用 **`-s`** 选项。然后文本必须完全匹配,但这可能相当棘手,因为 **`snmpget`** 在分隔符 **`=`** 之后输出的所有内容都算数。
### 监控网络接口
最后一个示例查询的是否是 Cisco 路由器的第一个网络接口正在运行:
nagios@linux:local/libexec$ ./check_snmp -H cisco1 -C public
-o ifOperStatus.1 -w 1:1 -l 'SNMP: Port Status for Port 1 is: '
SNNP: Port Status for Port 1 is: OK - 1
所需信息可以在 **`ifOperStatus`** 中找到。在这里我们查询端口 1。而 **`ifOperStatus`** 提供操作状态,**`ifAdmin-Status`** 则揭示接口是否被管理性地开启或关闭。
在这里指定警告限制时,我们使用范围 **`1:1`**,这样插件就会在接口物理关闭时发出警告,因此返回值是 0。在这里我们不需要定义临界状态,因为只有两种状态,“开启”或“关闭”。如果插件在接口关闭时返回 CRITICAL,你应该使用 **`-c 1:1`** 并完全省略 **`-w`**。
如果你只想查询网络接口的状态,你当然应该看看下面描述的插件 **`check_ifstatus`** 和 **`check_ifoperstatus`**,它们提供了稍微更多一些的操作便利性。
如果 MIB-II 或 MIB **`ucdavis`** 没有提供所需的信息,你也可以看看制造商提供的 MIB。你可以从 **`mib-2.system`** 中找出整体 MIB 隐藏在哪个部分树中:
user@linux:~$ snmpwalk -v1 -c public konica01 system
system.sysDescr.0 = Konica IP Controller
system.sysObjectID.0 = OID: enterprises.2364
...
该示例涉及一台名为**`konica01.system.sysObjectID.0`**的网络功能型柯尼卡复印机,表明**`enterprises.2364`**是设备特定细节的入口点。使用**`snmpwalk`**,您可以进一步获取信息:
user@linux:~$ snmpwalk -v1 -c public konica01 enterprises.2364
...
enterprises.2364.1.2.6.1.1.5.1.1 = "Ready to Print"
...
在这台复印机的具体情况下,您可以通过**`enterprises.2364.1.2.6.1.1.5.1.1`**查询当前设备状态。制造商通常存储有关实现 MIB 的信息,这样您就不必仅仅猜测。
## 11.3.2 同时检查多个接口
活动网络组件,如交换机,通常具有相当多的端口,检查每一个端口都会非常耗时。在这里,**`check_ifstatus`**插件非常有用,因为它可以同时测试所有端口。它通过 SNMP 检索此信息,并具有以下选项:
**`-H`** **``*`address`*``** **`/ --host=`****``*`address`*``**
这是将被查询的 SNMP 代理的主机名或 IP 地址。
**`-C`** **``*`password`*``** **`/ --community=`****``*`password`*``**
这设置了读取访问的社区字符串。
**`-p`** **``*`port`*``** **`/ --port=`****``*`port`*``**
此参数是 SNMP 代理运行的备用端口。默认为 UDP 端口 161。
**`-v`** **``*`version`*``** **`/ --snmp_version=`****``*`version`*``**
此参数指定查询的 SNMP 版本(**`1`**、**`2`**或**`3`**)。
**`-x`** **``*`list`*``** **`/ --exclude=`****``*`list`*``**
使用此选项来指定不应查询的逗号分隔的接口类型列表(请参见以下示例)。
**`-u`** **``*`list`*``** **`/ --unused_ports=`****``*`list`*``**
使用此选项来指定应从测试中排除的所有端口的逗号分隔列表。像**`-x`**一样,该列表由接口索引组成,这些索引由**`if Index: -u 13,14,15,16`**确定。
**`-M`** **``*`bytes`*``** **`/ --maxmsgsize=`****``*`bytes`*``**
这是 SNMP 数据包的最大大小;默认为**`1472`**字节。
使用排除列表,可以排除某些接口类型或端口号,可能是因为这些端口未被占用,或者连接到 PC 或其他设备,而这些设备并不总是运行。
使用以下查询,我们可以找出例如,在名为**`cisco01`**的 Cisco 交换机上哪些接口类型被组合在一起:
user@linux:~$ snmpwalk -v1 -c public cisco01 ifType
...
interfaces.ifTable.ifEntry.ifType.12 = ethernetCsmacd(6)
interfaces.ifTable.ifEntry.ifType.13 = other(1)
interfaces.ifTable.ifEntry.ifType.14 = propVirtual(53)
...
如果要排除接口类型**`other(1)`**和**`propVirtual(53)`**,则插件将发送带有两个数字的排除列表**`-x 1,53`**:
nagios@linux:local/libexec$ ./check_ifstatus -C public -H cisco01
-x 1,53
CRITICAL: host 'cisco01', interfaces up: 2, down: 10, dormant: 0,
excluded: 4, unused: 0
GigabitEthernet0/2: down
GigabitEthernet0/3: down
GigabitEthernet0/4: down
GigabitEthernet0/10: down
GigabitEthernet0/5: down
GigabitEthernet0/11: down
GigabitEthernet0/6: down
GigabitEthernet0/7: down
GigabitEthernet0/8: down
GigabitEthernet0/9: down
|up=2, down=10, dormant=0, excluded=4, unu
sed=0
实际上,此插件也不会在其输出中显示多行,尽管这里的换行可能暗示了这一点。此信息之所以在 Nagios Web 界面中以相对清晰的形式出现,是因为其中加入了 HTML 格式化元素**`<BR>`**。这导致每个端口的输出都显示在不同的行上。**`|`**字符定义性能数据的开始,在 Web 界面中根本不会出现。
此类查询作为以下命令对象实现:
define command{
command_name check_ifstatus
command_line \(USER1\)/check_ifstatus -H \(HOSTADDRESS\) -C
\(USER3\)
-x \(ARG1\)
}
这里也使用了宏**`$USER3$`**来在文件**`resource.cfg`**中定义社区字符串。总共有 32 个**`$USERx$`**宏可用,其中前两个通常包含路径细节,其余的可以按您希望的方式使用。
如果您希望排除端口而不是接口类型,可以在定义中使用**`-u`**选项而不是**`-x`**。
如果 Nagios 要监控**`cisco01`**交换机,如上所示,排除接口类型**`1`**和**`53`**,相应的服务定义如下:
define service{
service_description Interfaces
host_name cisco01
check_command check_ifstatus!1, 53
...
}
## 11.3.3 测试单个接口的运行状态
要测试单个接口,可以使用通用的插件**`check_snmp`**或**`check_ifoperstatus`**,后者专门测试网络卡的运行状态(**`ifOperStatus`**)。与通用插件相比,其优势主要在于易于使用:您不仅可以指定端口的索引,还可以指定其描述,例如,**`eth0`**。
**`check_ifoperstatus`**具有以下选项:
**`-H`** **``*`address`*``** **`/ --host=`****``*`address`*``**
这是待查询的 SNP 代理的主机名或 IP 地址。
**`-C`** **``*`password`*``** **`/ --community=`****``*`password`*``**
此参数给出读取访问的社区字符串。
**`-p`** **``*`port`*``** **`/ --port=`****``*`port`*``**
只要 SNMP 代理不在 UDP 端口 161 上运行,就可以使用此选项指定端口。
**`-k`** **``*`ifIndex`*``** **`/ --key=`****``*`ifIndex`*``**
*ifIndex* 是要查询的网络接口的编号(例如计算机的网络卡或交换机的端口)。
**`-d`** **``*`ifDescr`*``** **`/ --descr=`****``*`ifDescr`*``**
与索引键不同,该插件处理接口名称,从 *ifDescr*(见下文)获取。
**`-v`** **``*`version`*``** **`/ --snmp_version=`****``*`version`*``**
此处指定查询的 SNMP 版本(**`1, 2`**,或 **`3`**)。
**`-w`** **``*`return_value`*``** **`/ --warn=`****``*`return_value`*``**
此选项选择在接口休眠时的返回值。*return_value* 可以是 **`i`**(忽略休眠状态并返回 OK!),**`w`**(警告)或 **`c`**(严重,默认值)。
**`-D`** **``*`return_value`*``** **`/ --admin-down=`****``*`return_value`*``**
如果接口被管理员关闭,插件应该返回什么值(**`i`**、**`w`** 或 **`c`**)?默认值 **`w`** 会发出警告,**`c`** 返回 CRITICAL,**`i`** 返回 OK。
**`-M`** **``*`bytes`*``** **`/ --maxmsgsize=`****``*`bytes`*``**
这是 SNMP 数据包的最大大小;默认为 **`1472`** 字节。
在一个名为 **`igate`** 的系统上,其中 **`snmpwalk`** 找到以下接口 ...
...
interfaces.ifTable.ifEntry.ifDescr.3 = ipsec0
interfaces.ifTable.ifEntry.ifDescr.4 = ipsec1
...
interfaces.ifTable.ifEntry.ifDescr.7 = eth0
interfaces.ifTable.ifEntry.ifDescr.8 = eth1
interfaces.ifTable.ifEntry.ifDescr.9 = eth2
interfaces.ifTable.ifEntry.ifDescr.10 = ppp0
第一块以太网卡可以通过 **`-k 7`** 或 **`-d etho`** 进行测试。由于在第二种情况下,插件必须查询所有 **`ifDescr`** 条目以确定索引本身,这种变化会产生更高的网络负载。如果主机上的不是所有网络接口都处于活动状态,导致其索引发生变化,这特别有用。
插件本身会显示当前端口的索引:
nagios@linux:local/libexec$ *./check_ifoperstatus -H igate -c public *
-d eth0
OK: Interface eth0 (index 7) is up.
作为 Nagios 配置中的命令对象,调用看起来是这样的:
define command{
command_name check_ifoperstatus
command_line \(USER1\)/check_ifoperstatus -H \(HOSTADDRESS\) -C \(USER
3\) -d \(ARG1\)
}
**`$USER3$`** 宏再次包含社区字符串,该字符串在文件 **`resource.cfg`** 中定义。**`igate`** 服务的定义指定了要测试的接口名称作为插件参数:
define service{
service_description Interface eth0
host_name igate
check_command check_ifoperstatus!eth0
}
* * *
^([112]) POSIX 正则表达式,请参阅 **`man 7 regex`**。
^([113]) **`UCD-DEMO-MIB`** 是一个用于演示目的的 MIB
^([114]) 参见在线帮助,使用 **`man snmpcmd`**
^([115]) **`$USERx$`** 宏定义在资源文件 **`resource.cfg`** 中
^([116]) [`www.lm-sensors.nu/`](http://www.lm-sensors.nu/)
# 11.4 其他基于 SNMP 的插件
除了 Nagios 插件包中的 SNMP 插件外,Nagios 社区还提供大量针对特殊目的的其他插件。大多数可以在 **`[`www.nagiosexchange.org/`](http://www.nagiosexchange.org/)`** 的 `Check Plugins | SNMP` 类别中找到。^([117])
## 11.4.1 使用 **`nagios-snmp-plugins`** 监控硬盘空间和进程
其中之一是包 **`nagios-snmp-plugins`**,^([118]) 它不仅存在源代码版本,也存在 RPM 包(适用于 Red Hat 和 Fedora)。它包含两个非常易于使用的插件:**`check_snmp_disk`** 和 **`check_snmp_proc`**。
它们都绝对需要 NET-SNMP 代理作为另一侧的合作伙伴(参见第 238 页的 11.2.2 The NET-SNMP daemon),并使用 **`ucdavis.dskTable`** 和 **`ucdavis.prTable`** 测试配置文件 **`snmpd.conf`** 中指定的进程和文件系统。其选项仅限于指定主机和社区字符串:
**`-H`** **``*`address`*``** **`/ --host=`****``*`address`*``**
这是将被查询的 NET-SNMP 代理的主机名或 IP 地址。
**`-C`** **``*`password`*``** **`/ --community=`****``*`password`*``**
这是读取访问的社区字符串。
以下示例测试了 **`/data`** 文件系统的可用容量;再次使用 **`public`** 作为社区字符串:
nagios@linux:local/libexec$ ./check_snmp_disk -H swobspace -C public
/data: less than 50% free (= 95%) (/dev/md6)
NET-SNMP 代理的配置使用 **`disk`** 指令 (配置文件 snmpd.conf),将 **`50%`** 作为此文件系统的阈值。在这种情况下,插件相应地返回 CRITICAL。它只能区分错误和正常;没有警告状态。
使用 **`check_snmp_proc`** 同样简单:
nagios@linux:local/libexec$ ./check_snmp_proc -H localhost -C public
No slapd process running.
插件再次使用 **`proc`** 指令 (配置文件 snmpd.conf) 测试 NET-SNMP 代理配置中定义的进程。这里缺少 **`slapd`** 进程,因此返回 CRITICAL。返回值通过 **`echo $?`** 揭示。
相应的命令对象以类似不引人注目的方式定义:
define command{
command_name check_snmp_proc
command_line \(USER1\)/check_snmp_proc -H \(HOSTADDRESS\) -C \(USER3\)
}
define command{
command_name check_snmp_disk
command_line \(USER1\)/check_snmp_disk -H \(HOSTADDRESS\) -C \(USER3\)
}
此定义还假设社区字符串存储在文件 **`resource.cfg`** 中的 **`$USER3$`** 宏中。为了查询计算机 **`linux01`** 上的 NET-SMTPD 的硬盘负载,定义以下服务对象:
define service{
service_description DISK
host_name linux01
check_command check_snmp_disk
...
}
## 11.4.2 使用 **`check-iftraffic`** 检查网络接口的负载
MIB-II 只包含关于网络接口负载的信息数字,但没有使用带宽的平均值,例如。如果供应商在其 MIB 中没有特别提供此类条目,那么您将始终需要记录最后计数器状态和时间戳,以便您可以自己计算出相对使用情况。
**`[`www.nagiosexchange.org/`](http://www.nagiosexchange.org/)`** 介绍了两个插件,它们接管此任务。基于 Perl 的插件 **`check_traffic`**^([119]) 将查询值写入 *循环冗余数据库*(RRD,见 19.2 使用 Nagiosgraph 在 Web 上创建图形),这使得处理稍微复杂一些。
通过 **`check_iftraffic.pl`** 插件.^([120]),以更简单的方式达到相同的目的。它有以下选项:
**`-H`** **``*`address`*``** **`/ --host=`****``*`address`*``**
*`address`* 是要查询的 NET-SNMP 代理的主机名或 IP 地址。
**`-C`** **``*`password`*``** **`/ --community=`****``*`password`*``**
**``*`password`*``** 是读取访问的社区字符串。默认为公开。
**`-i`** **``*`ifDescr`*``** **`/ --interface=`****``*`ifDescr`*``**
从接口名称 **``*`ifDescr`*``**,插件确定索引以便它可以访问其他值(例如,计数器状态)。
**`-b`** **``*`integer`*``** **`/ --bandwith=`****``*`integer`*``**
这是接口的最大带宽,以比特为单位(见 **`-u`**)。
**`-u`** **``*`单位`*``** **`/ --units=`****``*`单位`*``**
这是使用**`-b`**指定的带宽的单位。可能的值是**`g`**(Gbit)、**`m`**(Mbit)、**`k`**(kbit)和默认的**`b`**(bit):**`-b 100 -u m`**对应于 100 兆比特(快速以太网)。
**`-w`** **``*`整数`*``** **`/ --warning=`****``*`整数`*``**
如果流量超过此警告限制的百分比(默认:**`85`**%),则插件发出警告。
**`-c`** **``*`整数`*``** **`/ --critical=`****``*`整数`*``**
这是百分比中的临界阈值(默认:**`92`**%)。
该插件将查询界面的时间戳和计数器状态保存在**`/tmp`**目录下的文件中,并在其前添加前缀**`traffic`**。因此,如果你在命令行上使用不同于**`nagios`**的用户 ID 进行手动测试,应在激活适当的 Nagios 服务之前删除**`/tmp/traffic`**目录下的**`_interface_computer`**文件。
以下命令行示例查询了计算机**`linux01`**上的快速以太网网络接口**`etho`**,理论上具有 100 Mbit 的带宽:
nagios@linux:local/libexec$ *./check_iftraffic.pl -H linux01 -i etho *
-b 100 -u m
Total RX Bytes: 60.32 MB, Total TX Bytes: 26.59 MB
Average Traffic:
1.14 kB/s (0.0%) in, 777.93 B/s (0.0%) out | inUsage=0.0,85,98 outUsage
=0.0,85,98
此处传输的数据量由插件分别报告,根据方向不同,这里宣布了 60.32 MB(**`RX`**,"接收")和 26.59 MB(**`TX`**,"发送")。文本包含 HTML 元素**`<br>`**(换行),用于在 Nagios Web 界面上显示输出为两行。随后是平均传输速率,再次分别针对传入和传出数据流量。**`|`**符号之后的性能数据(见 19.1 使用 Nagios 处理插件性能数据,第 404 页)仅包含平均负载的百分比,每个值分别对应传入和传出。数字**`85`**和**`98`**是警告和临界限制的默认值。
相应的命令对象实现如下:
define command{
command_name check_iftraffic
command_line \(USER1\)/check_iftraffic.pl -H \(HOSTADDRESS\) -C \(USER3\)
-i \(ARG1\) -b \(ARG2\) -u m
}
如果直接采用定义,必须在**`$USER3$`**宏中定义社区字符串。如果你只一般性地使用**`public`**作为密码,最好写成**`-C public`**而不是**`-C $USER3$`**。
为了简化以下服务定义中命令的调用,我们将单位设置为兆比特/秒(**`-u m`**)。
define service{
service_description Traffic load eth0
host_name linux01
check_command check_iftraffic!eth0!100
...
max_check_attempts 1
normal_check_interval 5
retry_check_interval 5
...
}
**`check_iftraffic`**通过比较不同时间点的两个计数器状态来计算使用的带宽。由于 Nagios 不能精确到秒进行测试,因此你选择的检查间隔不应太小。显示带宽使用的图形形式的**`Multi Router Traffic Grapher`**,^([121])通常以五分钟为间隔工作。
如果你选择 **`max_check_attempts`** 不是 **`1`**,你应该确保重试间隔(**`retry_check_interval`**)与正常检查间隔相同。对于 **`max_check_attempts 1`** 这没有区别,但你必须在某个时候定义一个 **`retry_check_interval`**。
## 11.4.3 用于特殊应用目的的 [manubulon.com](http://manubulon.com) 插件
Nagios Exchange,其中包含可在 [`www.manubulon.com/nagios/`](http://www.manubulon.com/nagios/) 找到的 SNMP 插件(见 表 11-4),还包括一些针对特定应用定制的插件,例如查询硬盘空间。它们相对简单易用。
表 11-4. [manubulon.com](http://manubulon.com)-SNMP 插件
| 插件 | 描述 |
| --- | --- |
| **`check_sn.mp_storage.pl`** | 存储设备(硬盘驱动器、交换空间、主内存等)查询 |
| **`check_snmp_int.pl`** | 接口状态和负载 |
| **`check_snmp_process.pl`** | 进程:状态、CPU 和内存使用情况 |
| **`check_snmp_load.pl`** | 系统负载 |
| **`check_snmp_mem.pl`** | 主内存和交换空间使用情况 |
| **`check_snmp_vrrp.pl`** | 查询诺基亚-VRRP 集群 ^([a]) |
| **`check_snmp_cpfw.pl`** | 查询 Checkpoint firewall-1^([b]) |
| **`check_snmp_env.pl`** | 测试交换机等环境参数,如温度、电源单元和风扇(思科、Foundry 等) |
| **`check_snmp_win.pl`** | 通过 SNMP 查询 Windows 服务 |
|
^([a]) VRRP 的缩写代表 *虚拟路由冗余协议*。
^([b]) [`www.checkpoint.com/products/firewall-1/`](http://www.checkpoint.com/products/firewall-1/)
|
我们将在这里详细介绍两个插件——**`check_snmp_storage.pl`** 和 **`_snmp_load.pl`**。
### 使用 **`check_snmp_storage`** 保持对存储介质的检查
虽然 **`check_snmp_disk`** 插件,如第 256 页的 11.4.1 使用 nagios-snmp-plugins 监控硬盘空间和进程 中所述,仅检查在 NET-SNMP 配置中输入的文件系统,但 **`check_snmp_storage.pl`** 能够查询任何存储介质——甚至交换空间或主内存——无需在目标主机上进行预先配置。**`check_snmp_storage.pl`** 测试的是 **`mib-2`** 的部分树,这里的 **`host`**,而 **`check_snmp_mem.pl`** 使用 **`ucdavis.memory`**,因此它仍然局限于 NET-SNMP。
你不必与 OID 作战,而是可以使用 **`swap space`** 类型的描述来指定存储介质的类型,这提供了一定程度的便利。这些可以通过以下方式使用 **`snmpwalk`** 进行查询:
user@linux:~$ snmpwalk -v1 -c public swobspace hrStorageDescr
hrStorageDescr.2 = STRING: Real Memory
hrStorageDescr.3 = STRING: Swap Space
hrStorageDescr.4 = STRING: /
...
hrStorageDescr.11 = STRING: /net/swobspace/b
当插件被调用时,**`STRING`**之后指定的文本就足够了,或者如果唯一的话,是这部分的一部分:
nagios@linux:local/libexec$ *./check_snmp_storage.pl -H swobspace *
-C public -m /net/swobspace/b -w 90 -c 95
/net/swobspace/b : 91 %used (34842MB/38451MB) (< 90) : WARNING
nagios@linux:local/libexec$ *./check_snmp_storage.pl -H swobspace *
-C public -m "Swap" -w 50 -c 75 -f
Swap Space : 0 %used (0MB/3906MB) (< 50) : OK | 'Swap Space'=0MB;1953;
2930;0;3906
在第二个示例中,只需指定**`Swap`**,即可查询**`交换空间`**的数据,因为模式是唯一的。**`-f`**选项确保**`check_snmp_storage.pl`**将在其输出中包含性能数据。
**`-w`**和**`-c`**以常规方式指定可用内存空间的警告或临界限制的百分比。以下概述列出了所有选项:
**`-H`** **``*`地址`*``** **`/ --host=`****``*`地址`*``**
这是将要查询的 NET-SNMP 代理的主机名或 IP 地址。
**`-C`** **``*`字符串`*``** **`/ --community=`****``*`字符串`*``**
这是读取访问的共同体字符串。
**`-p`** **``*`端口`*``** **`/ --port=`****``*`端口`*``**
**``*`端口`*``**指定一个替代端口,如果 SNMP 代理不在默认的 UDP 端口 161 上运行。
**`-m`** **``*`字符串`*``** **`/ --name=`****``*`字符串`*``**
**``*`字符串`*``**包含要查询的设备的描述,对应于其在**`hrStorageDescr`**中的描述(见上文),例如**`-m "交换空间"`**用于交换设备,**`-m "真实内存"`**用于主内存,或**`-m "/usr"`**用于文件树中挂载在**`/usr`**的分区。
**`-w`** **``*`百分比`*``** **`/ --warn=`****``*`百分比`*``**
如果使用的内存比例超过指定的阈值,默认情况下会发出警告。其他警告限制可以通过**`-T`**参数定义。
**`-c`** **``*`临界`*``** **`/ --critical=`****``*`临界`*``**
默认情况下,如果使用的内存比例超过指定的临界限制,状态将被分类为临界。也可以通过**`-T`**参数指定其他临界限制。
**`-T`** **``*`选项`*``** **`/ --type=`****``*`选项`*``**
临界和警告阈值指的是什么?
+ **`pu`** (*使用百分比*): 使用容量(百分比)
+ **`pl`** (*剩余百分比*): 百分比剩余空间
+ **`bu`** (*使用字节*): 使用容量(兆字节)
+ **`bl`** (*剩余字节*): 百分比剩余空间
默认是**`-T pu`**。
**`-r`** **`/ --noregexp`**
通常,**`-m`**参数中的描述被视为正则表达式。例如,这里的**`/var`**代表包含**`/var`**的所有文件系统,例如**`/var`**和**`/var/spool/imap`**,前提是这些确实是两个独立的文件系统。**`-r`**选项关闭正则表达式功能,因此指定**`/var`**将精确匹配此文件系统,但不匹配例如**`/var/spool/imap`**。
**`-s`** **`/ --sum`**
而不是对几个指定的存储介质进行单独测试,将总占用空间加起来并与总容量进行比较。然后确定是否超过阈值。
**`-i`** **`/ --index`**
使用 **`-m`**,通常指定一个文本,该文本会在描述 **`hrStorageDescr`** 中再次出现。使用 **`-i`** 选项时,使用索引表而不是描述。在这里,正则表达式功能也适用:**`-m 2`** 匹配索引中包含数字 **`2`** 的所有条目(即,**`2, 12, 20`** 等)。因此,同时使用 **`-r`** 选项是有意义的。
**`-e`** **`/ --exclude`**
现在,所有与 **`-m`** 规范匹配的内存都被排除在测试之外,剩余的内存包含在测试中。
**`-f`** **`/--perfparse`**
此选项提供额外的性能数据输出,这些数据未在 Web 界面中显示,但可以通过其他工具评估(见第十九章)。
### 使用 **`check_snmp_load`** 测试系统负载
插件比较平均系统负载,形式为一分钟、五分钟和十五分钟的平均值,或者以百分比表示的 CPU 负载。
**`-H`** **``*`address`*``** **`/ --host=`****``*`address`*``**
这是将被查询的 NET-SNMP 代理的主机名或 IP 地址。
**`-C`** **``*`string`*``** **`/ --community=`****``*`string`*``**
这是读取访问的社区字符串。
**`-p`** **``*`port`*``** **`/ --port=`****``*`port`*``**
**``*`port`*``** 是 SNMP 代理运行的替代 UDP 端口。默认为 UDP 端口 161。
**`-w`** **``*`warning_limit`*``** **`/ --warn=`****``*`warning_limit`*``**
警告限制可以是一个简单的整数百分比(例如,**`90`**)或由逗号分隔的整数三元组,它定义了系统负载平均的阈值,用于一分钟、五分钟和十五分钟(例如,**`8,5,5`**)。另一方面,百分比负载始终指代最后分钟的 CPU 负载。
如果插件查询 NET-SNMP 代理,则必须在第二种变体中另外指定 **`-L`** 选项,对于百分比,**`-N`**。
**`-c`** **``*`critical_limit`*``** **`/ --crit=`****``*`critical_limit`*``**
这指定了一个临界限制;语法与 **`-w`** 相同。
**`-L`** **`/ --linux`**
此选项指定插件通过 NET-SNMP 查询 Linux 系统的系统模式。
**`-A`** **`/ --as400`**
此选项指定查询 AS/400 机器上的 CPU 负载。
**`-I`** **`/ --cisco`**
此选项指定 Cisco 网络组件的 CPU 负载涉及。
**`-N`** **`/ --netsnmp`**
如果插件通过 NET-SNMP 查询 Linux 系统的 CPU 负载百分比,则必须指定 **`-N`** 选项。
**`-f`** **`/--perfparse`**
此选项确保输出未在 Web 界面中显示的性能数据,但可以通过其他工具评估(见第十九章)。
以下示例通过 NET-SNMP 查询计算机**`swobspace`**的系统负载,并指定了一分钟、五分钟和十五分钟平均值的阈值:
nagios@linux:local/libexec$ *./check_snmp_load.pl -H swobspace *
-C public -w 1,2,3 -c 3,5,6 -L
Load : 0.05 0.07 0.06 : OK
nagios@linux:local/libexec$ *./check_snmp_load.pl -H swobspace *
-C public -N -w 80 -c 90 -f
CPU used 3.0 : < 80 : OK | cpu_prct_used=3%;80;90
第二个示例涉及同一台机器的 CPU 负载百分比。在这里,我们除了请求性能数据外,还像往常一样重复了测量的值和阈值。
* * *
^([117]) [`www.nagiosexchange.org/SNMP.51.0.html`](http://www.nagiosexchange.org/SNMP.51.0.html)
^([118]) ftp://ftp.hometree.net/pub/nagios-snmp-plugins/
^([119]) [`nagios.sourceforge.net/download/contrib/misc/check_traffic/`](http://nagios.sourceforge.net/download/contrib/misc/check_traffic/)
^([120]) [`www.nagiosexchange.org//51;37`](http://www.nagiosexchange.org//51;37)
^([121]) [`www.mrtg.org/`](http://www.mrtg.org/)
# 第十二章. Nagios 通知系统
如果系统出现问题时没有通知正确的联系人,系统和网络监控还有什么意义?几乎没有任何系统或网络管理员能够持续关注 Nagios Web 界面并等待状态变化。一个实用的工作系统必须主动通知管理员(推送信息),这样管理员就有时间处理其他事情,并且只有在 Nagios 发出警报时才需要干预。
一个通知系统是否在实际中发挥作用,最终取决于它如何适应特定情况的要求。对某个人来说可能是关键错误的错误,对另一个人来说可能不是正常但仍然可以容忍的,没有什么比被大量看似错误但甚至在某些环境中不被视为错误的消息轰炸更糟糕了。过多的错误信息会使管理员变得粗心大意,并且最终真正的问题会淹没在错误消息的洪流中。
Nagios 提供了一个复杂的通知系统,允许您根据自身需求对环境进行精细调整。一开始的广泛设置可能看起来令人困惑,但一旦理解了基本原理,一切都会变得清晰许多。
保持 Nagios 小巧和模块化的努力也适用于通知系统:发送消息再次由系统交给外部程序:从简单的电子邮件到短信,再到硬件解决方案——例如服务器机柜上的真实交通灯——任何可能的事情都是可能的。
# 12.1 应在何时通知谁?
为了让 Nagios 发送有意义的消息,管理员必须回答四个问题:
+ 系统应在何时生成消息?
+ 应在何时发送?
+ 系统应通知谁?
+ 消息应该如何发送?

图 12-1. 通知系统的概述
图 12-1 给出了概念的大致轮廓。服务和主机检查生成消息,然后该消息通过各种过滤器,^([122])这些通常与时间有关。*联系人*指的是 Nagios 应该通知的人。如果消息通过了所有测试,系统将其交给一个外部程序,该程序通知相应的联系人。
* * *
^([122]) 严格来说,在主机或服务中定义的过滤器阻止消息的创建,而不是过滤已经生成的消息。然而,为了简化问题,我们假设 Nagios 创建了一个随后被相应过滤器丢弃的消息。
# 12.2 消息何时发生?
每条消息都由主机或服务检查开始,这确定了当前状态。在以下两种情况下,它会生成一条消息:
+ 一个硬状态变为另一个硬状态。
+ 一台计算机或服务保持在一个硬错误状态。(因此,测试确认了一个已经存在的问题。)
为了提醒您:**`max_check_attempts`** 参数(参见 2.3 定义要监控的机器,包括主机和 2.5 定义要监控的服务)定义了在主机和服务对象中,在 Nagios 将新状态分类为“硬”之前,测试应该重复多少次。如果设置为**`1`**,这立即就是情况,并随后产生相应的消息。如果值大于 1,系统会重复测试这么多次数,并且只有当它们都得到相同的新结果——例如确定 CRITICAL 错误状态——状态才会最终变为新的硬状态,从而触发新的通知。
只要 Nagios 没有达到指定的重复次数,就存在一个软状态。如果在这些重复完成之前旧状态再次出现,除非管理员查看 Web 界面或日志文件,否则管理员将不会得到通知。最终,管理员只对真正的未解决问题感兴趣。另一方面,为了评估可用性,通常连续几分钟服务不可用确实很重要,这就是为什么在评估中也考虑了软状态。
# 12.3 消息过滤器
即使您在系统范围内定义 Nagios 不仅可以通过 Web 界面和日志文件,还可以通过电子邮件和/或短信来引起对错误的注意,但在某些情况下,主机和服务定义中的过滤器参数可能会取消这些基本决定。在所有情况下,最终决定权在于为相关联系人定义的过滤器。在每个这三个级别(系统范围、主机/服务、联系人)上起作用的参数是什么,在图 12-2 中有描述。
如果一个过滤器阻止了通知,那么过滤器链就“在真空中”结束,换句话说——在层次结构中更低的过滤器选项仍然没有被考虑——Nagios 不会生成任何消息。

图 12-2. Nagios 通知系统中的过滤器序列(一些参数仅从 Nagios 版本 3.0 开始可用)
## 12.3.1 在系统范围内开启和关闭消息
在中央配置文件**`nagios.cfg`**中的**`enable_notifications`**参数,原则上可以定义 Nagios 是否应该发送消息。只有当它设置为**`1`**时,通知系统才会工作:
enable_notifications=1
## 12.3.2 启用和抑制计算机和服务相关的消息
在定义主机或服务时,各种参数可以影响消息系统。在这里,您可以定义,例如,Nagios 应该在什么时间发送消息,是否应该定期通知联系人错误状态,以及关于哪些状态或状态变化他应该被告知(仅 CRITICAL,或者 WARNING 等)。
开关**`notifications_enabled`**确定这个特定的计算机或服务是否足够重要,以至于管理员不仅应该通过 Web 界面,还应该通过其他方式被告知错误。如果是这样,该参数必须设置为**`1`**:
notifications_enabled=1
这也是默认情况,因此您必须在此处显式地将值设置为**`0`**以停止单独的通知。
### 考虑停机时间
在特定服务或主机故意不可用的时候,Nagios 当然不应该通过网络发送任何错误消息。相应的维护期配置(*停机时间安排*)只能通过 Web 界面进行,并在第 359 页的 16.3 计划停机时间中描述。
### 哪些状态和状态变化值得发送通知?
如果常规测试显示服务或计算机正在持续更改其数据,这在 Nagios 中被称为*摆动*(参见第 611 页的附录 B,第 332 页)发布确认,则不会发送通知,但如果管理员没有及时反应,那么一旦延迟期过期,Nagios 就会发送第一次通知。此选项对于避免在管理员在正常工作时间期间使用 Web 界面定期检查系统时发送不必要的通知非常有用。
### 消息是谁关注的?
在主机或服务对象中定义的联系人组本身不属于消息过滤器,但它仍然决定谁被通知,谁不被通知:
contact_group=admins
哪些联系人属于指定的组(此处:**`admins`**)是由其定义对象中的相应**`contact_group`**对象定义的(参见 2.8 消息接收者:联系人组,第 72 页):
-- /etc/nagios/global/contactgroups.cfg
define contactgroup{
contactgroup_name admins
alias administrators
members nagios,wob,mwi
}
尽管指定的联系人组仅进行粗略的预选:其中指定的哪些联系人实际上会收到消息取决于单个联系人定义中的过滤器函数。通过这种方式,你可以确保一位员工只在正常办公时间内被通知,另一位员工全天候被通知,其中一位员工需要了解所有状态变化,而另一位员工只被通知选择的一部分(例如,只有 CRITICAL 而不是 WARNING)。
## 12.3.3 与人员相关的过滤器选项
在定义**`contact`**对象时,也指定了 Nagios 在特定情况下如何发送通知的方法(参见第 275 页的 12.4 外部通知程序)。它可以分别针对主机和服务问题进行描述。还可能有几种并行方法,例如通过电子邮件**和**短信。
由于与联系人相关的过滤器专门针对相应的联系人对象,因此为同一个收件人定义几个参数不同的联系人肯定是有用的,例如一个联系人对象在正常工作时间通过电子邮件通知所有问题,另一个用于工作外时间的短信消息。
### Nagios 应该通知你什么?
应通知某人的事件不仅可以由主机或服务指定,也可以由联系人指定。在这里分别定义与主机和服务相关的状态:
host_notification_options=d,u,r
service_notification_options=c,r,u
可能的值与主机-服务参数**`notification_options`**相同(参见第 12.3.2 节的启用和抑制计算机和服务相关消息)。
从 Nagios 3.0 开始,您通常可以通过一个附加参数来切换主机和服务的通知:
host_notifications_enabled=1
service_notifications_enabled=1
值 0 阻止相应的消息,值 1 确保消息被发送。乍一看,这对应于伴随选项参数的值**`n`**(无通知)。
两个**`*_notifications_enabled`**参数也可以通过外部命令**`ENABLE/DISABLE_CONTACT_HOST_NOTIFICATIONS`**和**`ENABLE/DISABLE_C0NTACT_SVC_N0TIFICATI0NS`**^([123])来开启和关闭,这是通过外部命令接口实现的(参见第 292 页的 13.1 外部命令接口)。这可以通过一个涉及联系人的脚本完成,无需更改预设的**`*_notification_options`**。
### 消息何时到达收件人?
过滤链中的最后一个过滤器再次引用时间段。如果在此指定的时间段内产生消息,Nagios 会通知联系人;否则它会丢弃该消息。通知窗口可以分别为主机和服务的设置,并且它期望一个在别处定义的**`timeperiod`**对象作为值:
host_notification_period=24x7
service_notification_period=workhours
## 12.3.4 案例示例
### 通知一次,但可靠地完成
如果只为服务状态的每次变化发送一条消息,但这条消息必须在工作时间内始终到达相关收件人,你应该怎么做?我们可以通过将**`admins`**联系人组作为例子来说明这个问题的解决方案,该组分配了联系人**`wob`**,...
define contactgroup{
contactgroup_name admins
alias Local Site Administrators
members wob
}
...以及针对计算机**`linux01`**的**`PING`**服务:
define service{
host_name linux01
service_description PING
check_command check_ping!100.0,20%!500.0,60%
max_check_attempts 3
normal_check_interval 2
retry_check_interval 1
check_period 24x7
notification_interval 0
notification_period workhours
notification_options w,u,c,r,f
contact_groups admins
}
**`notification_interval 0`**通常强制 Nagios 不产生任何重复消息。**`notification_period`**通过**`timeperiod`**对象**`workhours`**确保所需的时间段:如果 Nagios 在其他时间发出警报,则使用内置的*重新安排*,即只有当指定的时间段再次适用时,才会发送通知。它绝对不会被丢弃。
为了使 Nagios 在所有状态变化中保持活跃,**`notification_options`**必须始终覆盖所有可能的服务事件。
为了确保联系人**`wob`**始终收到消息,重要的是在相应的**`contact`**对象中**`service_notification_period`**设置为**`24x7`**:
define contact{
contact_name wob
alias Wolfgang
host_notification_period 24x7
host_notification_options d,u,r
service_notification_period 24x7
service_notification_options w,u,c,r,f
}
在这个位置设置一个受限的时间过滤器,在特定情况下可能会导致每个单独的消息丢失。对于**`service_notification_options`**的值也是如此:只有当所有这些值都输入到这里时,才不会丢失任何消息。
### 在不同时间通知不同的管理员
如果您想在不同的时间通知不同的人关于不同的事件,您可能不能限制主机或服务的**`notification_period`**或**`notification_options`**:
define service{
...
notification_interval 120
notification_period 24x7
notification_options w,u,c,r,f
...
}
过滤仅针对单个联系人进行。为了在时间级别上使其工作,您必须确保 Nagios 在错误状态持续时定期生成消息(此处为每 120 个时间单位,通常是分钟)。
如果管理员 A 只想在工作时间内收到通知,并且只通知关键或正常状态的变化,A 的联系人对象将带有以下参数:
define contact{
...
service_notification_period workhours
service_notification_options c,r
...
}
与第一个例子相比,还有一个第二个不那么明显的变化:让我们假设该服务在早上 7:30 报告 CRITICAL 状态,这将持续几个小时。**`workhours`**对象被定义为描述周一至周五上午 8:00 至下午 18:00 的时间。在上面的例子中,Nagios 会暂时保留消息(重新安排),直到达到其中定义的时间段。因此,管理员将在 8:00 收到相应的消息。
在这里描述的情况下,不会进行重新安排,Nagios 每两小时生成一条相应的消息,如果联系人当前正在休息,则该消息会被过滤掉。系统相应地在 7:30 丢弃该消息,但允许两小时后下一条消息通过。因此,如果问题仍然存在,管理员直到 9:30 才能收到相应的信息。
两种解决方案哪一种更适合取决于具体要求。例如,对于电子邮件通知来说,管理员是否全天候接收邮件但只在办公室里阅读邮件几乎没有区别。在这种情况下,在邮件客户端中为 Nagios 消息设置过滤器,按倒序时间排序(最新的邮件排在前面)是有意义的。当问题被宣布时,管理员也可以在屏幕前快速查看 Web 界面,以检查是否有任何变化。
如果到目前为止描述的微分方法不足以解决问题,那么在 12.5 升级管理中描述的升级管理可能有所帮助。
* * *
^([123]) 查看 [`www.nagios.org/developerinfo/externalcommands/`](http://www.nagios.org/developerinfo/externalcommands/).
# 12.4 外部通知程序
哪些外部程序传递消息由联系定义确定。
这里又有两个参数用于定义要使用的命令,一个用于服务,一个用于主机:
define contact{
...
service_notification_commands notify-by-email,notify-by-sms
host_notification_commands host-notify-by-email,host-notify-by-sms
email nagios-admin@localhost
pager +49-1234-56789
address1 root@example.com
address2 123-456789
...
}
两个**`*_notification_commands`**都允许逗号分隔的列表,因此可以同时指定多个命令。然后,消息会以定义的所有方式同时发送给所有接收者。命令对象的名称描述了这些方式:通过电子邮件和通过短信。
为了获得更好的概览,相应的命令不是与文件**`checkcommands.cfg`**中的插件命令一起定义,而是在一个单独的对象文件**`misccommands.cfg`**中定义。Nagios 像加载任何其他具有对象定义的文件一样加载这些文件,这就是为什么可以为它们选择任何名称。
其他参数,**`email`**、**`pager`**、**`address1`**和**`address2`**,可以被视为变量。传递命令通过宏访问这些变量中设置的值。对于联系定义来说,**`pager`**是否包含用于短信发送的电话号码或指向电子邮件短信网关的电子邮件地址无关紧要。决定性因素是值与引用此变量的相应命令相匹配。
## 12.4.1 通过电子邮件通知
在定义**`notify-by-email`**命令时,指定一个名称和要执行的命令行,就像其他每个命令对象一样。只是它的长度不寻常,这就是为什么在这个打印版本中不得不多次换行:
define command{
command_name notify-by-email
command_line /usr/bin/printf "%b" "***** Nagios ***\n\n Notificat
ion Type: \(NOTIFICATIONTYPE\)\n\nService: \(SERVICEDESC\)\nHost: \(HOSTALIAS
\)\nAddress: \(HOSTADDRESS\)\nState: \(SERVICESTATE\)\n\nDate/Time: \(LONGDATE
TIME\)\n\nAdditional Info:\n\n\(SERVICEOUTPUT\)" | /usr/bin/mail -s " \(N
OTIFICATIONTYPE\) alert - \(HOSTALIAS\)/\(SERVICEDESC\) is \(SERVICESTATE\) **"
\(CONTACTEMAIL\)
}
打印出的命令对象来自包含的示例文件**`misccommands.cfg-sample`**。其中定义的命令行在原则上可以简化为以下模式:
printf text | mail -s "subject" e-mail_address
通过宏的帮助,**`printf`**生成消息文本,该文本通过管道传递给邮件程序。具体由哪些宏引起的情况在表 12-1 中揭示。^([124]) 使用此方法,上述长行生成类似以下的消息:
To: wob@swobspace.de
Subject: ** PROBLEM alert - mail-WOB/SMTP is CRITICAL **
Date: Fri, 14 Jan 2005 16:22:47 +0100 (CET)
From: Nagios Admin nagios@swobspace.de
***** Nagios *****
Notification Type: PROBLEM
Service: SMTP
Host: mail-WOB
Address: 172.17.168.2
State: CRITICAL
Date/Time: Fri Jan 14 16:22:47 CET 2005
Additional Info:
CRITICAL - Socket timeout after 10 seconds
表 12-1. 在通过电子邮件通知和主机通过电子邮件通知中使用的宏
| 宏 | 描述 |
| --- | --- |
| **`$CONTACTEMAIL$`** | 联系定义中**`email`**参数的值 |
| **`$LONGDATETIME$`** | 数据指定的长格式,例如,**`Fri Jan 14 16:22:47 CET 2005`** |
| **`$HOSTALIAS$`** | 主机定义中**`alias`**参数的值 |
| **`$HOSTADDRESS$`** | 主机定义中**`address`**参数的值 |
| **`$HOSTNAME$`** | 主机定义中**`host_name`**参数的值 |
| **`$HOSTOUTPUT$`** | 上次主机检查的文本输出 |
| **`$HOSTSTATE$`** | 主机状态:**`UP`**、**`DOWN`**或**`UNREACHABLE`** |
| **`$NOTIFICATIONTYPE$`** | 通知类型:**`PROBLEM`**(CRITICAL、WARNING 或 UNKNOWN),**`RECOVERY`**(错误状态后的 OK),**`ACKNOWLEDGEMENT`**(管理员已确认错误状态;见 16.1.2 对问题的负责,第 332 页),**`FLAPPINGSTART`**或**`FLAPPINGSTOP`** |
| **`$SERVICEDESC$`** | 服务定义中**`description`**参数的值 |
| **`$SERVICEOUTPUT$`** | 上次服务检查的文本输出 |
| **`$SERVICESTATE$`** | 服务状态:**`OK`**、**`WARNING`**、**`CRITICAL`**、**`UNKNOWN`** |
对于命令**`host-notify-by-email`**,命令行看起来类似,但现在使用的是与主机相关的宏:
/usr/bin/printf "%b" "***** Nagios *****\n\nNotification Type:
\(NOTIFICATIONTYPE\)\nHost: \(HOSTNAME\)\nState: \(HOSTSTATE\)\nAddress:
\(HOSTADDRESS\)\nInfo: \(HOSTOUTPUT\)\n\nDate/Time: \(LONGDATETIME\)\n" |
/usr/bin/mail -s "Host \(HOSTSTATE\) alert for \(HOSTNAME\)!" \(CONTACTEMAIL\)
它生成以下内容的电子邮件:
To: wob@swobspace.de
Subject: Host UP alert for wob-proxy!
Date: Fri, 14 Jan 2005 17:50:21 +0100 (CET)
From: Nagios Admin nagios@swobspace.de
***** Nagios *****
Notification Type: RECOVERY
Host: wob-proxy
State: UP
Address: 172.17.168.19
Info: PING OK - Packet loss = 0%, RTA = 69.10 ms
Date/Time: Fri Jan 14 17:50:21 CET 2005
## 12.4.2 通过短信通知
虽然发送电子邮件所需的基础设施通常总是可用的,但发送短信的程序,如**`yaps`**,^([125]) **`smssend`**,^([126]) 或**`smsclient`**^([127**),通常需要额外安装。**`yaps`**和**`smsclient`**需要本地调制解调器或 ISDN 卡,并直接与手机服务提供商(例如,T-Mobile)“电话”联系,**`smssend`**则建立与手机服务提供商的互联网服务器的连接,并通过此路径发送短信。使用**`yaps`**和**`smsclient`**,您还可以使用一个邮件网关,该网关从电子邮件生成并发送短信。
无论你选择哪种方法,都应该意识到在发送消息时可能存在的干扰:Nagios 服务器与互联网之间的连接要经过许多主机、路由器和防火墙。特别是如果 Nagios 本身正在监控涉及的某台计算机,事情就变得有趣了:如果这台机器宕机,那么通过**`smssend`**发送的消息将不再有效。同样适用于电子邮件-SMS 网关。无论是涉及自制的结构,使用**`yaps`**或**`smsclient`**,每个都代表自己的 SMS 网关,还是具有复杂统一消息解决方案的电信安装,如果实际发送 SMS 的节点距离 Nagios 服务器很远(例如,因为你有一个具有多个位置的联网电话系统),由于连接中断,消息无法到达目标的可能性会增加。
因此,最佳解决方案是在 Nagios 服务器本身上安装**`smsclient`**或**`yaps`**,并直接提供电话访问。在较大的、联网的电话系统中,你也可以考虑为电话访问提供从电话系统来的专用、直接线路。这里是否是 ISDN 或模拟只是所用技术的区别。
为了表示这里提到的程序,我们将更详细地研究**`smsclient`**,它可以非常简单地配置,并且在其主页上有一个活跃的社区。你还可以在那里找到一个链接到邮件列表,其成员会乐意在你有问题时提供帮助。
### 设置**`smsclient`**
虽然 Debian 有自己的预编译**`smsclient`**软件包,但对于 SuSE 和其他发行版,你必须自己编译软件。出于历史原因,程序本身被称为**`sms_client`**;在**`man sms_client`**中提供了一个简短的子文本。
从源代码安装遵循常规流程:
linux:~ # cd /usr/local/src
linux:local/src # tar xvzf /path/to/sms_client-2.x.y
linux:local/src # cd ./sms_client-2.x.y
linux:src/sms_client-2.x.y # ./configure
linux:src/sms_client-2.x.y # make && make install
这里值得提的一点是,“自制”的**`configure`**过程无需**`autoconf`**和**`automake`**。
表 12-2 中列出的配置文件现在位于目录**`/etc/sms`**;Debian 软件包将其安装到**`/etc/smsclient`**。
表 12-2. `smsclients`配置文件
| 文件 | 描述 |
| --- | --- |
| **`sms_addressbook`** | 别名和组的定义 |
| **`sms_config`** | 主要配置文件 |
| **`sms_daemons`** | **`smsclient`**守护进程模式的配置文件,其中可以通过专有协议访问。不是必需的。 |
| **`sms_modem`** | 调制解调器配置 |
| **`sms_services`** | 支持的提供商 |
文件 **`sms_services`** 列出了支持的提供商,并同时将它们分配给使用的协议。精确的拨打电话号码由目录 **`services`**(如果你自己编译)或 **`/usr/lib/smsclient/services`**(对于 Debian)中的相应服务文件指定。如有疑问,你应该请求你自己的移动蜂窝提供商的电话号码。邮件列表在这里也可能有所帮助。
在文件 **`sms_config`** 中,你设置了一个默认的提供商,程序在未指定特定提供商时将使用它进行调用:
SMS_default_service = "d1"
目前文件 **`sms_modem`** 中缺少的只是调制解调器的配置。然而,原则上,任何在 Linux 下工作的调制解调器都可以使用。以下示例中我们使用的是带有 Isdn4Linux-HiSax 驱动程序的 ISDN 卡:
MDM_lock_dir = "/var/lock" # directory for the lock files
MDM_device = "ttyI0" # device name of the modem
...
MDM_command_prefix = "AT"
MDM_init_command = "Z&E
MDM_dial_command = "D"
MDM_number_prefix = "0" # outside line, if required
...
这里使用 **`/dev/ttyI0`** 作为设备;对于 **`MDM_init_command`**,使用你自己的 MSN。这尤其适用于私人分支交换,它只允许在正确指定你自己的 MSN 时建立连接。
由于 Isdn4Linux 不识别音调或脉冲拨号,我们只使用 **`D`** 而不是通常的 **`DT`** 作为 **`MDM_dial_command`**。如果 ISDN 连接需要作为电话交换的一部分的外部线路,你应该输入相应的前缀;否则,此字符串保持为空。
**`smsclient`** 需要用于所使用的设备和日志文件 **`/var/log/smsclient.log`** 的写权限:
linux:~ # touch /var/log/smsclient.log
linux:~ # chgrp dialout /usr/bin/sms_client
linux:~ # chgrp dialout /dev/ttyI0 /var/log/smsclient.log
linux:~ # chmod 2755 /usr/bin/sms_client
linux:~ # chmod 664 /dev/ttyI0 /var/log/smsclient.log
为了测试这个,你现在应该发送——最好是作为用户 **`nagios`**(稍后将会使用 **`smsclient`**)——一条短信到你的手机(这里可以通过电话号码 **`01604711`** 接达):
nagios@linux:~$ sms_client 01604711 "Text"
Dialing SMSC 01712521002...
WARNING: read() Timeout
Connection Established.
Login...
SMSC Acknowledgment received
Login successful
Ready to receive message
Received Message Response: Message 3003123223 send successful - message
submitted for processing
Successful message submission
Disconnect...
Disconnected from SMSC
Hangup...
d1 Service Time: 17 Seconds
[000] d1:01604711 "Text"
Total Elapsed Time: 17 Seconds
### 使 Nagios 与 **`smsclient`** 协同工作
如果在 **`smsclient`** 中缺少第二个参数,即包含消息文本的参数,程序将从中读取 STDIN:
nagios@linux:~$ /bin/printf "%b" message | sms_client number
基于命令 **`notify-by-email`**,如第 276 页所述,我们在此将使用第二个变体来定义 **`notify-by-sms`** 命令:
'notify-by-sms' command definition
define command{
command_name notify-by-sms
command_line /usr/bin/printf "%.150s" "\(NOTIFICATIONTYPE\) \(HOSTNAM
E\)[\(HOSTADDRESS\)]/\(SERVICEDESC\) is \(SERVICESTATE\) /\(SHORTDATETIME\)/ \(SER
VICEOUTPUT\)" | /usr/bin/smsclient \(CONTACTPAGER\)
}
如同往常,整个 **`command_line`** 都写在一行上。Nagios 通过宏 **`$CONTACTPAGER$`** 获取电话号码(或别名),该宏从联系定义中读取 **`pager`** 参数的值。由于这里的短信可能不超过 150 个字符,我们将与电子邮件消息相比大大缩短信息。为了安全起见(你永远不知道插件输出(**`$SERVICEOUTPUT$`**)的实际长度),**`printf`** 格式说明符 **`.150`**(而不是 **`%b`**)在 150 个字符后截断文本。尽管我们通过 **`\n`** 在消息中省略了换行符,但由于其有限的显示,短信永远不会格式化得很好。因此 **`notify-by-sms`** 生成以下类型的一行消息:
PROBLEM elimail[172.17.130.1]/UPS is CRITICAL /2005-03-30 17:00:53/ Connection refused
* * *
^([124]) 所有宏的完整列表包含在原始文档中,可在[`localhost/nagios/docs/macros.html`](http://localhost/nagios/docs/macros.html)(通常在文件系统中的**`/usr/local/nagios/share/docs/macros.html`**下找到)找到。对于 Nagios 3.0,相应的文件**`macrolist.html`**也可以在这个目录中找到。
^([125]) 除了**`/usr/bin/mail`**客户端之外,还需要一个本地邮件服务器。
^([126]) **`[`www.sta.to/ftp/yaps/`](http://www.sta.to/ftp/yaps/)`**
^([127]) **`[`zekiller.skytech.org/smssend_menu_en.html`](http://zekiller.skytech.org/smssend_menu_en.html)`**
^([128]) **`[`www.smsclient.org/`](http://www.smsclient.org/)`**
# 12.5 升级管理
当重要组件失败且负责的管理员在指定时间内找不到解决方案时,尽管服务水平协议或其他合同要求 IT 部门这样做,^([129]) Nagios 升级通知的能力允许在组织层面上至少解决冲突。它可以用来提供多级支持。例如,Nagios 首先通知*第一级支持*(通常是*帮助台*)。如果问题在一天后仍然存在,那么就会通知*第二级支持*,依此类推。
Nagios 在这里也对主机和服务相关的升级阶段进行了区分。本质上,它们的功能是相同的。
在升级过程中,Nagios 不按时间单位计算,而是按已发送的消息数量计算。在以下示例中,系统应每 120 分钟报告**`linux01`**上**`Database`**服务的错误状态,^([130])并且全天候:
define service{
host_name linux01
service_description Database
notification_period 24x7
notification_interval 120
...
contact_groups admins
}
相应的消息总是发送到联系人组,因此没有升级时,就是发送到**`admins`**。

图 12-3. Nagios 根据已发送的消息数量进行升级
在第四次通知之后,Nagios 应启动升级的第一阶段(如图 12-3 所示),除了**`admins`**之外,还应通知**`second-level`**联系人组。第八条消息触发第二级,此时 Nagios 会通知**`contact_group third-level`**。
如图 12-3 所示,升级确实可以重叠。从图形中还可以看出,在服务对象中定义的联系人组仅在 Nagios 不进行升级时适用。一旦启动升级阶段,系统就会使默认联系人组失效。
如果原始联系人组——这里为**`admins`**——在第一级升级中也应收到消息,那么必须在升级定义中额外指定。如果有多个级别重叠,Nagios 将通知所有涉及的组。在图 12-3 中,第 8 到第 10 条消息相应地发送给**`admins`**和**`second-level`**以及**`third-level`**,而只有后者接收消息编号 11 和 12。从消息编号 13 开始,Nagios 只通知联系人组**`admins`**,因为此处不再定义升级。
后者通过单独的**`serviceescalation`**(用于服务)和**`hostescalation`**对象(用于计算机)来实现。对于服务升级对象,Nagios 除了服务详情(由**`service_description`**和**`host_name`**参数组成)和负责的联系人组名称之外,还要求定义异常情况开始和结束的时间:
define serviceescalation{
host_name linux01
service_description Database
first_notification 4
last_notification 10
notification_interval 60
contact_groups admins, second-level
}
在此处定义的升级级别从所需的第 4 条消息开始,并以第 10 条消息结束。如果**`last_notification`**被赋予值**`0`**,则升级仅在服务返回到 OK 状态时才结束。
此外,您还必须指定服务升级的**`notification_interval`**参数:这改变了通知间隔(根据服务定义之前为**`120`**)到**`60`**时间单位。此参数对于主机升级也是强制性的。**`hostescalation`**对象定义的唯一区别是,除了主机名称外,您还可以指定一个或多个主机组(当然,**`service_description`**参数也被删除)。
第二个升级步骤以相同的方式定义:
define serviceescalation{
host_name linux01
service_description Database
first_notification 8
last_notification 12
notification_interval 90
contact_groups third-level
}
如果存在具有不同**`notification_intervals`**的重叠升级,Nagios 将选择每种情况下定义的最小时间单位。因此,Nagios 以 60 分钟的间隔发送消息 8 到 10,以 90 分钟的间隔发送数字 11 和 12,然后再次应用原始的 120 分钟间隔。
使用**`escalation_period`**和**`escalation_options`**,有另外两个专门用于升级的设置参数。这两个参数与主机或服务定义中的**`notification_period`**和**`notification_options`**具有相同的功能,但它们仅适用于升级情况。
与**`notification_interval`**相反,**`escalation_period`** *并不替代* **`notification_period`**,而是作为其补充。从**`notification_period`**和**`escalation_period`**的交集,可以推导出实际的时间段。假设**`notification_period`**指的是早上 7:00 到下午 5:00 的时间,而**`escalation_period`**指的是上午 8:00 到下午 8:00 的时间段。那么 Nagios 将只在上午 8:00 到下午 5:00 的升级级别发送消息。你必须始终记住,只有已经发送的消息数量决定了是否存在升级级别。**`escalation_period`**和**`escalation_options`**仅作为额外的过滤器起作用。
在使用这两个参数之前,你应该仔细考虑你想通过它们实现什么。在某些情况下,将升级限制在特定时间段可能会导致它完全被省略。例如,如果你将它们限制在工作日,这意味着如果**`Database`**服务在周末失败,Nagios 只会在周一早上通知联系人组**`admins`**:周末系统已经发送了超过 12 条消息,因此它甚至不再使用其升级机制。如果通过**`escalation_period`**有时间限制,你应该将**`last_notification`**设置为**`0`**,以确保升级确实发生。
每次错误都会在某个时间点之后被恢复。一个智能机制确保 Nagios 只通知那些负责的联系人,这些联系人根据活跃的升级级别,并且也收到了要发送的最后一项通知。
* * *
^([129]) 这些也可以是内部的专业部门。
^([130]) 严格来说,每 120 个时间单位,默认时间单位是 60 秒。
# 12.6 主机和服务的依赖关系处理
如果你通过 NRPE(见第十章)使用本地插件(见第七章所示,该主机上本地安装的插件通过 NRPE 监控硬盘空间(**`Disks`**服务,见 10.5.3 优化配置)、登录用户数(**`Users`**服务)和系统负载(**`Load`**服务)。如果 NRPE 现在失败,Nagios 将宣布所有三个服务的 CRITICAL 状态,尽管它们的实际状态是未知的,而真正的问题是“NRPE 守护进程”。
为了解决这个矛盾,NRPE 作为一个独立的服务进行监控,并在**`servicedependency`**对象中描述了依赖关系。

图 12-4. 上述三个服务依赖于 NRPE
为了定义 NRPE 的附加服务检查,我们利用调用**`check_nrpe`**插件(见第十章)(几乎)没有任何参数的可能性。它将简单地返回正在使用的 NRPE 守护进程的版本:
nagios@linux:~$ /usr/local/nagios/libexec/check_nrpe -H linux01
NRPE v2.0
在第 222 页 10.5 Nagios 配置中定义的命令**`check_nrpe`**需要额外的参数,因此不能用于我们的目的。因此,我们设置了一个新的命令对象**`test_nrpe`**,它专门测试 NRPE:
define command{
command_name test_nrpe
command_line \(USER1\)/check_nrpe -H \(HOSTADDRESS\)
}
使用这种方式,现在可以定义一个**`NRPE`**服务:
define service{
host_name linux01
service_description NRPE
check_command test_nrpe
...
}
NRPE 的三个本地服务的依赖关系由以下**`servicedependency`**对象描述。
define servicedependency{
host_name linux01
service_description NRPE
dependent_host_name linux01
dependent_service_description Disks, Users, Load
notification_failure_criteria c, u
execution_failure_criteria n
}
**`host_name`**和**`service_description`**定义了主服务,其故障会导致在**`dependent_host_name`**指定的计算机上名为**`dependent_service_description`**的服务失败。所有四个参数都可以有多个条目,用逗号分隔。然而,你应该记住,每个从属服务都依赖于每个可能的主服务。
剩余的参数影响服务检查和通知:**`notification_failure_criteria`**指定对于主服务的哪些状态,涉及从属服务(例如**`Disks`**)错误的通告不应出现。可能的值是**`u`**(未知),**`w`**(警告),**`c`**(严重),**`p`**(挂起,即计划进行初始检查但尚未执行),**`o`**(正常)和**`n`**(无)。
**`u`**, **`c`** 在上述示例中意味着,如果主服务处于 CRITICAL 或 UNKNOWN 状态,Nagios 不会通知负责 "错误" 的管理员关于 **`Disks`**, **`Users`**, 和 **`Load`** 在 **`linux01`** 上的服务。如果用 **`o`** 表示 OK,逻辑可以反转:这里在没有错误的情况下没有消息,只要主服务处于 OK 状态。相应地,**`n`** 表示无论主服务状态如何,Nagios 都会提供通知。
**`execution_failure_criteria`** 参数根据主服务状态控制测试。与 **`notification_failure_criteria`** 一样,**`u`**(未知),**`w`**(警告),**`c`**(严重),**`p`**(挂起),**`o`**(正常),和 **`n`**(无),都指的是应该没有检查的主服务状态。在示例中,指定了 **`n`**,因此即使 NRPE 失败,Nagios 也会测试 **`Disks`**, **`Users`**, 和 **`Load`**。
因此,Nagios 抑制消息,但由于它仍然在依赖服务上执行服务检查,Web 界面始终显示这些服务的当前状态。
**`notification_failure_criteria`** 的详细信息与被动测试的 *Freshness 机制* 相互作用(参见第 295 页的 13.4 对被动检查过时信息的响应)。如果服务定义中使用了 **`check_freshness`**,并且 Nagios 认为最近确定的状态已过时,它将根据服务依赖关系执行主动测试,即使它应该抑制它们。
### 继承
Nagios 不自动继承依赖关系。一个例子在 图 12-5 中显示:在防火墙的内部,系统应通过 SNMP 查询各种资源。出于安全原因,测试是通过 NRPE 间接执行的,也就是说,Nagios 服务器运行安装在文件内部主机上的 SNMP 插件,间接通过 NRPE。

图 12-5. 服务的多级依赖
以下两个 **`servicedependency`** 对象描述了主机 **`linux04`** 上 **`SNMP`**(主服务)和 **`Disks`**(依赖服务)之间的依赖关系,以及 **`linux01`** 上的 **`NRPE`** 服务和 **`linux04`** 上的 **`SNMP`** 服务之间的依赖关系:
define servicedependency{
host_name linux04
service_description SNMP
dependent_host_name linux04
dependent_service_description Disks
notification_failure_criteria c, u
execution_failure_criteria c, u
}
define servicedependency{
host_name linux01
service_description NRPE
dependent_host_name linux04
dependent_service_description SNMP
notification_failure_criteria c, u
execution_failure_criteria c, u
}
如果 **`linux01`** 上的 NRPE 守护进程失败,Nagios 只会识别 **`NRPE`** 和 **`SNMP`** 之间的定义依赖关系,但不会识别 **`NRPE`** 和 **`Disks`** 之间的隐式依赖关系。为了考虑这些依赖关系,在 **`Disks`** 和 **`SNMP`** 之间的服务依赖关系定义中插入参数 **`inherits_parent`**。
inherits_parent 1
通过这种方式,Nagios 检查主服务本身(此处为 **`SNMP`**)是否依赖于另一个服务,这得益于相应的 **`servicedependency`**。如果 **`linux01`** 上的 **`NRPE`** 服务失败(CRITICAL 状态),Nagios 将省略对 **`linux04`** 上的 **`Disks`** 的检查,归功于 **`execution_failure_criteria c, u`**,并且也不会发送任何关于最近检测到的 **`Disks`** 状态的通知。
### 其他应用案例
如果大量依赖单一服务,服务之间的依赖定义尤其有用,这样实际问题可能会在错误消息的洪流中消失。除了与 NRPE 结合使用之外,这也适用于 Nagios 服务器无法直接测试的所有服务,并且它必须使用工具(NRPE、SNMP 或甚至 **`NSCLIENT`** 用于 Windows,见 20.2.1 NSClient)。如果无法建立到实用程序的简单连接并且无法查询常量值(版本号、系统名称),您仍然可以使用通用插件来访问相应的端口。
使用服务依赖性的另一个例子是依赖于数据库的应用程序:如果一个具有动态网页的 Web 应用程序(其基础数据库可能位于网络中的另一个主机上)无法工作,那么该 Web 应用程序将失败。数据库服务与动态 Web 应用程序之间精确定义的依赖性也确保了管理员会被告知实际原因。
### Nagios 3.0 的附加功能
Nagios 3.0 包含两项创新:一方面,参数 **`dependency_period`** 现在允许对依赖性施加时间限制。默认值为 **`7x24h`**,即全天候。
另一方面,Nagios 3.0 使得在同一主机上定义服务和依赖服务的依赖性变得更加容易。如果 **`dependent_host_name`** 与 **`host_name`** 相同,则可以省略在前面示例中使用的指定。这种所谓的 *同一主机依赖性* 的一个例子在 H.1.6 依赖描述 页 683 中描述。
## 12.6.2 仅在异常情况下:主机依赖性
主机依赖性在原则上与服务依赖性完全相同;**`hostdependency`** 对象也能够抑制消息。
然而,在细节上存在一些细微的差异。只有显式配置的常规主机检查可以被抑制,其中检查间隔被定义为与服务相同。然而,这种类型的主机检查应仅在特殊情况下使用,因为它可能会对 Nagios 的性能产生重大影响。通常,Nagios 会自行决定何时执行主机检查(参见第 92 页的 4.1 考虑网络拓扑)。
在几乎所有情况下,主机定义中的**`parents`**参数在描述主机之间的依赖关系方面表现得更好。只要 Nagios 可以直接测试单个主机,系统就能更好地区分 DOWN 和 UNREACHABLE(参见第 92 页的 4.1 考虑网络拓扑)。如果您不希望对特定主机进行任何通知,这取决于网络拓扑,那么您只应收到 DOWN 的通知,而不是 UNREACHABLE 的通知。
只有当 Nagios 无法再区分 DOWN 和 UNREACHABLE 时,才应使用主机依赖。这通常是在间接检查(例如,在 10.5.3 优化配置中显示的图中)执行主机检查时的情况。
# 第十三章. 使用外部命令文件进行被动测试
除了主动服务和主机检查之外,Nagios 还利用被动测试(以及这两种类型测试的组合)。虽然系统本身定义了主动检查执行的时间,并随后启动它们,但在被动模式下,Nagios 仅处理传入的结果。
为了实现这一点,需要一个接口,允许将外部测试结果传递给 Nagios,以及执行检查并通过接口提供结果的命令。通常,远程主机通过*Nagios 服务检查接受器*(NSCA)发送由 shell 脚本确定的测试结果,如下一章(第十四章)中所述,到 Nagios 服务器。
被动检查在分布式监控中尤其有用,其中非中心化的 Nagios 服务器将所有结果发送到中央 Nagios 实例。这一主题在第十五章中有详细讨论。它们还用于处理异步事件,这些事件的时间 Nagios 无法自行定义。一个例子是备份脚本在完成数据备份后向 Nagios 发送结果(OK 或 CRITICAL),另一个例子是处理 SNMP 陷阱(参见 14.6 应用示例 II:处理 SNMP 陷阱)。
# 13.1 外部命令的接口
外部命令的接口,在 Nagios 术语中称为*外部命令文件*,由 Nagios **`var`**目录下的子目录**`rw`**中的命名管道(FIFO)组成。131]
user@linux:~$ ls -lF /var/nagios/rw
prw-rw---- 1 nagios nagcmd 0 Dec 19 10:56 nagios.cmd|
在**`ls`**输出中用**`p`**标记的管道,在安装过程中正确设置了**`make install-commandmode`**命令。出于安全考虑,确保只有组**`nagcmd`**可以读取和写入管道是至关重要的。任何有权访问这里的人都可以通过命令远程控制 Nagios,并且如果他们想的话,可以完全关闭它。
Nagios 从外部命令文件接受的命令具有以下形式:
[timestamp] command;arguments
正如方括号中的时间戳所示,Nagios 期望的是以纪元秒为单位的当前时间,即自 1970 年 1 月 1 日以来在 UTC 时区中经过的秒数。其后跟一个空格,然后是一个命令,后面跟着匹配数量的参数,由分号分隔。
该接口广泛使用这种机制,允许用户通过鼠标点击进行各种设置。在线文档提供了所有可能命令的详细描述。132]。每个命令的示例脚本都可以在那里找到,可以复制到文件中并通过剪切粘贴使用,之后进行一些路径调整。
在本章中,我们将仅限于两种处理命令,即计算机将被动检查的结果传递给 Nagios 服务器的命令,**`PROCESS_SERVICE_CHECK_RESULT`**和**`PROCESS_HOST_CHECK_RESULT`**。
出于安全考虑,必须在主配置文件**`nagios.cfg`**中使用指令**`check_external_commands=1`**显式地打开外部命令的处理:
/etc/nagios/nagios.cfg
...
check_external_commands=1
command_check_interval=-1
command_file=/var/nagios/rw/nagios.cmd
...
**`command_check_interval`**确定 Nagios 每隔几秒钟检查一次现有命令的接口。**`−1`**表示“尽可能频繁”。**`command_file`**指定命名管道的路径。
* * *
^([131]) 命名管道是一个进程可以写入数据的缓冲区,然后另一个进程可以读取这些数据。最先写入的数据也是最先被读取的:*先进先出*(FIFO)。由于这涉及到主内存中的空间,命名管道不需要在硬盘上占用任何空间。
^([132]) [`www.nagios.org/developerinfo/externalcommands/`](http://www.nagios.org/developerinfo/externalcommands/)
# 13.2 被动服务检查
为了使 Nagios 能够通过接口接受被动服务检查,必须在全局配置和相应的服务定义中明确允许。在**`nagios.cfg`**中的对应条目是
/etc/nagios/nagios.cfg
...
accept_passive_service_checks=1
...
在服务定义中,你可以选择是否要在被动检查的同时执行主动检查。当然,只有在 Nagios 能够自己查询信息的情况下,才能执行主动检查。以下示例允许被动检查并停止所有主动检查:
define service{
host_name linux01
service_description Disks
passive_checks_enabled 1
active_checks_enabled 0
check_command check_dummy
check_period none
...
}
通常会对*新鲜度检查*(见 13.4 对被动检查过时信息的反应,第 295 页)进行例外处理——在这里,Nagios 使用在**`check_command`**中定义的命令。要完全禁止主动检查,将**`check_period`**参数设置为**`none`**。在这种情况下,检查命令不起作用,因此你可以在这里输入一个虚拟检查,例如(当然,像所有其他命令一样,必须定义)。
在要被动测试的计算机(在这个例子中,**`linux01`**)上,你必须通过 NSCA(见第十四章)确保它通过外部命令接口联系 Nagios 服务器。在那里,它以下一行形式写入被动服务检查的命令:
[timestamp] PROCESS_SERVICE_CHECK_RESULT; host-name;service;
return value; plugin output
时间戳可以在 shell 脚本中创建,例如使用**`date`**:
user@linux:~$ date +%s
1112435763
一个简单的脚本,可以将 Nagios 服务器上被动服务检查的结果传递给安装在该服务器上的 Nagios,可能看起来像这样:
!/bin/bash
EXTCMDFILE="/var/nagios/rw/nagios.cmd"
TIME='date +%s'
HOST=$1
SRV=$2
RESULT=$3
OUTPUT=\(4
CMD="[\)TIME] PROCESS_SERVICE_CHECK_RESULT;\(HOST;\)SRV;\(RESULT;\)OUTPUT"
/bin/echo $CMD >> $EXTCMDFILE
当它运行时,它期望参数以正确的顺序出现:
name_of_script linux01 Disks 0 'Disks ok: everything in order 😃'
在主机名和服务名之后,测试状态以数字形式跟随,最后是输出文本。如果服务名包含空格,那么它也应该用引号括起来。
# 13.3 被动主机检查
被动主机检查遵循与被动服务检查相同的原理,只是它们涉及的是计算机而不是服务。要全局允许它们,必须在**`nagios.cfg`**中将**`accept_passive_host_checks`**参数设置为 1:
/etc/nagios/nagios.cfg
...
accept_passive_host_checks=1
...
此外,要被动监控的计算机的主机定义必须允许这种主机检查:
define host{
host_name linux01
passive_checks_enabled 1
active_checks_enabled 0
check_period none
check_command check_dummy
...
}
在这个例子中,它同时禁止了主动检查。
通过外部接口发送的命令,该计算机通过该接口提供其测试结果,与已经介绍的服务检查命令的语法只有细微差别:
[timestamp] PROCESS_HOST_CHECK_RESULT;hostname;return value; plugin output
激活和被动主机检查在一点上有所不同:在被动检查中,Nagios 不再能够区分 DOWN 和 UNREACHABLE(参见第 92 页的 4.1 考虑网络拓扑)。如果你仍然想在发出通知时考虑网络拓扑依赖性,并给出实际已关闭的主机的具体信息,你必须在这种情况下使用主机依赖性(参见第 289 页的 12.6.2 仅在异常情况下:主机依赖性)。
# 13.4 对被动检查过时信息的反应
被动检查的本质在于 Nagios 对提供的信息感到满意。Nagios 无法控制远程主机何时以及以何种间隔提供这些信息。甚至可能发生信息根本未到达的情况。
为了将服务器的“知识状态”分类为过时,Nagios 具有通过*freshness 检查*自行变得活跃的能力。与被动检查一样,freshness 检查必须在全局范围内以及相关的服务主机对象中启用。为此,你需要在文件**`nagios.cfg`**中设置以下全局参数:
/etc/nagios/nagios.cfg
...
check_service_freshness=1
service_freshness_check_interval=60
check_host_freshness=0
host_freshness_check_interval=60
...
**`check_host_freshness`**中的值**`0`**和**`check_service_freshness`**中的值**`1`**确保 Nagios 只为服务执行 freshness 检查,而不是为主机。检查间隔定义了服务器更新其信息的间隔,在这种情况下,每 60 秒更新一次。Nagios 在特定服务或主机的情况下真正变得活跃取决于阈值值,你可以使用**`freshness_threshold`**参数在适当的服务或主机定义中设置此值:^([133])
define service{
host_name linux01
service_description Disks
passive_checks_enabled 1
active_checks_enabled 0
check_freshness 1
freshness_threshold 3600
check_command service_is_stale
...
}
因此,在这个例子中,Nagios 只有在最后传输的值超过 3600 秒(一小时)时才会执行此服务的 freshness 检查。然后 Nagios 启动在**`check_command`**中定义的命令,即使相应的主机或服务定义中已关闭主动检查,或者甚至在全局范围内也是如此。
如果你定义了示例中提到的命令,即**`service_is_stale`**,以便 Nagios 真正检查服务或主机,那么即使主动检查被关闭,Nagios 也会执行主动测试,但始终仅在被动结果超过阈值值设置的时间更长时。
如果无法进行或不需要主动检查,您可以使用伪测试来确保 Nagios 会明确地显示错误状态,从而引起管理员的注意。否则,Nagios 将始终显示最后接收到的状态。如果这是正常的,那么可能不会注意到当前结果已经有一段时间没有到达。以下伪测试脚本使用**`echo`**提供适当的错误信息,并通过**`exit 2`**提供 CRITICAL 的返回值,以便管理员可以相应地做出反应:
!/bin/bash
/bin/echo "CRITICAL: no current results of the service"
exit 2
如果您从插件目录中以**`service_is_stale.sh`**启动脚本,Nagios 命令**`service_is_stale`**将被定义为以下内容:
define command{
command_name service_is_stale
command_line \(USER1\)/service_is_stale.sh
}
如果**`linux01`**上的**`Disks`**服务的结果超过一小时没有出现,Nagios 将运行脚本**`service_is_stale.sh`**,该脚本始终返回 CRITICAL,无论**`linux01`**最后发送了什么数据。只有当主机通过被动检查向服务器传递新的更积极的结果时,这种 CRITICAL 状态才会结束。
* * *
^([133]) 如果您没有明确指定**`freshness_threshold`**,则硬状态将使用为**`normal_check_interval`**设置的值,如果存在软状态,则**`retry_check_interval`**的值将作为默认值。
# 第十四章. Nagios 服务检查接受者(NSCA)
为了将服务和主机检查通过网络发送到中央 Nagios 服务器,需要一个传输机制。这由**Nagios 服务检查接受者**(NSCA)提供。它由两个组件组成:一个客户端程序**`send_nsca`**,它接受远程主机上的服务或主机检查结果并将它们发送到 Nagios 服务器,以及运行在服务器上的 NSCA 守护进程**`nsca`**,它接收来自客户端的数据,为此外部命令文件接口(参见 13.1 外部命令接口)。
Nagios 服务检查接受者最初开发是为了实现分布式监控,其中分散的 Nagios 服务器可以将它们的检测结果发送到中央 Nagios 服务器(参见第十五章分布式监控,第 317 页)。原则上,**`send_nsca`**发送给 Nagios 服务器的数据可以来自您喜欢的任何应用程序。
在网络安全方面,通过网络发送命令到中央 Nagios 实例并非微不足道,因为可以使用外部命令文件完全关闭 Nagios。这就是为什么 NSCA 以加密形式发送数据,客户端必须拥有正确的密钥才能访问接口。这阻止了任意网络参与者能够运行任何命令在 Nagios 服务器上。

图 14-1. NSCA 的功能
# 14.1 安装
NSCA 版本 2.7.2,在本书印刷时,是在 2007 年春季发布的;因此,你使用的发行版很可能包含一个当前包。然而,源代码^([134])编译起来相当简单。作为先决条件,你需要安装库**`libmcrypt`**以及相关的头文件^([135)),否则无法使用集成加密。
在解压后的源代码目录中,你应该运行包含的**`configure`**脚本,指定 Nagios 配置和**`var`**目录:
linux:local/src # tar xvzf/path/to/nsca-2.7.2.tar.gz
...
linux:local/src # cd nsca-2.7.2
linux:src/nsca-2.7.2 # *./configure --sysconfdir=/etc/nagios *
--localstatedir=/var/nagios
...
******* Configuration summary for nsca 2.7.2 07-03-2007 *******:
General Options:
NSCA port: 5667
NSCA user: nagios
NSCA group: nagios
...
最后它会显示输出,显示 NSCA 用户默认启动时的权限,如果没有在配置中指定其他权限。通常 NSCA 守护进程在 TCP 端口 5667 上等待。
最后执行**`make all`**编译两个程序**`nsca`**和**`send_nsca`**。它们现在位于子目录**`src`**中,需要手动复制到合适的目录:
linux:src/nsca-2.7.2 # cp src/nsca /usr/local/sbin/.
linux:src/nsca-2.7.2 # scp src/send_nsca remote host: /usr/local/bin/.
**`nsca`**被复制到 Nagios 服务器,最好复制到目录**`/usr/local/ sbin`**。**`send_nsca`**应该位于将测试结果发送到 Nagios 服务器的远程主机上。如果这台计算机有不同的操作系统版本或平台,那么运行在那里的客户端可能需要重新编译。这两个程序各自都需要自己的配置文件,最好存储在目录**`/etc/nagios`**中。
linux:src/nsca-2.7.2 # cp nsca.cfg /etc/nagios/.
linux:src/nsca-2.7.2 # scp send_nsca.cfg remote_host: /etc/nagios/.
* * *
^([134]) [`www.nagios.org/download/`](http://www.nagios.org/download/)
^([135]) 相应的二进制包通常在其名称中包含**`-dev`**或**`-devel`**。
# 14.2 配置 Nagios 服务器
## 14.2.1 配置文件**`nsca.cfg`**
为了 NSCA 能够工作,Nagios 服务器上的外部命令文件接口必须在配置文件**`/etc/nagios/nagios.cfg`**中激活(13.1 外部命令接口, 第 292 页)并且相应的数据在 NSCA 配置文件**`nsca.cfg`**中输入。
/etc/nagios/nsca.cfg
server_port=5667
server_address=192.168.1.1
allowed_hosts=127.0.0.1
nsca_user=nagios
nsca_group=nagios
debug=0
command_file=/var/nagios/rw/nagios.cmd
alternate_dump_file=/var/nagios/rw/nsca.dump
aggregate_writes=0
append_to_file=0
max_packet_age=30
password=verysecret
decryption_method=10
参数 **`server_port`**、**`server_address`**、**`allowed_hosts`**、**`nsca_user`** 和 **`nsca_group`** 仅在 **`nsca`** 以守护进程方式启动时生效。如果以 inet 守护进程启动,则其配置文件中设置的值应用于 NSCA 服务器地址和 NSCA 监听的端口,允许访问该接口的主机的 IP 地址,以及运行 Service Check Acceptor 的用户和组权限。
**`debug`** 参数使得查找错误更加容易,但通常应关闭(值 **`0`**)。如果设置为 **`1`**,NSCA 将将调试信息写入 syslog。
命名管道由条目 **`command_file`** 定义。如果你指定了替代输出文件,使用 **`alternate_dump_file`**,则在指定的命名管道不存在时,它作为后备。在版本 2.0 之前,Nagios 每次关闭时都会删除管道,但这种情况不应再发生。
如果设置为 **`1`**,**`aggregate_writes`** 确保 NSCA 只收集一次所有传入的命令,然后将这些命令作为块传递给接口。如果此位置的值是 **`0`**,则 NSCA 会立即将每个传入的命令发送到外部命令文件。
**`append_to_file`** 可以是值 **`0`**(以写入模式打开外部命令文件)或 **`1`**(以追加模式打开),并且应始终设置为 **`0`**。^([137])
NSCA 会丢弃超过 **`max_packet_age`** 秒的客户端消息,以避免重放攻击。此值不应超过 900 秒(15 分钟),并且应尽可能小。
最后两个参数涉及通信的加密。**`password`** 包含实际密钥,对于客户端来说是相同的,并且必须在客户端的配置中输入(参见第 304 页的 14.3 客户端配置)。因为密钥以明文形式写入文件,所以 **`nsca.cfg`** 应仅对运行 NSCA 的用户可读,在我们的例子中是 **`nagios:`**。
linux:/etc/nagios # chown nagios.nagios nsca.cfg
linux:/etc/nagios # chmod 400 nsca.cfg
最后,**`decryption_method`** 定义了加密算法。默认值为 **`1`**(XOR),与 **`0`**(无加密)几乎一样不安全。**`10`** 代表 LOKI97,被认为是安全的。所有可能的算法列表包含在提供的配置文件中,其中包含许多旧算法和一些较新的算法,如 DES(**`2`**)、Triple-DES(**`3`**)、Blowfish(**`8`**)和 Rijndael(AES)。
## 14.2.2 配置 inet 守护进程
如果你想使用 inet 守护进程启动 **`nsca`**,则需要在文件 **`/etc/services:`** 中添加以下条目。
nsca 5667/tcp # Nagios Service Check Acceptor (NSCA)
### **`xinetd`** 配置
如果使用较新的 **`xinetd`**,则将在 **`/etc/xinetd.d`** 目录中创建 **`nagios-nsca`** 文件,内容如下:
/etc/xinetd.d/nsca
description: NSCA
default: on
service nsca
{
flags = REUSE
socket_type = stream
wait = no
user = nagios
group = nagios
server = /usr/local/sbin/nsca
server_args = -c /etc/nagios/nsca.cfg --inetd
log_on_failure += USERID
disable = no
only_from = 127.0.0.1 ip1 ip2... ipn
}
对于用户和组,以它们的权限运行 NSCA,以及 NSCA 守护进程 **`nsca`**(参数 **`server`**) 和相应的配置文件路径,以粗体打印的值,如有必要,调整到您自己的环境。行 **`only_from`**,作为 **`nsca.cfg`** 参数 **`allowed_hosts`** 的等效,接受来自所有 IP 地址的空间分隔值,这些地址可以用来调用 NSCA。包含 NSCA 作为完整包并默认安装 **`xinetd`** 的发行版,包括一个可用的 **`xinetd`** 配置文件,您只需调整最后一个参数。
为了使新的配置生效,需要使用 **`reload`** 参数运行 **`xinetd`** 初始化脚本:
linux:~ # /etc/init.d/xinetd reload
### inetd 配置
如果运行标准 **`inetd`** 命令,配置文件 **`/etc/inetd.conf:`** 中将添加以下行(为了打印版本而进行了换行):
nsca stream tcp nowait nagios /usr/sbin/tcpd
/usr/local/sbin/nsca -c /etc/nagios/nsca.cfg --inetd
如果您想省略 TCP 包装器 **`tcpd`**,只需省略字符串 **`/usr/sbin/tcpd`**。在这种情况下,您还必须明确指定 NSCA 启动时使用的用户(**`nagios`**)、二进制的完整路径 **`nsca`** 和配置文件的绝对路径。以便网络守护进程能够考虑到修改,其配置必须重新加载:
linux:~ # /etc/init.d/inetd reload
* * *
^([136]) 如果要为 **`allowed_hosts`** 定义多个 IP 地址,它们之间用逗号分隔。
^([137]) 仅当外部命令文件用于调试目的替换为简单文件时,追加模式才有意义。
^([138]) [`en.wikipedia.org/wiki/L0KI97`](http://en.wikipedia.org/wiki/L0KI97)
^([139]) Rijndael-128: **`14`**; Rijndael-192: **`15`**; Rijndael-256: **`16`**
# 14.3 客户端配置
客户端侧的配置文件 **`send_nsca.cfg`** 必须包含与 Nagios 服务器上的文件相同的加密参数:
password=verysecret
decryption_method=10
由于密钥也以纯文本形式写入此处,因此它不应被任何用户读取。因此,最好在客户端创建一个用户 **`nagios`** 和一个组 **`nagios`**:
linux:~ # groupadd -g 9000 nagios
linux:~ # useradd -u 9000 -g nagios -d /usr/local/nagios
-c "Nagios Admin" nagios
您现在应该保护文件 **`send_nsca.cfg`**,以确保只有用户 **`nagios`** 可以读取它,并确保使用 SUID 机制,程序 **`send_nsca`** 总是以此用户的用户 ID 运行。如果您现在授予组 **`nagios`** 执行权限,只有其成员可以执行 NSCA 客户端程序:
linux:~ # chown nagios.nagios /etc/nagios/send_nsca.cfg
linux:~ # chown nagios.nagios /usr/bin/send_nsca
linux:~ # chmod 400 /etc/nagios/send_nsca.cfg
linux:~ # chmod 4710 /usr/bin/send_nsca
linux:~ # ls -l /usr/bin/send_nsca
-rws--x--- 1 nagios nagios 83187 Apr 2 17:56 /usr/local/bin/send_nsca
# 14.4 将测试结果发送到服务器
客户端程序 **`send_nsca`** 从标准输入读取主机或服务检查的详细信息,管理员必须按以下格式格式化:^([140])
host-name\tservice\treturn value\toutput
host-name\treturn value\toutput
**`send_nsca`**将此发送到 Nagios 服务器。第一行描述了服务检查的格式,第二行描述了主机检查的格式。占位符**``*`返回值`*``**被替换为确定的状态,即**`0`**表示 OK,**`1`**表示 WARNING,**`2`**表示 CRITICAL,**`3`**表示 UNKNOWN。**``*`输出`*``**指的是一行文本,是插件为管理员提供的支持类型。作为分隔符,使用制表符(**`\t`**)。
为了使这个命令能够被外部命令理解,NSCA 守护进程首先在时间戳和匹配的命令(**`PROCESS_SERVICE_CHECK_RESULT`** 或 **`PROCESS.HOST_CHECK_RESULT`**)前加上前缀。这就是为什么只有这两个命令可以使用 NSCA 发送。
**`send_nsca`**本身有以下选项:
**`-H`** **``*`地址`*``**
这是 NSCA 将要联系的目标 Nagios 服务器的计算机名或 IP 地址。
**`-d`** **``*`分隔符`*``**
这是输入的分隔符;默认为制表符。以下示例页面使用分号作为*分隔符*。
**`-c`** **``*`配置文件路径`*``**
此参数指定配置文件**`send_nsca.cfg`**的路径。由于没有路径被编译到客户端中,**`send_nsca`**默认期望在当前目录中找到该文件。因此,使用此选项指定绝对路径是有意义的。
**`-p`** **``*`端口`*``**
这定义了一个替代端口,如果默认的 TCP 端口 5667 没有被使用。
**`-to`** **``*`超时`*``**
在**``*`超时`*``**秒(默认为**`10`**)后,如果未建立连接,**`send_nsca`**将终止连接尝试到 NSCA 守护进程。
通过以下简单的测试脚本,可以测试 NSCA 的功能。选择一个状态不是未知(例如,OK)的服务作为测试对象,在这个例子中,是主机**`linux0l:`**上的**`nmbd`**。
!/bin/bash
CFG="/etc/nagios/send_nsca.cfg"
CMD="linux01;nmbd;3;UNKNOWN - just one NSCA test"
/bin/echo $CMD | /usr/local/bin/send_nsca -H nagios -d ';' -c $CFG
脚本将其从 Nagios 的角度看,置于未知状态。运行之后,你应该发现传输是否成功:
nagios@linux:~$ bash./test_nsca
1 data packet(s) sent to host successfully.
一旦 Nagios 处理了这个命令,并且你在浏览器中重新加载了页面,Web 界面就会显示所选服务的未知状态。在下一个活跃的检查之后,之前的状态将会恢复。
由于使用**`send_nsca`**发送 Nagios 检查结果非常简单,因此保护 NSCA 不被滥用至关重要,正如已经展示的那样。在客户端,你应该限制对客户端程序**`send_nsca`**及其配置文件的访问,并确保你有安全的加密,在服务器上明确定义允许的发送者和 IP 地址。
* * *
^([140]) 通常你必须确保你自己编写的测试脚本产生正确的输出;如果你使用 Nagios 插件,你必须相应地重新格式化它们的输出。由于后者可以直接通过 NRPE 运行得更好,这应该成为规则的例外。
# 14.5 应用示例 I:集成 syslog 和 Nagios
Linux 和 Unix 系统通常通过 syslog 记录系统相关的事件。迟早你可能会希望 Nagios 也通知管理员重要的 syslog 事件。为此,你需要被动服务检查、NSCA 用于将结果传输到 Nagios 服务器,以及过滤单个块条目的方法。
如果你使用的是 **`syslog-ng`**^([141]) 而不是标准的 BSD syslog,你可以利用其设置过滤器和使用模板格式化输出的能力。使用 NSCA 可以弥补程序本身无法以加密形式传输数据的事实。
除了与 Nagios 的连接外,还有评估日志文件的程序来补充,例如 **`logcheck`**^([142]),它几乎包含在每一个 Linux 发行版中,但它并不能取代它们。这是因为 Nagios 可以为每个事件发送单独的电子邮件,但不能像 **`logcheck`** 那样发送事件摘要(通常每小时一次)。此外,Web 界面总是显示每个情况下的最后事件。
## 14.5.1 为使用 Nagios 准备 **`syslog-ng`**
除了源代码外,**`syslog-ng`** 的主页^([143]) 还提供了一份详细的手册,因此我们在此仅讨论基本原理。该软件区分了 **`source`**、**`filter`** 和 **`destination`**。所有三个对象可以以任何形式组合;它们在配置文件 **`/etc/syslog-ng/syslog-ng.conf:`** 中定义。
/etc/syslog-ng/syslog-ng.conf
source local {
unix-stream("/dev/log");
internal();
file("/proc/kmsg" log_prefix("kernel: "));
};
destination console_10 {
file("/dev/tty10");
};
filter f_messages {
not facility(auth, authpriv) and
level(info.. alert);
};
log {
source(local);
filter(f_messages);
destination(console_10);
};
此示例同时定义了三个源:**`unix-stream`** 从套接字 **`/dev/log`** 读取,这是大多数程序将消息发送到 syslog 的方式。**`internal`** 是 **`syslog-ng`** 提供内部消息的源名称,以及从文件 **`/proc/kmsg`** 接收 **`kernel`** 消息。这些消息带有 **`kernel:`** 前缀,以便它们可以与正常日志条目区分开来。
**`destination`** 定义确保所有 syslog 输出都显示在控制台 **`ttyl0`** 上(这可以通过 -)。
**`filter`** 定义了哪些消息应该到达这个目的地,如果有。在 **`f_messages`** 过滤器的情况下,这是所有匹配类别(**`level`**)**`info`** 的消息,并且 syslog 没有提供带有戳记(**`facility`**;参见 **`man syslog.conf`** 和 **`man 3 syslog`**)**`auth`** 或 **`authpriv`** 的消息。或者 **`syslog-ng`** 可以根据搜索模式进行过滤,使用指令 **`match`** (**``"*`pattern`*"``**),根据记录日志的程序(**`program`**(**``"*`program name`*"``**))和根据源主机(**`host`**(**``"*`hostname`*"``**))。
最后,关键字 **`log`** 将源、过滤器和目的地链接起来。这里可以指定多个配置,因此可以在单个语句中指定多个源和目的地:
log {
source1); source2;...
filter1; filter2;...
destination1; destination2;...
}
如果你在一个 **`log`** 语句中指定了多个过滤器,**`syslog-ng`** 只允许通过匹配所有过滤条件的数据(AND 链接)。
要将此集成到 Nagios 中,使用定义程序作为目标的选项,该目标会在每个事件上被调用:
destination d_nagios_warn {
program("/usr/local/nagios/misc/send_syslog.sh"
template("$HOST;syslog-ng;1;WARNING: $MSG\n") template_escape(no));
};
destination d_nagios_crit {
program("/usr/local/nagios/misc/send_syslog.sh"
template("$HOST;syslog-ng;2;CRITICAL: $MSG\n") template_escape(no));
};
**`template`** 指令格式化输出,使其适合用于 **`send_nsca`**,使用分号作为分隔符:主机和服务名称(**`syslog-ng`**)后面跟着状态(**`1`** = 警告;**`2`** = 严重),然后是实际输出文本。除了 **`$H0ST`** 和 **`$MSG`**,**`syslog-ng`** 还有一系列其他宏,这些宏在主页上的文档中分别进行了描述。参数 **`template_escape`** 用于保护文本中的引号,主要用于 SQL 命令,因此在这种情况下可以将其设置为 **`no`**。
以下脚本 **`send_syslog.sh`** 使用 bash 函数 **`read`** 逐行读取标准输入,对于每行读取的内容,它调用 **`send_nsca`**,将数据作为被动测试结果发送到 Nagios(如本章所述):
!/bin/bash
while read -r line; do
echo $line | /usr/bin/send_nsca -H nagsrv -d ';'
-c /etc/nagios/send_nsca.cfg
1>/usr/local/nagios/var/send_syslog.log 2>&1
done
由于使用了分号作为分隔符,我们使用选项 **`-d`** 明确指定这一点。每个 **`send_nsca`** 命令在标准输出上显示的状态报告被脚本重定向到单独的日志文件(**`/usr/local/nagios/var/send_syslog.log`**)。
由于 syslog 配置中的 **`program`** 指令,**`syslog-ng`** 会自动启动脚本。这也是 **`send_nsca`** 命令处于无限循环中的原因:这意味着每次有相关事件时,**`syslog-ng`** 都不会运行外部程序。
## 14.5.2 Nagios 配置:易变服务
在 Nagios 术语中,“volatile”指的是只显示一次错误状态的服务。这适用于例如在查询错误时自动重置状态的设备——这意味着错误无法重现。同样适用于 syslog 条目:如果跟随错误状态检查返回错误,这始终是第二个事件。因此,这里没有持续错误状态,而是一个再次发生的问题。
对于持续错误状态,Nagios 通常在将问题状态分类为硬状态之前不会发送任何进一步的消息。然而,有了**`is_volatile`**参数,它将每个错误都视为刚刚发生。Nagios 记录状态,发送通知,并实现事件处理器——如果已定义的话——(见第 619 页的附录 C
图 14-2. `syslog-ng`服务处于错误状态
此问题可以通过 Web 界面解决,该界面允许手动生成被动检查结果。
如果您点击图 14-2 中的服务名称,将显示扩展状态信息(图 14-3
图 14-3. 箭头指向生成`syslog-ng`服务的被动测试结果的可能性
当然,您也可以为每个 syslog 事件定义自己的服务。这有时可能相当耗时,但它确实允许您在 Web 界面中分离各种消息及其处理状态。如果**`syslog-ng`**中的过滤器限制为 syslog 服务对象始终只引用一个要监控的资源,您也可以省略**`is_volatile`**参数。

图 14-4. 创建被动检查结果 `syslog-ng`
* * *
^([141]) 中的“ng”代表*下一代*。
^([142]) [`sourceforge.net/projects/logcheck/`](http://sourceforge.net/projects/logcheck/)
^([143]) [`www.balabit.com/products/syslog_ng/`](http://www.balabit.com/products/syslog_ng/)
# 14.6 应用示例 II:处理 SNMP 陷阱
由 SNMP 代理(见 11.1 SNMP 简介)。
## 14.6.1 使用**`snmptrapd`**接收陷阱
为了接收 SNMP 陷阱,你需要一个特殊的 Unix/Linux 守护进程,它从它们生成消息供 Nagios 使用。软件包 NET-SNMP,在 11.2.2 NET-SNMP 守护进程中描述,包括守护进程**`snmptrapd`**。
在以下场景中,**`snmptrapd`**安装在第三台主机上(既不是生成陷阱的计算机,也不是 Nagios 服务器)。它通过脚本评估接收到的信息,并将其通过 NSCA 转发到 Nagios 服务器。145]
在**`snmptrapd`**配置文件**`/etc/snmp/snmptrapd.conf`**中,每个陷阱类型都有一个单独的条目,其语法对应于以下行之一:
traphandle oid program
traphandle oid program arguments
traphandle default program
traphandle default program arguments
关键字**`traphandle`**后面跟的是所需陷阱的对象标识符,或者跟关键字**`default`**。在后一种情况下,条目适用于所有没有自己的配置条目的陷阱。最后,指定了在接收到相关陷阱时应运行的程序。
此外,你还可以包括与此程序一起使用的参数。但在此过程中必须小心。引号由**`snmptrapd`**作为字符传递,而空格始终用作分隔符。这意味着你不能传递包含空格的任何参数,这在分配 Nagios 中的名称服务时应予以考虑。
**`snmpdtrapd`**通过标准输出以以下格式向此程序提供信息:
hostname
ip-address
oid value
...
第一行包含发送消息的主机的完全限定域名,第二行是其 IP 地址。然后给出一个或多个 OID-值对,每个值对占一行。特定事件通常与一个唯一的 OID-值对相关联,因此程序通常可以完全省略 OID-值对的评估。
在下面的 **`snmptrapd.conf`** 示例中,为了便于阅读,行已被换行。每个 **`traphandle`** 指令 *必须* 在一行中输入:
snmptrapd.conf
traphandle SNMPv2-MIB::coldStart /usr/local/nagios/libexec/eventhandler/
handle-trap SNMP cold-start
traphandle NET-SNMP-AGENT-MIB::nsNotifyRestart /usr/local/nagios/libexec
/eventhandler/handle-trap SNMP restart
traphandle NET-SNMP-AGENT-MIB::nsNotifyShutdown /usr/local/nagios/libexe
c/eventhandler/handle-trap SNMP shutdown
traphandle default /usr/local/nagios/libexec/eventhandler/handle-trap SN
MP unknown
这里使用的陷阱默认由 NET-SNMP 包中的 SNMP 代理 **`snmpd`** 发送,只要在 **`snmpd.conf:`** 中指定了目的地。
snmpd.conf
trapsink name_or_ip_of_the_nagios-server
如果收到带有 OID **`SNMPv2-MIB::coldStart`** 的陷阱,例如,**`snmptrapd`** 将使用参数 **`cold-start`** 启动脚本 **`handle-trap`**。这样它就不必首先从 OID-值对中搜索必要的信息。然而,这个快捷方式仅适用于描述其功能的陷阱 OID 名称。
## 14.6.2 将陷阱传递给 NSCA
脚本 **`handle-trap`**,由 **`snmptrapd`** 运行,分解传递的信息并将其正确格式化后传递给 **`send_nsca:`**
!/bin/bash
NAGIOS="nagsrv"
LOGFILE="/usr/local/nagios/var/handle-trap.log"
read HOST && echo "host: $HOST" >> $LOGFILE
read IPADDR && echo "ip: $IPADDR" >> $LOGFILE
case $IPADDR in
192.168.201.4)
HOSTNAME="irouter"
;;
*)
# silent discard from unknown hosts
exit 0
;;
esac
if [ -z "$1" ]; then
echo "usage: $0
echo "usage: $0
exit 1
else
SERVICE="$1"
fi
if [ ! -z "$2" ]; then
SWITCH="$2"
fi
case $SWITCH in
"cold-start")
OUTPUT="snmpd: Cold Start"
STATE=0
restart)
OUTPUT="snmpd: Restart"
STATE=1
;;
shutdown)
OUTPUT="snmpd: Shutdown"
STATE=2
;;
*)
OUTPUT="Unknown Trap"
STATE=1
;;
esac
CMD="\(HOSTNAME;\)SERVICE;\(STATE;\)OUTPUT"
echo "$CMD" >> $LOGFILE
echo "$CMD" | /usr/bin/send_nsca -H $NAGIOS -d ';'
-c /etc/nagios/send_nsca.cfg >> $LOGFILE 2>&1
首先它保存日志文件和 Nagios 服务器 **`nagsrv`** 的名称,每个都在单独的变量中。第一个 **`case`** 语句指定 Nagios 用于传递的 IP 地址(暂时存储在 **`IPADDR`** 中)的主机名。**`HOST`** 通常包含完全限定域名,这也不可以直接使用,有时也只包含一个 IP 地址,因此在这里使用后者更好。显式测试还允许它丢弃来自不受欢迎的主机的陷阱。最后,匹配的陷阱无需进一步认证即可在 Nagios 服务器上着陆.^([146])
下面的 **`if`** 语句确定是否也向脚本提供了服务名称。如果是这样,则将其保存到 **`SERVICE`** 变量中。如果有第二个参数,过程类似。根据值,下一个 **`case $SWITCH`** 指令定义输出文本和 Nagios 期望的状态。
最终组装 NSCA 的命令,并通过脚本将 **`CMD`** 变量传递给 **`send_nsca`**。与前面的示例一样,使用分号作为分隔符,这必须在 **`send_nsca`** 中使用选项 **`-d`** 指定。
## 14.6.3 匹配服务定义
与 **`syslog-ng`** 示例(14.5.1 为使用 Nagios 准备 syslog-ng 在第 309 页专门讨论了易变服务的问题。
* * *
^([144]) [`www.opennms.org/`](http://www.opennms.org/)
^([145]) 如果您在 Nagios 服务器本身上安装**`snmptrapd`**,则不需要 NSCA,并且可以像第 13.2 节被动服务检查中描述的那样,直接将格式化命令发送到外部命令接口,该节在第 293 页。
^([146]) 虽然 SNMPv3 确实为 SNMP 陷阱提供了认证,但这超出了本书的范围。
# 第十五章. 分布式监控
可以使用被动服务和主机检查来创建一个场景,其中几个非中心 Nagios 实例将它们的结果发送到中央服务器。通常,它们使用 Nagios 服务检查接受者(参见第十四章)。

图 15-1. 使用 Nagios 进行分布式监控
# 15.1 启用 OCSP/OCHP 机制
为了使用 OCSP/OCHP,需要几个步骤。该机制最初在全局配置文件**`/etc/nagios/nagios.cfg`**中的非中央 Nagios 服务器上开启(仅限),其中定义了针对主机(OCHP)和服务的全局命令。这导致非中央 Nagios 实例将每个结果发送到中央服务器。
在服务和主机定义中,您可以额外设置相应的服务或主机是否应该使用该机制。为了使中央 Nagios 服务器能够使用传输的结果,它上面的每个服务或主机最终都必须重新定义一次。
只有在您确实想要分布式监控的情况下,才应在**`nagios.cfg`**中开启**`obsess_over_services`**和**`obsess_over_hosts`**这两个参数。
/etc/nagios/nagios.cfg
...
obsess_over_services=1
ocsp_command=submit_service_check
ocsp_timeout=5
obsess_over_hosts=1
ochp_command=submit_host_check
ochp_timeout=5
每次 Nagios 服务器收到新的测试结果时,它会调用使用**`ocsp_command`**或**`ochp_command`**定义的命令对象。这会在资源上造成额外的负载。
这两个超时防止 Nagios 在一个命令上花费太多时间。如果处理没有终止(因为命令本身没有超时,中央 Nagios 服务器没有反应),那么非中央 Nagios 实例的进程表会很快填满,并可能溢出。
如果您想选择性地排除特定服务和主机的测试结果,不将其传输到中央 Nagios 服务器,可以使用以下参数:
define host{
...
obsess_over_hosts=0
...
}
define service{
...
obsess_over_services=0
...
}
当值为**`1`**时,本地 Nagios 实例将主机或服务检查的结果发送到中央服务器,但值为**`0`**时,则不会发生这种情况。**`1`**是**`obsess_over_hosts`**和**`obsess_over_services`**的默认值;如果结果**不**要传输,则必须指定这两个参数。如果中央位置只负责特定的事情,而其余的行政工作在现场进行,则始终建议这样做。
# 15.2 定义 OCSP/OCHP 命令
定义非中央实例将结果发送到 Nagios 主服务器的两个命令,在大多数情况下涉及基于**`send_nsca`**的脚本(参见 14.4 将测试结果发送到服务器中的示例)。对于服务,这样的脚本如下所示,在这种情况下称为**`submit_service_check:`**
!/bin/bash
Script submit_service_check
PRINTF="/usr/bin/printf"
CMD="/usr/local/bin/send_nsca"
CFG="/etc/nagios/send_nsca.cfg"
HOST=$1
SRV=$2
RESULT=$3
OUTPUT=$4
\(PRINTF "%b" "\)HOST\t\(SRV\t\)RESULT\t$OUTPUT\n" | $CMD -H nagios -c $CFG
当运行时,命令期望在命令行上以正确的顺序提供四个参数:监控的主机、服务名称、插件打开的返回值(**`0`** 表示 OK,**`1`** 表示 WARNING 等),以及插件发出的单行信息文本。为了格式化数据,我们使用**`printf`**函数(**`man printf`**)。最终将格式化后的字符串传递给**`send_nsca`**。
OCHP 的等效脚本(存储在此处的文件**`submit_host_check`**)看起来如下所示:
!/bin/bash
Script submit_host_check
PRINTF="/usr/bin/printf"
CMD="/usr/local/bin/send_nsca"
CFG="/etc/nagios/send_nsca.cfg"
HOST=$1
RESULT=$2
OUTPUT=$3
\(PRINTF "%b" "\)HOST\t\(RESULT\t\)OUTPUT\n" | $CMD -H nagios -c $CFG
唯一缺少的是服务描述的指定。
最好将这两个脚本,按照 Nagios 文档的要求,存储在插件目录(通常是 **`/usr/local/nagios/libexec`**,但对于某些发行版来说将是 **`/usr/lib/nagios/plugins`**)下的子目录 **`eventhandlers`** 中(通常需要创建)。您可以使用宏 **`$USER1$`** 从匹配的命令对象定义中检索它。这最好在 **`misccommands.cfg 文件`** 中定义:
define command{
command_name submit_service_check
command_line \(USER1\)/eventhandlers/submit_service_check \(HOSTNAME\) '\(
SERVICEDESC\)' \(SERVICESTATEID\) '\(SERVICEOUTPUT\)'
define command{
command_name submit_host_check
command_line \(USER1\)/eventhandlers/submit_host_check \(HOSTNAME\) \(HO STSTATEID\)
'\(HOSTOUTPUT\)'
如果您为此使用单独的文件,您必须确保 Nagios 通过在 **`/etc/nagios/nagios.cfg`** 中添加条目来加载此文件。**`$SERVICEDESC$`** 宏和 **`command_line`** 行中的两个输出宏周围的单引号很重要。它们的值有时包含空格,如果没有引号,命令行会将这些空格解释为分隔符。
# 15.3 实际场景
分布式监控的一个应用是监控分支或外部办公室,在这些地方,非中心 Nagios 安装仅限于运行服务和主机检查,并将结果发送到中心实例。非中心实例不需要进一步使用 Nagios 功能,如通知系统或 Web 界面。
另一方面,如果管理员负责分布式位置的网络安全,而中心 IT 部门只负责特殊服务,那么非中心 Nagios 服务器将设置为正常、完整的安装,并选择性地通过 OCSP/OCHP 机制仅将那些检查结果转发到中央办公室,那里的专家负责。
无论情况如何,您必须确保主机和服务定义在非中心和中心都可用。这可以通过使用模板(2.11 模板,第 75 页)和 **`cfg_dir`** 指令(2.1 主配置文件 nagios.cfg,第 55 页)非常简单地完成:您设置定义,以便配置文件可以 1:1 复制。
## 15.3.1 避免配置文件中的冗余
在以下示例中,我们假设非中心服务器仅执行主机和服务的检查,并将结果发送到中心服务器,不提供任何其他 Nagios 功能。以下目录设置在中心主机上:
/etc/nagios/global
/etc/nagios/local
/etc/nagios/sites
/etc/nagios/sites/bonn
/etc/nagios/sites/Frankfurt
/etc/nagios/sites/berlin
...
用于每个位置的配置都放在目录 **`/etc/nagios/sites/`** 下的 **`location`** 目录中。在 **`global`** 之后,所有可以在所有位置相同使用的定义都跟随(例如,在 **`checkcommands.cfg`** 中的命令定义)。目录 **`local`** 包含针对中心服务器定义的特定定义。这些包括服务和主机的模板,其中必须区分中心和外部。
此目录也在非中心服务器上单独创建:仅从中心实例复制 **`global`** 和 **`sites/`****``*`location`*``** 文件夹到分支机构。
三个目录通过 **`/etc/nagios/nagios.cfg`** 中的 **`cfg_dir`** 指令读取。
-- /etc/nagios/nagios.cfg
...
cfg_dir=/etc/nagios/global
cfg_dir=/etc/nagios/local
cfg_dir=/etc/nagios/sites
...
在服务定义中仅使用对于非中心页面和中心页面都相同的设置:
-- /etc/nagios/sites/bonn/services.cfg
define service{
host_name bonn01
service_description HTTP
use bonn-svc-template
...
check_command check_http
...
}
位置相关的参数由模板处理。
## 15.3.2 定义模板
为了确保中心服务器和非中心服务器上的服务定义一致,本地模板必须与中心模板具有相同的名称。此外,您还应该确保所有必需的参数(参见第二章配置 Nagios 第 53 页)都已输入,即使它们在某个位置不是必需的,因为模板和服务定义必须共同覆盖所有必需的参数。
以下示例显示了一个非中心位置的服务模板:
-- On-Site configuration for the Bonn location
define service{
name bonn-svc-template
register 0
max_check_attempts 3
normal_check_interval 5
retry_check_interval 1
active_checks_enabled 1
passive_checks_enabled 1
check_period 24×7
obsess_over_services 1
notification_interval 0
notification_period none
notification_options n
notifications_enabled 0
contact_groups dummy
}
对于非中心页面重要的参数以粗体形式打印。除了指向测试本身的参数外,参数 **`obsess_over_services`** 也必须包含在内。这确保检查结果被发送到中心服务器。
**`notifications_enabled`** 在此情况下关闭通知,因为本地管理员无需担心来自中心监控服务的错误消息。或者这也可以在非中心的 **`/etc/nagios/nagios.cfg`** 中全局完成。
**`register 0`** 确保模板仅作为模板使用,因此 Nagios 不会将其解释为单独的服务定义。
中心服务器上具有相同名称的对应部分看起来如下:
-- Service template for the central Nagios server
define service{
name bonn-svc-template
register 0
max_check_attempts 3
normal_check_interval 5
retry_check_interval 1
active_checks_enabled 0
passive_checks_enabled 1
check_period none
check_freshness 0
obsess_over_services 0
notification_interval 480
notification_period 24×7
notification_options u,c,r
notifications_enabled 1
contact_groups admins
}
参数 **`passive_checks_enabled`** 以及通知系统的配置在这里很重要。在中心侧,涉及测试本身的参数仅在启用新鲜度检查时才会起作用(参见第 13.4 节对被动检查过时信息的反应第 295 页)。这仅在中心 Nagios 服务器本身能够主动测试所有服务且有任何疑问时才有效。由于在此简单的模板解决方案中,**`check_command`** 在位置相关的服务定义中给出,且在非中心和中心服务器上相同,因此只有在中心和非中心都可以使用相同的命令对象时才会有效——如果**`global/checkcommands.cfg`** 中的对象定义在两边匹配。
然而,在示例中,我们完全关闭了波恩地点的服务主动测试,使用 **`check_period none`** 和将 **`check_freshness`** 设置为 0。到目前为止所描述的系统当然也可以应用于主机检查。
# 第三部分. Web 界面和其他可视化 Nagios 数据的方法
# 第十六章. 经典 Web 界面
右侧是带有醒目黑色背景的导航区域,其余区域用于显示被调用的 CGI 脚本(图 16-1)- Nagios Web 界面就这么简单。起始屏幕提供了访问程序文档的入口——如果你只是想快速查找某些信息,这非常实用。
只要你有正确的访问权限,Web 界面允许你做的不仅仅是查找信息。你可以运行一系列命令并主动控制 Nagios:从设置单个命令,到开关消息,到重启服务器。
要完全描述所有功能,需要单独一本书。这就是为什么我们在这里只描述 CGI 程序所基于的概念,^([147]) 以此方式向您展示可用的广泛选项。
许多功能使用相同的 CGI 程序。如果你在图 16-1 所示的导航区域上下移动鼠标,并观察浏览器在此操作时的状态显示,这会揭示要调用的 URL,你将看到在**监控**部分直到**显示主机**:输入字段,始终调用 CGI 程序**`status.cgi`**,只有四个例外。参数不同。对于 CGI 程序**`cmd.cgi`**,情况类似,它可以运行一般命令。传递的参数指定是否读取注释,或启用或禁用消息,或重启 Nagios。

图 16-1. 在“服务问题”和“主机问题”菜单项下未处理的子项自 Nagios 3.0 以来一直位于 Nagios Web 界面的起始页。
表 16-1. CGI 程序概述
| CGI 程序 | 描述 |
| --- | --- |
| **`status.cgi`** | 以各种形式显示状态;迄今为止最重要的 CGI 程序(图 16-10 到 图 16-15, 第 334 页)。 |
| **`statusmap.cgi`** | 监控主机的拓扑表示(参见 图 16-27, 第 347 页) |
| **`statuswrl.cgi`** | 以 3D 格式表示拓扑结构;需要 VRML 兼容的浏览器,并允许在虚拟空间中进行交互式导航(图 16-29, 第 349 页) |
| **`statuswml.cgi`** | WAP 设备(手机)的简单状态页面 |
| extinfo.cgi | 关于主机或服务的附加信息,以及运行命令的可能性(图 16-4, 第 331 页) |
| cmd.cgi | 运行命令(图 16-23, 第 343 页) |
| tac.cgi | 所有要监控的服务和主机的概述,**战术概述**(参见 图 16-26, 第 346 页) |
| outages.cgi | 导致部分网络故障的网络节点(图 16-30, 第 350 页) |
| config.cgi | 显示 Nagios 对象定义(图 16-31, 第 352 页) |
| histogram.cgi | 发生事件的数量的直方图(图 16-34, 第 353 页) |
| History.cgi | 显示所有曾经发生的事件(图 16-35, 第 355 页) |
| notifications.cgi | 所有已发送通知的概述(图 16-36, 第 355 页) |
| showlog.cgi | 显示所有日志文件条目 (图 16-37, 第 356 页) |
| summary.cgi | 事件报告,可以按主机、服务、错误类别和时间段进行编译 (图 16-39, 第 358 页) |
| trends.cgi | 记录已发生状态的时序轴 (图 16-40, 第 359 页) |
表 16-1 显示了包含在包中的所有 CGI 程序的概述。它们都会检查运行请求操作的人是否有权这样做。通常,用户只能访问他作为联系人登记的主机和服务的相关信息。此外,还有可能为特定用户分配更全面的权限,使他们基本上可以显示所有主机和服务,例如,或请求系统信息。其他用户的设置在**`cgi.cfg`**配置文件中完成,认证参数在 A.2 cgi.cfg 中的 CGI 配置, 第 606 页中描述。
# 16.1 识别和应对问题
对于管理员来说,一个合适的起点是**服务问题**页面,可以通过菜单项访问,如图图 16-2 所示。您可以一目了然地看到所有问题。如果只有与服务相关的问题,但没有与主机相关的问题,**主机**列中的主机名背景为灰色,但红色背景表示主机本身是问题的来源。

图 16-2. 服务问题菜单项将当前问题提请注意
主机 **`sis-mail`** 和 **`sis-proxy`**,在图 16-2 中失败,现在可以在**主机问题**菜单项中再次看到它们(图 16-3):**`sis-mail`**无法访问(不可达),因此真正的故障因此存在于主机 **`sls-proxy`** 的失败中。这种依赖关系在**故障**菜单项中得到了说明(图 16-30, 第 350 页)或**状态图**(图 16-27, 第 347 页)。在图 16-27 中,两个失败的主机以红色背景显示,并且你可以清楚地看到哪个主机依赖于另一个主机(始终从中央 Nagios 主机的角度)。

图 16-3. 主机问题菜单项揭示了此显示
## 16.1.1 对有问题的主机的注释
管理员通过电话与外部办公室澄清了问题:DSL 连接已失败。他向负责的提供商宣布了这一故障。为了防止他的同事再次遇到同样的麻烦,管理员在失败的主机上输入了相应的注释。为此,他点击状态显示中的主机名,这会带他到一个特定主机的信息页面(图 16-4),这些选项在 16.2.2 附加信息和控制中心:extinfo.cgi 中有更详细的描述,第 339 页。

图 16-4. `extinfo.cgi` 提供所选主机的附加信息
使用页面底部的**添加新注释**链接,CGI 程序**`cmd.cgi`**(16.2.3 外部命令接口:cmd.cgi, 第 343 页),通过传递相应的参数已经为此任务做好了准备,^([148]) 允许记录注释(图 16-5). 主机名已经显示,**持久**框中的勾选确保注释也将“存活”在 Nagios 重启之后。在**作者(您的姓名):**字段中填写的用户名可以编辑,同样,**注释**字段中的实际注释也可以编辑.^([149])

图 16-5. 为主机添加注释
管理员通过**提交**按钮确认输入。返回到状态概览,例如使用**服务问题**菜单项,管理员将在主机名旁边看到一个气泡,表示此主机存在注释(图 16-6). 点击图标将打开对应的信息页面,并将管理员直接带到注释输入页面(图 16-7). 点击**操作**列中的垃圾桶图标可以单独删除这些注释,如果需要的话。

图 16-6. 一个气泡显示注释的存在

图 16-7. 点击删除所有注释将一次性删除所有注释
## 16.1.2 对问题承担责任
*致谢*(在 Web 界面上如此拼写)比简单的注释更接近工作流程。致谢信号向其他管理员表明有人已经在处理问题,因此暂时不需要其他人介入。在状态概览中,一个小工图标象征着这种承担责任的形式(图 16-8")), Nagios 还会通知相关联系人。
要发出此类声明,需要在相关主机的扩展信息页面上使用**“确认此主机问题”**链接。除了用于输入正常评论的字段外,此情况下还有两个复选框,**“粘性确认”** (图 16-9)——如果选中,此选项将防止在错误状态持续时进行周期性通知——以及**“发送通知”**。如果后者也被选中,Nagios 将通知其他管理员。

图 16-8. 一个工人图标表示管理员已经承担了问题的责任(确认)

图 16-9. 主机确认输入对话框
**持久性注释**在 Nagios 2.x 和 Nagios 3.0 中的效果不同:在 Nagios 2.x 中,只有当复选框被标记时,注释才会被保留。不幸的是,使用这种方法在重启时保存注释的缺点是,当问题解决后,注释不会自动消失。另一方面,Nagios 3.0 通常在重启后保留所有注释。如果删除**“持久性注释”**的勾选标记,Nagios 将在问题得到纠正后立即自动删除注释。如果勾选标记被设置,当不再需要时,必须手动删除注释,就像在 Nagios 2.x 中一样。
我们在这里使用故障主机状态进行演示的内容,也可以应用于故障服务。CGI 程序是相同的,并且通过传递参数,它们会接收到有关是否涉及主机或服务的相关信息,并相应地做出反应;只有主机字段会以**服务**条目的形式获得支持。
* * *
^([147]) 我们在这里提到 CGI 程序而不是 CGI 脚本的合理原因是:Nagios 2.x 和 3.0 的所有 CGI 程序都是 C 程序。
^([148]) **`cmd_type=1&host=sls-proxy`**. 关于参数的更多内容请参阅 16.2.3 外部命令接口:cmd.cgi,见第 343 页。
^([149]) 从 Nagios 3.0 开始,可以通过使用参数**`lock_author_name`**(参见 A.2.2 其他参数)来防止修改作者名称。
# 16.2 各个 CGI 程序概述
在本书付印时,这一章是关于 Nagios Web 界面的最全面文档,特别是针对单个 CGI 脚本。但由于篇幅限制,我们不会深入每个细节。如果你想要了解更多,你必须查看脚本的源代码或查看**`nagios-users`**^([150])邮件列表。其中一些也被 Nagios 开发者阅读,许多问题在那里得到了解答,而这些问题的文档目前尚不存在。
## 16.2.1 状态显示的变体:**`status.cgi`**
到目前为止,最重要的 CGI 程序是**`status.cgi`**,它负责状态显示。显示的内容由三个参数组决定。第一个参数组定义生成的网页是否显示所有主机、特定主机或服务组:
http://nagiosserver/nagios/cgi-bin/status.cgi?host=all
http://nagiosserver/nagios/cgi-bin/status.cgi?hostgroup=all
http://nagiosserver/nagios/cgi-bin/status.cgi?servicegroup=all
使用**`host`**可以选定单个主机,而在此情况下**`all`**代表所有主机。**`hostgroup`**允许显示特定的主机组,同样你也可以使用**`all`**来代表所有主机组。最后,**`servicegroup`**指示 CGI 程序显示给定值的单个服务组或**`all service groups`**,使用**`all`**。

图 16-10. 概览输出样式
**`host=all`**和**`hostgroup=all`**的输出在样式上有所不同,这种样式由第二个参数组定义。对于**`host=all`**,**`style=detail`**是默认设置,而对于**`hostgroup=all`**,它是**`style=overview.status.cgi?host=all&style=overview`**,因此它产生的结果与**`status.cgi?hostgroup=all`**相同。
不属于任何主机组的主机仅在**`host=all&style=detail`**或**`hostgroup=all&style=hostdetail`**的详细视图中出现。所有其他显示样式总是显示整个主机组,其中可能缺少单个主机。**`status.cgi`**提供了五种可能的输出样式:**`overview`**以表格形式表示主机,但根据状态总结服务(图 16-10 展示了这种情况)。对于**`SAP`**主机组,你可以通过以下 URL 调用相应的显示
http://nagiosserver/nagios/cgi-bin/status.cgi?hostgroup=SAP&style=overview
**`style`**值**`summary`**压缩了**`overview: status.cgi`**的输出,仅显示每行一个主机组(图 16-11 展示了 Nagios 2.x 的情况,图 16-12 展示了 Nagios 3.0 的情况)。对于 Nagios 3.0,错误状态被区分成**未处理**(未设置确认)或**已确认**。

图 16-11. Nagios 2.x 的**`summary`**输出样式

图 16-12. Nagios 3.0 的 ``*`summary`*`` 输出样式
**`grid`** 样式提供了一个非常吸引人的总结,您可以通过它所突出显示的颜色看到每个单独服务的状态(图 16-13)。**`detail`** 在单独的一行中详细显示每个服务。**`hostdetail`** 输出样式仅限于主机信息,为每个主机提供一行详细信息的详细信息(图 16-15)。

图 16-13. `grid` 输出样式

图 16-14. `detail` 输出样式

图 16-15. `hostdetail` 输出样式
第三个也是最后一个参数组允许您通过 *选择器* 影响由 **`status.cgi`** 显示的状态和属性,例如尚未由管理员设置确认的所有处于错误状态的服务(参见 16.1.2 负责问题,第 332 页)。状态通过 **`hoststatustypes`** 或 **`servicestatustypes`** 参数传递,属性通过 **`hostprops`** 和 **`serviceprops`**。所有四个参数在等号后都需要数值,这些数值总结在 表 16-2、表 16-3 和 表 16-4 中。
表 16-2. `Hoststatustypes` 的可能值
| 值 | 描述 |
| --- | --- |
| 1 | 待定(由于为该主机计划进行的第一次测试的结果尚未可用) |
| 2 | UP |
| 4 | DOWN |
| 8 | 不可达 |
第三个也是最后一个参数组允许使用**选择器**来影响**`status.cgi`**显示哪些状态和属性,例如,所有尚未设置确认的故障状态的服务(参见 16.1.2 负责问题)。条件通过参数**`hoststatustypes`**或**`servicestatustypes`**传递,属性通过**`hostprops`**和**`serviceprops`**参数传递。所有四个参数都需要等于号后的数值,这些数值总结在表 16-2、表 16-3 和表 16-4 中。
表 16-3. `Servicestatus types` 的可能值
| 值 | 描述 |
| --- | --- |
| 1 | 待定(服务最初计划进行检查,但迄今为止没有结果可用) |
| 2 | 正常 |
| 4 | 警告 |
| 8 | 未知 |
| 16 | 严重 |
表 16-4. `host` 和 `serviceprops` 的可能值
| 值 | 描述 |
| --- | --- |
| 1 | 计划的下线时间(计划下线) |
| 2 | 没有计划的下线时间(没有计划下线) |
| 4 | 确认(状态已由管理员确认) |
| 8 | 没有确认 |
| 16 | 主机/服务检查已禁用 |
| 32 | 主机/服务检查已启用 |
| 64 | 事件处理器已禁用 |
| 128 | 事件处理器已启用 |
| 256 | 振荡检测已禁用 |
| 512 | 振荡检测已启用 |
| 1024 | 主机/服务振荡(波动) |
| 2048 | 主机/服务不振荡 |
| 4096 | 当前排除在通知之外的主机或服务 |
| 8192 | 通知已启用 |
| 16384 | 被动主机/服务检查已禁用(第十三章) |
| 32768 | 被动主机/服务检查已启用 |
| 65536 | 至少有一个被动测试结果的主机/服务 |
| 131072 | 至少有一个活动检查结果的主机/服务 |
| 262144 | 硬状态下的主机/服务(从 Nagios 3.0 开始) |
| 524288 | 软状态下的主机/服务(从 Nagios 3.0 开始) |
如果你想同时查询多个状态或属性,只需将指定的值相加:**`status.cgi?host=all&servicestatustypes=28`** 显示所有具有错误状态的服务:警告、未知和严重,即 4+8+16 = 28。此查询与导航区域中的**服务问题**菜单项相同。
**`status.cgi?hostgroup=all&hoststatustypes=12&style=hostdetail`** 对应导航区域中的 **主机问题** 菜单项。它查询所有处于 DOWN 或 UNREACHABLE 状态的主机(这里 4+8 = 12)。由于只应显示主机信息,而不显示服务信息,因此输出样式为 **`hostdetail`**。
**`status.cgi?host=all&servicestatustypes=24&serviceprops=10`** 是第一个示例的变体:仅显示状态为 UNKNOWN 和 CRITICAL(8 + 16 = 24),并且既不显示计划停机时间,也没有已经被确认(2 + 8 = 10)。
CGI 程序每次在单独的复选框中指定过滤器参数。图 16-16 展示了第三个示例。

图 16-16. 此信息框显示了 status.cgi 应显示的状态和属性
如果您愿意,可以根据自己的需求定义自己的导航区域,或者直接使用现有的导航区域。主页由一个框架组成,导航区域本身由一个普通的 HTML 文件定义:**`/usr/local/nagios/share/side.html`**.^([151])
在 Netways 的 Nagios 示例页面上提供了一个更改后的 **`side.html`** 示例^([152]);^([153]); 另一个示例是图 16.6 使用 Nuvola 风格的现代布局中展示的 Nuvola 风格。
## 16.2.2 额外信息和控制中心:**`extinfo.cgi`**
如果使用 **`host`** 或 **`service`** 参数调用,**`extinfo.cgi`** 不仅提供特定主机或服务的详细信息(图 16-4, 第 331 页),还充当主机和服务(参数 **`hostgroup`**)以及服务组(**`servicegroup`**)的控制中心。根据被调用的对象类,您可以从这里运行各种命令。
在左侧区域,详细记录了主机的状态,而在右侧的框中——被**主机命令**覆盖——提供了可以运行的命令选择。这些命令调用**`cmd.cgi`**(16.2.3 外部命令接口:cmd.cgi,第 343 页)并且仅在外部命令接口(13.1 外部命令接口,第 292 页)激活时才有效。页面底部允许您输入特定对象的注释、读取它们,并再次删除。**`extinfo.cgi`**为服务生成的网页也遵循此模式。
服务和主机组的对应页面(图 16-17),另一方面,仅允许运行特定组的命令,并且不显示任何其他信息。每个命令适用于整个组,从而节省了大量的鼠标点击。例如,**禁用此主机组中所有主机的通知**,确保 Nagios 不再向此主机组中的主机发送任何消息。

图 16-17. SAP 主机组的命令中心:`extinfo.cgi?type=5&hostgroup=SAP`
除了主机、服务和相应的组之外,CGI 程序还有其他显示功能,这些功能由 CGI 参数**`type:`**启用
http://nagsrv/nagios/cgi-bin/extinfo.cgi?type=value
根据指定的值,可能需要进一步参数,因此要显示服务,还必须包括主机名和服务标识:
**`extinfo.cgi?type=0`**
显示 Nagios 进程本身及其所有全局参数的信息(例如启动时间和进程 ID;通常包括发送通知、处理性能数据等;参见图 16-18)。在**进程命令**框中可以更改全局参数,并且 Nagios 也可以停止和重新启动。

图 16-18. Nagios 进程和全局设置信息:`extinfo.cgi?type=0`
**`extinfo.cgi?type=l&host=`****``*`host`*``**
显示**``*`主机`*``**(参见图 16-4,第 331 页)的命令和信息。
**`extinfo.cgi?type=2&service=`****``*`service`*``**
对于**``*`服务`*``**也是如此。
**`extinfo.cgi?type=3`**
在单页上显示所有可用的主机和服务评论(图 16-19)。

图 16-19. 所有现有评论的概述:`extinfo.cgi?type=3`
**`extinfo.cgi?type=4`**
提供了按主机和服务以及主动和被动检查分开的 Nagios 性能信息(图 16-20)。

图 16-20. 性能信息:`extinfo.cgi?type= 4`
中间列显示了 Nagios 在过去 1、5、15 和 60 分钟内已经执行了多少个计划测试。只要存在**`normal_check_interval`**超过五分钟的检查,前两个值永远无法达到 100%。
右侧列定义了此页的实际值:**检查执行时间**指定了 Nagios 执行主动主机和服务检查所需的最小、最大和平均时间。**检查延迟**衡量了测试计划开始时间和实际运行时间之间的距离。如果这种延迟明显大于一或两秒,Nagios 可能存在性能问题。一个可能的原因是系统处理性能数据太慢,但低性能硬件也可能在这里发挥作用。寻找原因有时可能非常困难,原始文档^([154])提供了关于此主题的一些提示。
**`extinfo.cgi?type=5&hostgroup=`****``*`hostgroup`*``**
显示主机组的命令中心(图 16-17 在第 339 页)。
**`extinfo.cgi?type=6`**
显示主机和服务的所有计划维护期(图 16-21)。

图 16-21. 所有计划维护期的概述:`extinfo.cgi?type=6`
**`extinfo.cgi?type=7`**
显示所有计划测试的概述,按下一个实施时间排序(见图 16-22)。在此旁边,**`extinfo.cgi`**还列出了上次检查的时间。
**“活动检查”**列显示相应的测试是否处于活动状态,而在**“操作”**列中可以删除计划中的检查或将检查移动到不同的时间。
**`extinfo.cgi?type=8&servicegroup`****``*`servicegroup`*``**
显示服务组的命令中心,其结构与主机组的命令中心相同。

图 16-22. 所有计划中的测试,按计划实施时间排序:`extinfo.cgi?type=7`
## 16.2.3 外部命令接口:**`cmd.cgi`**
作为一名真正的全能选手,**`cgi.cmd`**,拥有大约 100 个功能,涵盖了接口为外部命令提供的几乎所有可能性。**`cmd_typ`**参数定义了 CGI 程序应该运行这些功能中的哪一个。以下命令
http://nagiosserver/nagios/cgi-bin/cmd.cgi?cmd_typ=6
关闭特定服务的活动服务检查(图 16-23)。为了唯一描述所需的服务,必须指定主机和服务描述。如果手动运行 CGI 程序,显示的 Web 表单将查询这些值;如果**`cmd.cgi`**由另一个 CGI 程序启动,所需数据将通过 CGI 参数传递。此处可能的参数是**`host`**、**`service`**、**`hostgroup`**和**`servicegroup`**,后面跟着一个等号(=)和相应的 Nagios 对象。

图 16-23. 使用`cmd.cgi?cmd_typ=6`禁用服务检查
图 16-24 列出了指向主机或服务的最重要命令,而图 16-25 显示了那些指向全局参数控制(对应于主配置文件**`nagios.cfg`**中的值)。源代码文件**`include/common.h`**包含所有可能值的完整列表,包括计划中但尚未实现的值。
图 16-24 和图 16-25 的第一列描述了命令的功能:**`ADD_HOST_COMMENT`**为主机添加注释,**`DISABLE_ACTIVE_SVC_CHECK`**关闭服务的活动检查(简称为**`SVC`**)。
此后的列指定了相应函数所引用的对象类型。要添加带有**`ADD_HOST_COMMENT`** 的注释,你必须指定相关的主机。因此,在主机列中显示的函数代码**`1`**。只有当匹配的服务被命名时,才能关闭特定的活动服务检查,所以函数代码**`6`** 应该在**服务**列中找到。使用**`16`**,你可以关闭指定主机上的所有活动服务检查;也有针对主机或服务组所有活动服务检查的相应代码。
使用**`ACKNOWLEDGE_PROBLEM`**,管理员确认他正在处理特定问题。**`33`**(主机列)指的是主机问题,而**`34`**(**服务**列)指的是服务问题。灰色字段表示没有对应于主机和服务组的函数。当使用**`cmd_typ=33`** 打开的网页表单时(图 16-9
图 16-24. `cmd.cgi?cmd_typ=` 最重要主机和服务相关代码
指向全局参数的函数(图 16-25
图 16-25. `cmd.cgi` 命令代码用于全局参数
## 16.2.4 一目了然的最重要事项:**`tac.cgi`**
作为“战术概览”,**`tac.cgi`** 在一个网页上提供了大量信息,以摘要形式显示(图 16-26
图 16-26. 使用 `tac.cgi` 的战术概览
在页面右侧的上框总结了**`extinfo.cgi?type=4`**(参见 16.2.2 额外信息和控制中心:extinfo.cgi)Nagios 性能数据,这些数据可以详细显示。下面的条形图显示了整个监控网络的健康状况,以百分比表示。如果你将鼠标悬停在任何一个条形上,你也会看到百分比数值。
## 16.2.5 网络拓扑图:**`statusmap.cgi`**
**`statusmap.cgi`** (图 16-27) 提供了监控主机之间依赖关系的视图。从中间的中央 Nagios 服务器开始,线条连接了服务器直接到达的所有主机——这些主机的定义不需要指定**`parents`**参数(参见 2.3 定义要监控的机器,包括主机,第 62 页)。
图形还揭示了 Nagios 只能通过其他主机间接访问的主机。因此,在**`sis-mail`**和图 16-27 中的 Nagios 服务器之间,有主机**`sis-proxy`**、**`hspvip`**和**`pfint. sis-proxy`**,正如注释**Down**和红色(而不是绿色)的背景所暗示的,已经失败。由于**`sis-mail`**依赖于它,因此它处于 UNREACHABLE 状态,**`statusmap.cgi`**也用红色背景标记。

图 16-27. 以图形方式显示的监控主机依赖关系
Nagios 如何在图形中排列主机由配置文件**`cgi.cfg`**中的参数**`default_statusmap_layout`**(A.2.1 认证参数)定义。布局也可以通过 Web 界面中的选择窗口进行更改(在图 16-28 的右上角)。该图显示了 Netways 的演示系统,其外观取决于用户特定的坐标,在这种情况下,你必须为每个主机单独指定(参见 16.4.1 扩展主机信息)。Nagios 提供的问号图标已被网站管理员更换为更漂亮的图片。坐标和图标由**`hostextinfo`**对象定义,在 16.4.1 扩展主机信息中更详细地描述。

图 16-28. 带有自定义坐标和图标的状况图
如果将鼠标移至特定的主机上,Nagios 将在左上角打开一个黄色窗口,显示状态信息,包括 IP 地址、当前状态信息和最后检查的时间。在这个框的底部,**`statusmap.cgi`**总结了在此主机上运行的服务状态。
如果你双击特定的主机,Nagios 将分支到通常的状态概述,除了所选主机的数据外,还显示属于此主机的所有服务(第 336 页的图 16-14 提供了一个示例)。
## 16.2.6 3D 导航:**`statuswrl.cgi`**
**`statuswrl.cgi`** 允许 Nagios 在网络计划的 3D 表示中移动 (图 16-29). 在这里,您可以放大到主机,移动整体视图,旋转等。
显示需要 VRML 功能的浏览器.^([156]) 尽管原始文档^([157]) 提供了对应插件的链接,但其中两个已经过时,只有 *Cortona*^([158]) 在印刷时可以访问。然而,这个插件在 Linux 下不工作;在 Windows 下,它与 Internet Explorer 一起工作,也可以与 Netscape、Mozilla 和 Firefox 一起工作.^([159]) 美国国家标准与技术研究院(NIST)在其网站上提供了一个按操作系统和浏览器组织的 VRML 软件的良好概述.^([160])
在 Linux 的 VRML 插件中,*OpenVRML*、^([161]) 和 *free WRL*^([162]) 最有可能被使用。标准的 Linux 发行版通常不包括完整的软件包。OpenVRML 包含在 Fedora 的 Extras 中;在 freeWRL 的主页上有 Fedora 和 Ubuntu 的二进制软件包。除非您是经验丰富的系统管理员或软件开发者,否则您不应该尝试自己编译软件:这里有很多陷阱。如果您以前从未使用过 Java 编译器,也没有自己编译过像 Mozilla 或 Firefox 这样的复杂软件包,那么您应该放弃。

图 16-29. 这张图片标志着您自己的网络之旅的开始
但这一切都不是绝望的理由,因为 3D 导航的使用本身就值得怀疑,尤其是当正常状态图的 2D 视图已经显示了所需的所有信息,并且在浏览器中显示简单的平面图形比 CPU 密集型的 3D 渲染要快得多。在您匆忙开始自己编译软件的冒险之前,我们建议您自己决定,使用 Cortona 插件,编译像 OpenVRML 这样的项目是否值得努力。
## 16.2.7 使用手机查询状态:**`statuswml.cgi`**
为了使 Nagios 提供的信息对没有完全功能浏览器的 WAP^([163])设备可访问,**`statuswml.cgi`** 生成 WML 格式的网页,^([164]) 可以用手机显示——前提是 Nagios 服务器在互联网上是可访问的。除了对主机和服务的状态查询外,它还允许 CGI 程序关闭测试和通知,并通过对现有问题的确认来确认问题。
在您将 Nagios 通过互联网访问之前,您应该仔细思考:Nagios 提供了许多敏感数据,这些数据可能会被黑客滥用。如果有疑问,您最好不使用它。没有直接互联网访问,**`statuswml.cgi`** 是无用的,因为手机无法使用如 VPN 隧道之类的受保护访问方法。这就是为什么我们在此处不会详细介绍**`statuswml.cgi`**。
## 16.2.8 分析中断的局部网络:**`outages.cgi`**
CGI 程序 **`outages.cgi`** 只显示那些导致局部网络故障的主机概览中的网络节点:与状态概览不同,如图 16-15,第 336 页,**`outages.cgi`** 在**#受影响的主机**列中指定了每种情况下影响的多少服务和主机(图 16-30)。

图 16-30. 只要 `sis-proxy` 失败,Nagios 就无法访问其后面的任何主机
使用**操作**列中的图标,您可以调用其他 CGI 程序,这些程序将选择性地过滤掉此处显示的主机上的信息。从左到右,它们显示了详细视图中的状态显示(交通灯)、拓扑网络视图(网络树)、3D 视图(**3-D**)、趋势显示(图表)、主机日志文件条目(电子表格),以及已发出的通知的显示(扩音器)。
## 16.2.9 使用 **`config.cgi`** 查询对象定义
**`config.cgi`** 展示了指定类型(图 16-31)的所有对象的定义表格概览——涉及的对象类型可以在右上角的选项字段中定义。如果考虑本身包含 Nagios 对象(在主机视图中为**主机检查命令,默认联系人组**,以及——在图片中不可见——**通知周期**),则链接会直接带您到该对象类型的配置视图。

图 16-31. `config.cgi`显示所选对象类(此处为主机)的当前配置(提取)
CGI 程序不提供任何更改设置的方法。此外,只有被列入参数**`authorized _for_configuration_information`**(配置文件**`cgi.cfg`**,第 607 页)的用户才有权访问此视图。
## 16.2.10 可用性统计:**`avail.cgi`**
如果你正在监控系统,那么你也会对其可用性感兴趣。**`avail.cgi`**首先询问你是否对**主机、服务、主机组**和**服务组**感兴趣。选择时间范围后,你将看到概述,如图 16-32 所示。对于**服务**和**主机**,你还可以通过**所有主机**或**所有服务**以 CSV 文件的形式展示可用性数据。
**`avail.cgi`**将主机和服务分别显示。服务或主机在特定状态下保持的时间可以通过相应的颜色列查看——绿色表示 OK,黄色表示 WARNING,红色表示 CRITICAL(服务),DOWN 和 UNREACHABLE(主机)——以百分比表示。显示服务状态为 UNKNOWN 的时间的列以橙色显示。不完整的日志文件显示在**未确定**列中。如果存在大于零的值,则表示 Nagios 无法就状态发表意见的时段。
在每个表格下方,**平均**行指定了各个值的平均值。在图 16-32 中,涉及的主机有 99.965%的时间是可用的。
**`avail.cgi`**在每种情况下都显示了两次可用性:首先作为评估期间的绝对值,然后(在括号中)与数据实际可用的时间相关。只要**时间未确定**列显示**`0.000%`**,两个可用性值就匹配。

图 16-32. 使用`SAP-Services`服务组示例的可用性报告
如果你点击显示的某个主机或服务,将出现详细视图。图 16-33 展示了主机**`sap-12`**的此类视图。

图 16-33. 详细解释了主机`sap-12`的可用性
在一个显示所选期间状态的彩色条形图中,有关于主机本身的详细信息,然后是监控在此主机上运行的服务可用性的统计信息。这包括日志文件的摘录,只显示与主机可用性相关的条目;即**`HOST UP`**、**`HOST DOWN`**或**`HOST UNREACHABLE`**。日志文件条目由**`avail.cgi`**截断以节省空间。
## 16.2.11 发生了哪些事件,频率如何?—**`histogram.Cgi`**
如果主机或服务的状态发生变化,这被称为**事件**。CGI 程序**`histogram.cgi`**以不同的视图显示了这种变化的频率。如果你选择**月日**作为**细分类型**,它说明了哪一天发生了什么事件,以及发生的频率(图 16-34). 服务中的红色图表代表 CRITICAL,橙色代表 UNKNOWN,黄色代表 WARNING,绿色代表 OK。处于 DOWN 状态的主机的曲线由**`histogram.cgi`**用红色标记,不可达主机的曲线用酒红色标记,绿色线条通常代表 OK。

图 16-34. 在哪些天发生了多少种类型的事件?
如果你选择“星期几”这个变化,网页将显示一周中哪一天发生的事件最多,这样你可以找出周一是否真的是最糟糕的一天。此外,你还可以按天(**小时**)或按年月(**月份**)显示频率。通过**报告周期**你可以调整报告周期。通过**假设状态保留**你可以调整是否保留并包含在评估中的先前存在的状态(**`yes`**)或不是(**`no`**)。
如果你已经配置了 Nagios,以便它明确记录监控主机和服务的状态以重启或当日志文件更改时,^([165])并且如果你将**`Initial states logged`**设置为**`yes`**,脚本将明确将其包含在评估中。一个**`no`**将忽略条目;**`histogram.cgi`**随后假定系统启动后的状态与重启前直接存在的状态相同.^([166])
**忽略重复状态**在状态长时间持续并因此反复产生相同结果时,会做出让步。如果你在这里设置为“是”,脚本将只评估一次而不是多次。
如果你选择 **`State types to graph:**** 中的 **`Hard and soft states`** 项,**`histogram.cgi`** 也会计算软状态。例如,如果一个服务在 **`retry_check_interval`** 设置为 **4** 时从 OK 变为 CRITICAL,那么 **`histogram.cgi`** 会计算总共四个结果,三个软状态和一个硬状态。如果你只评估硬状态,统计值评估为 1。如果错误被纠正,则没有软状态;因此,如果包含软状态在评估中,CRITICAL 的值通常大于 RECOVERY 的值。
## 16.2.12 在特定状态后过滤日志条目:**`history.cgi`**
**`history.cgi`** 脚本允许通过选择字段 **`State type options`**(如图 16-35 中的顶部右侧所示图 16-35) 选择性地从日志文件中提取某种类型(软或硬)的状态,并使用 **`History detail level for all hosts`** 提取特定事件(所有、所有与主机相关的、所有服务事件、仅主机恢复、仅主机下线等)。当调用 CGI 程序时,可以通过参数限制要显示的条目到个别主机、服务或主机或服务组。因此,命令
histogram.cgi?host=sap-12
仅显示主机 **`sap-12`** 的日志文件条目。如果输出应限制到特定主机,则还需要指定服务描述:
histogram.cgi?host=sap-12&service=PING
选择主机和服务组的方式相同:
histogram.cgi?hostgroup=SAP
histogram.cgi?servicegroup=SAP-Services
**`history.cgi`** 视图所显示的周期取决于日志文件的存档间隔。脚本始终引用存档文件的内容。如果你在配置文件 **`nagios.cfg`** 中将参数 **`log_rotation_method`** (A.1 主配置文件 nagios.cfg) 设置为 **`d`** 以进行每日存档,网页将显示一天的条目。使用箭头(如图 16-35 中的顶部所示图 16-35),你可以上下滚动查看不同日期。

图 16-35. `history.cgi` 过滤日志文件中的信息
## 16.2.13 谁被告知了什么,何时?— **`notifications.Cgi`**
日志文件还提供了一个过滤视图:**`notifications.cgi:`** 它显示了所有已发送的消息。在这里,视图也可以通过右上角的选项字段限制到特定的消息组,如图 16-36:涉及所有主机的通知,关于处于关键状态的服务等。

图 16-36. `notifications.cgi` 回答了谁在何时收到关于什么的消息的问题
如果你只想看到有关特定主机和服务的消息,你必须再次在运行 CGI 程序时使用参数来指定:
notifications.cgi?host=host
notifications.cgi?host=host&service=service name
notifications.cgi?contact=contact
除了 **`host`** 和 **`service`**,你还可以选择特定的联系人,但选择主机或服务组是不可能的。
## 16.2.14 显示所有日志文件条目:**`showlog.cgi`**
CGI 程序 **`showlog.cgi`** 以原始形式显示日志文件,并添加了一些彩色图标以帮助你找到方向:一个红色按钮标记关键服务状态或 DOWN/UNREACHABLE 主机,一个黄色按钮标记 WARNING,一个绿色按钮标记 OK。其他按钮指的是信息条目或 Nagios 重启(图 16-37).
你在这里只有一个选项:按时间顺序。通常 **`showlog.cgi`** 首先显示最新的条目。如果你启用“旧条目优先:”(右上角)的复选框,则首先显示最旧的条目。
这里表示的周期也取决于归档方法:如果你每天归档一次,每个网页将只获得一天的数据。要访问其他日期的条目,你必须使用图片顶部的箭头浏览日志文件的各个归档文件。

图 16-37. 一个蓝色按钮标记信息条目,图表从红色变为绿色表示 Nagios 重启,带有绿色勾选背景的 GO 图标表示监控系统的重启
## 16.2.15 评估你想要的任何内容:**`summary.cgi`**
如果迄今为止引入的显示和选择选项不足以满足你的需求,你可以使用 **`summary.cgi`** 创建自己的报告,该报告生成图 16-38 中显示的选择对话框。**标准报告:**部分提供了一个快速总结,其中只能选择一种固定的报告类型。点击此按钮下方直接生成的报告。
第二部分更为复杂。**报告类型:** 字段,与 **最近警报** 报告类型一起,提供了最后 **`n`** 个单独事件的个别列表。数字 **`n`** 在选择对话框的 **最大列表项数:** 下进一步定义。**报告类型:** 也可以用来在单独的一行上显示所有事件,使用 **最近警报**,或者您可以选择显示统计信息,例如总体发生的事件数量、每个主机组的数量等,使用 **警报总数、按主机组划分的警报总数** 等。
一个特别有趣的报告类型是 **顶级警报生成者**:此类报告显示在报告期间造成最多麻烦的人的点击列表。
在 **报告期间:** 您可以从预定义的间隔中选择所需的报告期间(本周、过去七天、本月、上周、上个月等),或者您可以选择 **`自定义报告期间`** 并定义您选择的任何时间段。如果您忘记明确指定 **`自定义报告期间`**,CGI 程序将忽略您设置的日期,并选择当前在 **报告期间** 中输入的内容。

图 16-38. `summary.cgi` 中参数的选择模板
随后的报告期间细节根据主机、服务或其组、状态类型和/或单个状态(例如,仅处于 CRITICAL 状态的服务)进行筛选。在最后指定 **最大列表项数** 很重要:**`summary.cgi`** 总是只显示在此处指定的条目数。默认值有点小;如果您想显示所选期间的所有条目,您应将值输入为 **`0`**。此处可以明确给出的最大值是 999。然后,**创建摘要报告!** 按钮生成所需的报告(图 16-39)。
报告的标题包含报告期间和所做选择的详细信息。表格直接上方的细节很有趣:**显示最近的 25 条,共 3721 条匹配警报**表明选择标准匹配了总共 3721 条条目,但由于 **最大列表项数** 的限制,CGI 脚本只输出了最近的 25 条条目。

图 16-39. 由 `summary.cgi` 生成的个人报告
## 16.2.16 随时间图形化跟踪:**`trends.Cgi`**
图形输出 **`trends.cgi`** (图 16-40) 提供了特定主机或服务何时发生状态的快速概述。选择特定的主机或服务后,可以定义一个周期,就像在 **`summary.cgi`** 中一样。状态由 **`trends.cgi`** 进行颜色编码,这使得概述更容易跟随。
CGI 程序的缩放功能是一个有趣的细节。如果你在特定部分的彩色区域点击,所选区域会根据右上角指定的缩放因子放大或缩小。负数输入(**`−1, −2, −3`** 和 **`−4`**)会扩展报告期而不是减少它。

图 16-40. `trends.cgi` 表示状态的时序序列——这里以服务为例
* * *
^([150]) [`lists.sourceforge.net/mailman/listinfo/nagios-users`](http://lists.sourceforge.net/mailman/listinfo/nagios-users)
^([151]) 如果您一直按照本书中的安装说明进行。
^([152]) [`nagios-demo.netways.de/`](http://nagios-demo.netways.de/)
^([153]) [`www.netways.de/`](http://www.netways.de/)
^([154]) **`/usr/local/nagios/share/docs/tuning.html`**
^([155]) [`netways.de/Demosystem.1621.0.html`](http://netways.de/Demosystem.1621.0.html)
^([156]) 虚拟现实标记语言(VRML),版本 2.0/1997,用于描述虚拟“空间”。
^([157]) **`/usr/local/nagios/share/docs/cgis.html#statuswrl_cgi`**
^([158]) [`www.parallelgrafics.com/products/cortona`](http://www.parallelgrafics.com/products/cortona)
^([159]) 对于 Firefox,您需要手动安装,在安装过程中选择 **自定义** 而不是 **典型**,并在 **不支持的浏览器** 中指定浏览器的插件目录。
^([160]) [`cic.nist.gov/vrml/vbdetect.html`](http://cic.nist.gov/vrml/vbdetect.html)
^([161]) [`www.openvrml.org/`](http://www.openvrml.org/)
^([162]) [`freewrl.sourcef orge. net/`](http://freewrl.%20sourcef%20orge.%20net/)
^([163]) 无线接入协议。
^([164]) 无线标记语言包含 HTML 的一部分,其功能大大减少。
^([165]) 在 **`nagios.cfg;`** 中的参数 **`log_initial_state`**,见第 597 页。
^([166]) 这里的细微差别在于**`retain_state_information`**(参见 A.1 主要配置文件 nagios.cfg)。如果此参数设置为 0,Nagios 会忘记之前的状态。如果没有**`log_initial_state = yes`**,Nagios 在重启后会接受 OK 状态。
^([167]) 因此,Nagios 在将状态分类为“硬”之前会重复测试四次。
^([168]) 如果报告期间的事件数量小于**最大列表项数**中指定的数量,则报告将涵盖此期间发生的所有事件。
# 16.3 计划停机时间
在每个系统环境维护工作中,管理员会时不时地积累一些可以正常计划的任务,以便提前通知用户。Nagios 将这些维护窗口称为*计划停机时间*;管理员可以在由**`extinfo.cgi`**(图 16-4, 第 331 页)或对应的主机或服务组(图 16-17, 第 339 页)生成的信息页面上输入这些信息。在此过程中,**`extinfo.cgi`**利用了**`cmd.cgi`**(16.2.3 外部命令接口:cmd.cgi, 第 343 页),该接口也可以选择性地调用:
http://nagiosserver/nagios/cgi-bin/cmd.cgi?cmd_typ=55
打开单个主机的维护时间导入模板。**`cmd_typ`**的值在图 16-24 中总结,第 344 页。
提供了另一种记录维护时间段的方法的插件,这些插件与 CGI 程序类似,使用外部命令接口,但可以自动化,与交互式 Web 界面相比。这样的插件也可以在 Nagios Exchange 上找到.^([169])
对于计划中的停机时间,Nagios 阻止发送通知。这确保管理员不会被虚假警报淹没。当检查是否应该发送消息时,停机时间是列表中的第三项(图 16-2 显示了主机停机时间的输入模板(**`cmd.cgi?cmd_typ=55`**)。

图 16-41. 在 Web 界面中,使用此对话框记录主机的停机时间
第一行定义了主机,而在第二行 Nagios 会自动输入您用于登录 Web 界面的登录信息。在 **注释** 关键字之后的输入字段中,您可以描述计划停机的原因。指定触发器可以显示它是否是通过其他条目间接生成的。在记录新的停机时间时,应将值保留为 **N/A**(即不可用,没有触发器)。
在接下来的四行中,您可以选择输入两种不同的停机类型:固定的(**类型:固定**)或可变的时间段(**灵活**)。第一种类型有一个固定的开始时间和结束时间。在这种情况下,Nagios 完全忽略 **灵活持续时间** 字段中的小时和分钟输入。
灵活的停机时间从指定时间段内首次事件发生时开始。从这一刻起,Nagios 根据此处指定的小时和分钟来规划停机时间。这可能会超过 **结束时间** 中指定的终点。
如果还有其他主机依赖于在 **主机名**:中指定的计算机(可能是因为涉及了路由器,其他主机对象已将其作为 **父对象** 进入),您可以使用最后一条项目,**子主机**:为所有子主机安排触发下线,将灵活的下线传递给所有“子主机”,**为所有子主机安排非触发下线** 对固定下线做同样处理,而 **对子主机不采取任何操作** 忽略依赖关系,这样 Nagios 就不会为除此处指定的主机以外的任何主机计划下线。
这种遗传行为如何在图 16-41 中生效,可以通过第 342 页上图 16-21 中所有计划下线的概述来展示。第一行包含刚刚描述的主机 **eli-saprouter** 的下线,其 **下线 ID** 为 **1**。由继承此超时引起的条目在 **触发 ID** 列中包含导致下线的 **下线 ID**:对于 **`sap-12`**,这是 **1**,因为 **`eli-saprouter`** 的维护也影响了此主机。
当计划下线时,Nagios 会同时生成一个注释条目,当这个时间段过去后,这个注释条目会自动被移除。这就是为什么在状态显示中会出现一个话泡。在下线期间,Nagios 会补充一个“呼噜声标志”,其目的是表示睡眠状态(图 16-42)。

图 16-42. 呼噜声标志 zzzzz 显示主机下线开始
## 16.3.2 服务下线
服务的下线与主机的下线在两个小细节上有所不同。除了主机名外,还必须包含服务描述,并且排除继承的可能性,因为服务没有相应的依赖关系。
主机宕机并不会自动影响到其上运行的服务。但既然主机宕机时这些服务也无法使用,建议您为所有依赖的服务规划相同的宕机时间。逐个服务地输入宕机时间可能会相当繁琐。使用主机组(**`cmd_typ=85`**)来做这件事会容易得多,如图 16-43 所示。使用这种方法,您可以仅用一个命令就为特定主机组中的服务定义宕机时间,以及更多:同时勾选**“也为主机安排宕机时间”**选项,将为该组中的所有主机定义相同的宕机时间.^([170])

Figure 16-43. 主机组中所有服务的单个宕机时间
* * *
^([169]) [`www.nagiosexchange.org/Downtimes.38.0.html`](http://www.nagiosexchange.org/Downtimes.38.0.html).
^([170]) 至少在 Nagios 版本 3.0rc1 之前,复选框没有任何效果;在那里,您必须再次运行**`cmd.cgi?cmd_typ=84`**来分别输入主机的宕机时间。
# 16.4 主机和服务的附加信息
通过为主机和服务的扩展信息,您可以在 Web 界面中包含额外的信息,并使用合适的图标来改善其外观。在 Nagios 2.x 中,有两个单独的对象来存储这些信息:**`hostextinfo`**和**`serviceextinfo`**。从 Nagios 3.0 开始,附加信息直接定义在主机和服务对象中。尽管 Nagios 3.0 仍然评估**`hostextinfo`**和**`serviceextinfo`**对象,但在检查配置时会发出警告信息,并将这些对象视为过时。
计划在版本 4 之前完全从 Nagios 中移除这些信息。首次使用 Nagios 3.0 的用户应直接在主机和服务定义中指定以下介绍的信息,并从一开始就省略**`hostextinfo`**和**`serviceextinfo`**。如果您正在从 Nagios 2.x 迁移到 Nagios 3.0,您无需担心这一点,并且可以继续使用这些对象的现有实例。
为了使这一点更清晰,以下我们将使用术语**`hostextinfo`**和**`serviceextinfo`**对象*信息*。对于 Nagios 2.x,该术语指的是相同名称的*对象*,而对于 Nagios 3.0,它指的是**`host`**和**`service`**对象中给出的相应*细节*。参数本身在 Nagios 2.x 和 3.0 中是相同的。对象信息仅影响 Web 界面,对 Nagios 的功能没有影响。
## 16.4.1 扩展主机信息
主机对象信息允许您通过链接和图标以及坐标形式的增强功能,在 Web 界面中通过附加功能来增强主机的显示:
Nagios 2.x # Nagios 3.0
define hostextinfo{ define host{
host_name linux01
notes Samba Primary Domaincontroller
notes_url /hosts/linux01.html
action_url /hosts/actions/linux01.html
icon_image base/linux40.png
icon_image_alt Linux Host
vrml_image base/linux40.png
statusmap_image base/linux40.gd2
2d_coords 120, 80
3d_coords 70.0,30.0,40.0
}
当这些参数被定义时,唯一必需的参数是主机的指定,即**`host_name`**;其余的都是可选的:
**`host_name`**
这是将要通过以下属性扩展其 Web 页面的主机对象的名称。
**`notes`**
使用此功能以获取**`extinfo.cgi`**在信息页面中考虑的附加信息。(上述示例中指定的条目,**Samba Primary Domaincontroller**,可以在 Linux 图标下方找到,图 16-44")))

图 16-44. `extinfo.cgi`同样在此处显示了 Linux 图标(括号中的 Tux)的替代文本以及参数`notes`的附加信息(在替代文本下方)
**`notes_url`**
这是包含有关所讨论主机额外信息的(HTML)文件的 URL,您可以通过图标链接到该文件,该图标以红色略为打开的手册形式呈现,既在状态概述中(图 16-45"))。如果涉及的主机文档存储在内联网中,那么维护合同、热线电话号码、系统配置等只需鼠标点击即可获得。
参数可能包含一个绝对路径(从 Web 服务器的视角来看)或一个完整的 URL(**`http://.`**..)。

图 16-45. 此细节视图显示了`notes_url`(打开,阅读手册)`action_url`(粉红色星星)和`icon_image`(此处,Linux 企鹅)的图标
**`action_url`**
这是一个指向为主机运行操作的链接,例如,通过仅点击鼠标即可执行 CGI 程序,如**`cmd.cgi`**。由于浏览器中的链接始终只是一个链接,因此这不必是一个命令,你也可以轻松地链接到另一个网页。在状态概览(图 16-45]]
**`icon_image_alt`**
如果浏览器没有显示图片(例如,对于阅读设备或点字输出设备),则会出现此图标的替代文本。从图标和图标文本细节中,Nagios 生成以下 HTML 代码:
IMG SRC= icon_image ALT=icon_image_alt>
**`vrml_image`**
这是在 3D 表示中象征主机图像的符号。允许的格式再次是 GIF、JPEG 或 PNG。你应该避免使用幻灯片,因为图像放置在一个立方体上,3D 界面中的透明部分可能会导致意外结果。
**`statusmap_image`**
这是**`statusmap.cgi`**(见 16.2.5 网络拓扑图:statusmap.cgi,第 346 页)在其拓扑图中表示主机的图像。Netways 的 Nagios 演示页面(^[172]),(图 16-28 在第 348 页)展示了很好的例子。
虽然允许使用 GIF、JPEG 和 PNG,但最好使用 GD2 格式,因为这样 Nagios 生成状态图所需的计算机时间更少。使用程序**`pngtogd2`**,该程序应作为大多数 Linux 发行版中 Thomas Boutell GD 库实用程序组件的一部分提供,可以轻松地将 PNG 文件转换。再次推荐 40×40 像素的图像大小。
**`2d_coords`**
此参数指定了拓扑图的用户定义布局的坐标。细节以像素为单位给出,原点**`(0, 0)`**位于左上角,并且值必须是正数:正 x 值表示从原点到右边的像素数,正 y 值表示从原点向下。
图 16-28 使用单个主机的固定坐标。如果状态图映射的布局与用户定义的不同,Nagios 会忽略**`2d_coords`**细节。
**`3d_coords`**
这些是 3D 表示的坐标。允许使用正负浮点数。**`(0.0,0.0,0.0)`**用作原点。在起始视图中,**`statuswrl.cgi`**调整 3D 图像的大小,以便所有现有主机都显示在屏幕上。因此,起始点在屏幕上的位置无法预测。
在 Nagios Exchange 中,**Logos and Images**类别中有大量成品图标。最好将它们解压缩到单独的子目录中,这样各个包就不会相互干扰:
linux:~ # cd /usr/local/nagios/share/images/logos
linux:images/logos # tar xvzf imagepak-base.tar.gz
base/aix.gd2
base/aix.gif
base/aix.jpg
base/aix.png
base/amiga.gd2
...
**`imagepak-base.tar.gz`**包含一组基本的图标选择,你可以根据需要用其他包进行补充。与本章开头对象定义一样创建的**`base`**子目录也必须包含在内。
## 16.4.2 扩展服务信息
扩展服务对象信息与主机等效对象信息大致相同,所以我们只提一下差异。除了主机名外,**`service_description`**中的服务描述是必需的,但 2D(状态图)和 3D 视图的详细信息被省略:
Nagios 2.x # Nagios 3.0
define serviceextinfo{ define service{
...
host_name linux01
service_description LPD
notes Linux Print Services
notes_url /hosts/linux01-lpd.html
action_url /hosts/linux01-lpd-action.html
icon_image base/hp-printer40.png
icon_image_alt Linux Print Server
}
与扩展主机信息相比,本例中的状态概述只显示在**`icon_image`**中指定的打印机图标,而不显示在**`notes_url`**和**`action_url`**中定义的两个图标。它们只会在**`extinfo.cgi`**生成的页面中显示,与扩展主机信息中的图标相同 (图 16-44"), 第 363 页)。
* * *
^([171]) 如果你一直遵循本书中建议的路径。
^([172]) [`nagios-demo.netways.de/`](http://nagios-demo.netways.de/)
^([173]) [`www.nagiosexchange.org/Image_Packs.75.0.html`](http://www.nagiosexchange.org/Image_Packs.75.0.html)
# 16.5 通过 Web 界面进行配置更改:重启问题
CGI 程序**`cmd.cgi`** (16.2.3 外部命令接口:cmd.cgi, 第 343 页)通过 Web 界面允许进行一系列当前配置的更改。^([174]) 以这种方式可以切换通知或主动检查等。
Nagios 不会将这些更改保存到相关的配置文件中,而是在单独定义的文件中记录当前状态,该文件使用**`nagios.cfg`**中的参数**`state_retention_file in nagios.cfg`** (参见 A.1 主配置文件 nagios.cfg). 但如果你在 Web 界面进行了许多更改后重启 Nagios 会发生什么?
Nagios 是否保留重启后所做的交互式更改,或者忘记它们,取决于配置文件**`nagios.cfg`**中的参数**`retain_state_informationin`** (A.1 主配置文件 nagios.cfg). 默认值**`0`**告诉系统忘记交互式更改。为了让 Nagios 记住这些更改,你必须设置
/etc/nagios/nagios.cfg
...
retain_state_information=1
...
但这又带来了一个新的问题:在 Web 界面中设置的配置项不会优先于配置文件中的详细信息。如果你为某个服务更改了那里的**`active_checks_enabled`**参数,配置文件中参数的方向就会被忽略,因为当前文件中用**`state_retention_file`**定义的临时存储设置将始终“胜出”。这种行为会影响所有可以通过界面更改的外部命令参数,因此也可以通过 CGI 程序**`cmd.cgi`**进行更改。Nagios 的原版文档^([175])用红色星号标记了这些参数。
在此情况下,有两种方法可以提供解决方案:一方面,你可以在重启前短暂地将参数**`retain_state_information`** 设置为**`0`**。然后,Nagios 在重启时会忘记所有更改,并从头开始读取配置文件。这种方法仅在特殊情况下推荐,因为在大型环境中几乎不可能完成配置文件中的所有交互式更改。另一方面,你可以养成习惯,每次在配置文件中做出更改时,都在 Web 界面中再次进行更改。虽然这会稍微增加一些工作量,但永远不会存在丢失当前设置,甚至可能是非常重要的设置的风险。
主机和服务的定义中还有两个额外的参数提供了微调的机会:
define host{
...
retain_status_information 1
retain_nonstatus_information 1
...
}
define service{
...
retain_status_information 1
retain_nonstatus_information 1
...
}
**`retain_status_information`** 指定主机或服务的当前状态是否应该在 Nagios 重启后继续存在:**`1`** 表示系统会临时存储状态,而**`0`** 表示它会忘记状态。对于状态来说,**`1`** 是一个更合理的值,你应该只在有正当理由的情况下偏离这个值。
另一方面,**`retain_nonstatus_information`** 指的是描述**无**状态的全部信息。例如,这包括是否启用了活动检查,是否允许被动检查,或者是否需要通知管理员此对象的状态变化。当值为**`1`**时,系统会临时存储这些信息,并在重启后再次使用;而当值为**`0`**时,Nagios 在重启时会忘记当前设置,并从配置文件中读取设置。
* * *
^([174]) 当进行此操作时,CGI 程序会使用外部命令文件接口。
^([175]) Nagios 2.x: **`/usr/local/nagios/share/docs/xodtemplate.html`**,Nagios 3.0: **`/usr/local/nagios/docs/objectdefinitions.html`**
# 16.6 使用 Nuvola 风格的现代布局
到目前为止所描述的 Nagios Web 界面的经典视图仅使用了少数 CGI 配置选项。然而,几乎不可能将更多项目放入左侧的导航栏中,该导航栏的外观已经变得有些业余。一个解决方案是使用 Nuvola 风格,如图图 16-46 所示。
实际 CGI 程序的布局——此示例显示了右侧图片中带有**`status.cgi`**的服务问题视图——不仅色彩丰富,还有新的图标。在图片的左侧,你可以看到相当优雅的导航,并配以相应的图标。然而,真正的亮点是使用基于 JavaScript 的菜单树:可以通过鼠标点击打开和关闭各个条目(例如,**首页**、**监控**、**报告**和**配置**等部分)。

图 16-46. 以 Nuvola 风格显示的 Nagios:此处显示的是服务问题
在安装 Nuvola 风格之前,必须备份 **`/usr/local/nagios/share`** 目录,以便如果你不喜欢新的设置,可以恢复旧设置。
NagiosExchange^([176]) 在印刷时的当前版本 1.0.3 是 2005 年 9 月的,但它与 Nagios 3.0 一起工作得非常好。内容被解压到一个合适的空目录中:
linux:~ # cd /usr/local/src; mkdir nuvola; cd nuvola
linux:src/nuvola # tar xvzfpfad/zu/nagios-nuvola-1.0.3.tar.gz
...
linux:src/nuvola # cd html
源文件包含在 Nagios 中已存在的文件(**`index.html, main.html`**)和目录(**`stylesheets, images`**),它们在安装过程中会覆盖原始文件。此外,Nuvola 风格包括一个新的子目录,**`side`**,其中包含树导航的实际 JavaScript 代码:
linux:nuvola/html # tree
|-- config.js
|-- images
| |
... ...
|-- index.html
|-- main.html
|-- side
| |-- apytmenu.css
| |-- apytmenu.js
| |-- apytmenu_data.js
... ...
| |-- dtree.css
| |-- dtree.js
| |-- dtree_data.js
... ...
| |-- icons
| | |
... ...
|-- sidel.html
'-- stylesheets
|
... ...
5 directories, 175 files
**`html`** 目录的内容简单地复制到 **`/usr/local/share`**,例如,使用 **`rsync:****
linux:nuvola/html # rsync -av. /usr/local/nagios/share/.
...
为了使新的导航出现,必须安装 **`sidel.html`** 文件。如果你只是将其重命名为 **`side.html`**,那么新版本的 Nagios 的 **`make install`** 将会再次覆盖它。因此,最好使用一个单独的索引文件,例如 **`index1.html`**,并从这个文件运行 Nagios Web 界面:
http://nagiosserver/nagios/index1.html
要完成这个任务,你需要将包含在 Nuvola 中的 **`index.html`** 文件复制到 Nagios 的 **`share`** 目录下,并命名为 **`index1.html:****
linux:nuvola/html # cp index.html/usr/local/nagios/share/index1.html
在 **`index1.html`** 文件中,你将 **`side.html`** 替换为 **`side1.html`**,以便调用 JavaScript 导航:
...
document.write('<FRAME SCROLLING="no" SRC="side1.html" NAME="side"
...
...
如果你认为像本书的作者一样,改变所有 CGI 程序的样式过于夸张,你可以只挑选改进的导航,并根据你的想法进行补充和重新设计。你不需要复制整个 **`html`** 目录,只需选择所需的文件即可:
linux:nuvola/html # cp -r side /usr/local/nagios/share/.
linux:nuvola/html # cp side1.html config.js/usr/local/nagios/share/.
linux:nuvola/html # cp index.html/usr/local/nagios/share/index1.html
你像我们刚才展示的那样更改 **`index1.html`** 文件,并检查 **`config.js:**** 中的 **`cgipath`** 变量
...
var cgipath = "/nagios/cgi-bin/";
...
Nuvola 使用现成的菜单树库,商业版本称为 **`apytmenu`**,^([177]) 这里将不讨论,或者免费版本 dTree.^([178)。dTree 是 **`config.js (treeType = 'dtree'`**) 中的默认设置,并且完全包含在内。菜单和树的配置在 **`side`** 目录下的 **`dtree_data.js`** 文件中完成。可以用 **Home** 菜单作为例子简要解释其基本原理:
general = new dTree('general');
general.header( 'Home', 'icon', ...);
general.add(0,-1);
general.add(1, 0,'Documentation','docs/index.html', ... );
document.write(general);
**`dTree`** 函数生成一个新的菜单树。它的参数是一个可自由选择的标识符(在这种情况下,**`general`**),用于引用树。**`general.header`** 设置菜单的标题为 **`Home`**。该函数还需要其他参数,包括一个图标(如图所示)。
第一个 **`general.add`** 调用将树仍锚定到待创建的状态。**`add`** 函数的前两个参数指的是要添加的节点编号,然后是其父节点编号。最顶层的节点称为 **`0`**,其下是 **`Documentation`** 条目,分配编号 **`1`**。如果 **`Documentation`** 本身要具有子节点,调用方式如下:
general.add(2, 1, 'new_entry', ...);
general.add(3, 1, 'new_entry', ...);
general.add(4, 1, 'new_entry', ...);
最后,**`document.write`** 构建整个菜单树。**`header`** 函数有以下参数:
menu_name. header(title, icon, height, background image, background color, open);
**``*`title`*``**
包含标题,也可以设置为 URL。点击标题会打开指定的超链接。
**``*`icon`*``**
指定显示在标题前面的图形的路径。
**``*`height`*``**
指定标题下方背景的高度。随后,可以指定此背景的属性,要么作为背景图像,使用 **``*`backgroundimage`*``**,要么作为颜色(**``*`background colorw`*``**)。
最后,**``*`open`*``** 指定菜单树在开始时应该是打开(**`1`**)还是关闭(**`0`**)。指定文本值的参数用单引号括起来,数值参数直接书写,如示例所示。
**`add`** 函数以类似的方式调用:
menu_name.add(id, pid, name,
url, title, target, icon,varlistentry58
iconOpen, open, css)
**``*`id`*``** 是节点编号,**``*`pid`*``** 是要整合的条目所在的节点编号。**``*`name`*``** 定义菜单中节点的名称,**``*`url`*``** 定义要调用的超链接。**``*`title`*``** 和 **``*`target`*``** 可选地指定通过 *url* 调用的页面标题和显示页面的目标框架。这两个参数通常在这里保持为空;目标框架的默认值——对于 Nagios 来说是正确的——是框架 **`main`**。
**``*`icon`*``** 定义放置在菜单条目前面的迷你图形,**``*`iconOpen`*``** 可选地包含在条目打开时替代它的另一个图标。**``*`open`*``** 再次定义在启动时条目应该是打开(值 **`1`**)还是关闭(值 **`0`**),**``*`css`*``** 可选地允许替代 CSS 定义。对于所有可选参数,以下适用:如果它们在末尾,可以省略,但如果它们后面跟有其他详细信息,省略必须用一对单引号(**``*`''`*``**)标记。
包含的文件 **``*`dtree_data.js`*``** 包含四个广泛的菜单。如果你处理 JavaScript 的经验不多,最好保存此模板并逐步调整。如果出现错误,信息非常稀少且通常具有误导性,因此特别重要的是要准确记录从一步到下一步所更改的内容,以便能够快速隔离错误。
在这一点上,我们再次提到 dTree 主页^([179)),它提供了带有代码摘录的示例,以及编程接口的描述。
对于本章中描述的 Nagios Web 界面的可能性不满意的人应该看看 NagVis (第十八章,第 389 页)。这个插件允许自由定义的界面,并以令人印象深刻的方式补充了标准 CGI。然而,NagVis 的前提是安装数据库接口 NDOUtils (第十七章,第 375 页),这稍微提高了安装门槛。
* * *
^([176]) [`www.nagiosexchange.org/75;252`](http://www.nagiosexchange.org/75;252)
^([177]) [`dhtml-menu.com/`](http://dhtml-menu.com/)
^([178]) [`www.destroydrop.com/javascripts/tree/`](http://www.destroydrop.com/javascripts/tree/)
^([179]) [`www.destroydrop.com/javascripts/tree/`](http://www.destroydrop.com/javascripts/tree/)
# 第十七章。使用 NDOUtils 的灵活 Web 界面
Nagios 2.x 和 3.0 的 Web 界面,如第十六章第 327 页第十六章中所述,对于拥有数百台主机的环境来说有一个关键缺点:它无法扩展。只要您只观察错误状态并密集地使用确认,您就可以使用基于 CGI 的 Web 界面管理得很好。但如果你试图显示数千个服务,你必须准备好等待——无论它们的状态如何。设置页面可能需要很长时间,然后实际工作几乎是不可能的。
Nagios 扩展与 CGI Web 界面有冲突,因为这直接评估 Nagios 内部,如对象配置、状态数据和日志文件。这意味着每个用于补充或替换 Web 界面的扩展都必须遵循这个逻辑。
解决这个问题的方案被称为 NDOUtils(*Nagios 数据对象工具*)。这些工具包括一些工具,它们将所有数据——从配置到事件和检查结果,再到历史记录——写入数据库,并通过统一的数据库模型提供。
将 NDOUtils 连接到 Nagios 的机制被称为*Nagios 事件代理*(NEB)。这为 Nagios 添加了一个模块化接口。NEB 在 Nagios 启动时加载扩展作为模块,这样模块就可以在不重新编译 Nagios 的情况下使用。这种方法类似于 Apache 模块,它们在需要时加载,并为 Web 服务器添加新功能。
NDOUtils 是 Nagios 未来基于 PHP 实现的 Web 界面的基础,预计从 Nagios 4.x 版本开始投入使用。然而,NagVis(见第十八章,第 389 页)已经提供了一个基于 NDOUtils 的替代 Web 界面。
# 17.1 事件代理
NEB 提供了一个基于共享库的 Nagios 与外部模块之间的接口。一个外部、应用程序依赖的模块提供了*回调函数*。Nagios 内核本身会为每个事件从加载的模块中调用相应的回调函数:如果没有匹配的函数,则不会发生任何操作。回调函数执行什么动作留给开发者想象:要么它自己执行某些操作,要么它将配置、状态和事件数据传递给外部应用程序,如图 17-1 所示。
对于数据传输到外部工具,可以使用 Unix 套接字或网络套接字,尽管也可以使用文件系统。应用程序进一步处理信息(例如,将其保存到数据库中,或通过 SNMP 陷阱发送消息,写入 syslog 等)。

图 17-1. 外部应用程序与加载的 NEB 模块通信
当回调函数被调用时,Nagios 会等待其完成。这意味着长时间的执行时间会阻碍系统。因此,回调函数应该始终将耗时的处理步骤留给外部应用程序,并限制于尽可能快地发送必要的信息。
构建事件代理模块应该留给经验丰富的程序员来做;普通人必须满足于使用现成的模块。NEB 模块可以通过主配置文件**`nagios.cfg:`**中的指令**`broker_module`**进行集成。
/etc/nagios/nagios.cfg
...
broker_module=module-with-path arguments
event_broker_options=-1
你是否将参数传递给模块取决于其具体实现。参数**`event_broker_options`**控制 Nagios 传递给事件代理模块的信息。使用选项**`−1`**表示所有信息,而值 0 则防止任何信息传递。通过 Nagios 源代码中的文件**`broker.h`**提供了一种选择性传递特定信息的替代方法:
/* broker.h from the Nagios sources /
...
/************** EVENT BROKER OPTIONS *****************/
define BROKER_NOTHING 0
define BROKER_EVERYTHING 1048575
define BROKER_PROGRAM_STATE 1 /* DONE */
...
define BROKER_DOWNTIME_DATA 512 /* DONE */
...
define BROKER_STATUS_DATA 4096 /* DONE */
...
define BROKER_RETENTION_DATA 32768 /* DONE */
define BROKER_ACKNOWLEDGEMENT_DATA 65536
表 17-1. 要传输到 NagVis 的数据
| 代理选项 | 值 | 说明 |
| --- | --- | --- |
| **`BROKER_PROGRAM_STATE`** | 1 | 程序是否是运行的 Nagios |
| **`BROKER_DOWNTIME_DATA`** | 512 | 计划维护期的详细信息 |
| **`BROKER_STATUS_DATA`** | 4096 | 所有检查的当前状态信息 |
| **`BROKER_RETENTION_DATA`** | 32768 | 为 Nagios 重启缓冲的数据 |
| **`BROKER_ACKNOWLEDGEMENT_DATA`** | 65536 | 确认已对主机和服务检查的错误状态进行的确认 |
在第十八章中介绍的 NagVis 1.1 需要表 17-1 中列出的信息。相应的数值总和为**`102913`**,因此可以修改**`event_broker_options`**如下,使其适合 NagVis:
/etc/nagios/nagios.cfg
...
event_broker_options=102913
关于事件代理的信息目前非常稀少。唯一描述接口的是来自 Nagios 2.0 的相当旧的文档和《Nagios 事件代理 API》^([180])。
* * *
^([180]) [`www.nagios.org/developerinfo`](http://www.nagios.org/developerinfo)
# 17.2 数据库接口
作为事件代理概念的具体和实用应用,Nagios 数据对象工具,或称 NDOUtils,将所有配置和事件数据保存到数据库中。为了能够使用数据库,还需要进一步的应用程序。对于 Nagios 4.x 版本,这很可能是基于 PHP 的新设计的 Web 界面。在新闻发布时(当时 Nagios 3.0 尚未完成),这个 Nagios 版本是否会立即管理数据库中的所有配置数据仍然是一个猜测。
对于数据库,NDOUtils 目前仅支持 MySQL;计划使用 PostgreSQL,但在本章节中引入的 1.4 版本中尚未实现。
由于 NDOUtils 插件提供了一个相对简单易用的数据库接口,预计它们与 Nagios 3.x 的使用将会增加。NagVis(下一章从第 389 页讨论)已经提供了一个强大的基于 NDO 的前端,在许多情况下可以替代状态图,该图相对简单,在 16.2.5 网络拓扑图:statusmap.cgi 中从第 346 页进行了讨论。
图 17-2 展示了 Nagios 数据可以导入到 NDOUtils 数据库的各种路径。Nagios 的数据导出由事件代理模块 ndomod 处理。它可以选择操作 TCP 或 Unix 套接字,或将数据写入文件。如果 Nagios 安装在与 NDOUtils 数据库相同的计算机上,Unix 套接字接口将提供最佳性能和最高安全性(与 TCP 套接字不同,Unix 套接字不能从网络上访问)。查询最终将数据写入数据库的 ndo2db 守护进程的套接字。
使用文件的方法涉及实用程序 FILE2SOCK,它读取文件并通过 TCP 或 Unix 套接字将数据传递给 nd02db 守护进程。FILE2SOCK 还可以从标准输入读取数据。

图 17-2. 如何将 Nagios 数据集成到 NDOUtils 数据库中?
对于每个数据库,您需要恰好一个 ndo2db 守护进程。如果有多个不同的客户端可以访问套接字接口,它将启动多个进程来处理这些。
程序 LOG2NDO 是 NDOUtils 之一。它从 Nagios 2.x 和 3.0 读取日志文件,并将这些数据传递给 ndo2db 守护进程——要么直接通过套接字接口,要么通过必须单独用 FILE2SOCK 导入的文件。如果您想将此类历史数据集成到数据库中,您将需要提供大量的存储空间,因为日志文件在存档时被压缩,但在数据库中以未压缩的形式保存。因此,当使用数据库管理时,日志文件会占用更多空间。
FILE2SOCK 和 LOG2NDO 主要用于导入历史数据。NagVis 稍后需要的数据由 Nagios 在非常短的时间间隔内更新。由于这里不需要历史数据,我们将不再详细描述这两个程序。
# 17.3 安装
由于在使用 MySQL 4.0 版本时,NDOUtils 数据库的一些表中的**`INSERT`**语句存在问题,因此最好从一开始就使用 MySQL 5。^([181]) 除了 MySQL 服务器包(在 Debian 中为“Etch” **`mysql-server-5.0`**) 和在服务器包安装过程中通常自动选择的库之外,您还需要相应的开发包(在 Debian 中为“Etch” **`libmysqlclient15-dev`**),以便能够编译 NDOUtils。
NDOUtils 与 Nagios 广泛集成的一个后果是版本必须与所使用的 Nagios 版本完全匹配。Nagios 和 NDOUtils 都在源代码中用宏**`CURRENT_OBJECT_STRUCTURE_VERSION`**定义它们的版本状态。该宏可以在 Nagios 源代码的文件**`./include/objects.h`**中找到(对于 Nagios 3.0,在本例中):
linux:src/nagios-3.0rc1 # fgrep CURRENT_OBJECT_STRUCTURE_VERSION
include/objects.h
define CURRENT_OBJECT_STRUCTURE_VERSION 307
NDOUtils 包包含两个包含文件,一个用于 Nagios 2.x,一个用于 Nagios 3.x:
linux:src/ndoutils-1.4b7 # fgrep CURRENT_OBJECT_STRUCTURE_VERSION
include/*/objects.h
include/nagios-2x/objects.h:#define CURRENT_OBJECT_STRUCTURE_VERSION 2
include/nagios-3x/objects.h:#define CURRENT_OBJECT_STRUCTURE_VERSION 307
如果 Nagios 的**`CURRENT_OBJECT_STRUCTURE_VERSION`**值与 NDOUtils 源代码中的两个值之一不匹配,NDOUtils 模块将卸载自己并拒绝执行。该过程在日志文件**`nagios.log`**中有记录,如下所示(两个不同的版本用粗体表示):
[1186152181] ndomod: NDOMOD 1.4b4 (06-19-2007) Copyright (c) 2005 -2007
Ethan Galstad (nagios@nagios.org)
[1186152181] ndomod: I've been compiled with support for revision 303 of
the internal Nagios object structures, but the Nagios daemon is currentl
y using revision 304. I'm going to unload so I don't cause any probl...
## 17.3.1 编译源代码
最新版本的 NDOUtils 代码可以从 Nagios 网页^([182])下载,然后解压到合适的目录:
linux:~ # cd /usr/local/src/nagios
linux:src/nagios # tar xvzf /path/to/ndoutils-1.4b7.tar.gz
...
linux:src/nagios # cd ndoutils-1.4b7
linux:nagios/ndoutils-1.4.b7 # ./configure --sysconfdir=/etc
...
linux:nagios/ndoutils-1.4.b7 # make
...
我们使用开关 **`--sysconfdir=/etc`** 启动 **`configure`** 运行,以便安装模块和守护进程的配置文件,以符合本书中的约定,即到目录 **`/etc/nagios`**。**`make`** 调用编译程序代码,然后手动完成安装:
linux:nagios/ndoutils-1.4.b7 # cd ./src
linux:ndoutils-1.4.b7/src # cp ndo2db-3x ndomod-3x.o log2ndo file2sock
/usr/local/nagios/bin/
对于 Nagios 2.x,守护进程 **`ndo2db-2x`** 和模块 **`ndomod-2x.o`** 被复制到 **`/usr/local/nagios/bin`** 而不是 3.x 版本。
## 17.3.2 准备 MySQL 数据库
在 MySQL 数据库系统中,我们需要一个存储用户 **`nagios`** 适当访问选项的数据库。为了设置这个数据库,我们首先以用户 **`root:`** 登录 MySQL。
user@linux:~$ mysql --user=root -p
Enter password: root-passwort_for_the_db
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1861
Server version: 5.0.32-Debian_7etch1 Debian etch distribution
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>
开关 **`-p`** 确保请求密码。以下命令测试是否设置了密码:
user@linux:~$ mysql --user=root
如果由该登录触发的操作没有错误消息,则 **`root`** 密码缺失。这应该使用以下命令指定:
user@linux:~$ /usr/bin/mysqladmin -u root password 'secret'
您应该用您自己的安全密码替换 **``*`secret`*``**。^([183)]
数据库(被命名为 **`nagios`**)使用 SQL 命令 **`CREATE DATABASE`** 创建,然后使用 **`GRANT:`** 给予所需的权限。
mysql> CREATE DATABASE nagios;
Query OK, 1 row affected (0.01 sec)
mysql> GRANT USAGE ON . TO 'nagios'@'localhost' IDENTIFIED BY 'secret'
WITH MAX_QUERIES_PER_HOUR 0
MAX_CONNECTIONS_PER_HOUR 0
MAX_UPDATES_PER_HOUR 0 ;
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON 'nagios'.*
TO 'nagios'@'localhost';
Query OK, 0 rows affected (0.01 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql> quit
**`GRANT USAGE`** 命令定义了用户及其密码,并指定对他来说,在每小时查询次数、数据库连接次数或数据库更新次数上没有限制。对于密码,选择比 **``*`secret`*``** 稍微安全一些的密码,但必须以纯文本形式写在这里。**`GRANT USAGE`** 还没有给 **`nagios`** 数据库的表提供任何访问权限。这由第二个 **`GRANT`** 命令处理。通过 **`FLUSH PRIVILEGES`** 激活对 **`nagios`** 用户权限的更改。
NDOUtils 需要 **`SELECT`**、**`INSERT`**、**`UPDATE`** 和 **`DELETE`** 权限。对于仅从数据库中读取数据的 NagVis 和其他应用程序,**`SELECT`** 权限就足够了。
在下一步中,将生成表格,NDOUtils 将在此之后保存数据。在 NDOUtils 源代码的 **`db`** 子目录中提供了一个用于此目的的完成 SQL 脚本,并且只需要执行:
user@linux:src/ndoutils-1.4b7$ cd db
user@linux:ndoutils-1.4b7/db$ mysql -u root -p nagios < mysql.sql
脚本应在所有情况下(即没有任何消息)正常运行。创建的表格可以使用 SQL 命令 **`show tables`** 显示。
各种发行版默认安装 MySQL 时会开启日志记录。与(通常是二进制)日志文件一起,可以复制或恢复数据库的当前状态。然而,与 NDOUtils 结合使用时,这些日志文件会迅速增长。如果您仅使用数据库进行 NDOUtils,您将只在罕见情况下需要此类工具,因此可以在 **`my.cnf`** 配置文件中注释掉所有 **`*log*`** 参数,并重新启动 MySQL——这次不进行日志记录。
## 17.3.3 升级数据库设计
由于 NDOUtils 正在积极开发中,因此不能排除对数据库结构的较大更改。对于升级,数据库设计可能也需要更改。NDOUtils 提供了一个脚本用于此目的,位于子目录 **`db`** 中的 **`upgradedb`**,它将自动调整表格:
linux:~ # cd /usr/local/src/nagios/ndoutils-1.4b7/db
linux:ndoutils-1.4b7/db # ./upgradedb -u root -p password
-h localhost -d nagios
Current database version: 1.4b5
****** DB upgrade required for 1.4b7
Using mysql-upgrade-1.4b5.sql for upgrade...
****** Upgrade to 1.4b7 complete
该脚本检测现有的 NDOUtils 版本,并相应地调整表格。其中之一是,它使用 SQL 命令 **`ALTER TABLE`**,对于在上一节中创建的 MySQL 用户 **`nagios`** 来说,权限不足。因此,脚本需要以 MySQL 用户 **`root`** 的身份运行。
* * *
^([181]) 作者已测试版本 5.0.23,但也有报告称 NDOUtils 与 MySQL 4.1.x 版本成功兼容。
^([182]) [`www.nagios.org/download/`](http://www.nagios.org/download/)
^([183]) 关于 MySQL 安全管理的更多说明,可以在在线文档 [`www.mysql.org/doc/refman/5.0/en/security-guidelines.html`](http://www.mysql.org/doc/refman/5.0/en/security-guidelines.html) 中找到,也可能在随分发版提供的文档中找到,位于 **`/usr/share/doc/`**。
# 17.4 配置
NDOUtils 在三个不同的位置进行配置。文件 **`ndomod.cfg`** 指定了事件代理模块的设置。**`ndo2db.cfg`** 控制守护进程 **`ndo2db`**,它从代理接收数据并将其写入数据库。**`/etc/nagios/nagios.cfg`** 中的条目最终确保 Nagios 启动时加载事件代理模块 **`ndomod`**。
子目录 **`./config`** 中的 NDOUtils 源代码为两个配置文件中的每一个提供了一个模板。该命令
linux:src/ndoutils-1.4b7 # cp config/ndo*.cfg /etc/nagios/.
根据本书中使用的惯例,将这些复制到目录 **`/etc/nagios`**。
## 17.4.1 调整事件代理配置
**`ndomod.cfg`** 的模板几乎可以不变地使用;您只需调整到 **`var`** 目录的路径:
/etc/nagios/ndomod.cfg
instance_name=default
output_type=unixsocket
output=/var/nagios/ndo.sock
tcp_port=5668
output_buffer_items=5000
buffer_file=/var/nagios/ndomod.tmp
file_rotation_command=rotate_ndo_log
file_rotation_interval=14400
file_rotation_timeout=60
reconnect_interval=15
reconnect_warning_interval=15
data_processing_options=-1
config_output_options=2
**`instance_name`** 指的是数据库中要使用的实例。如果您在数据库中只映射一个 Nagios 实例,则可以保持 **`default`** 设置。假设 Nagios 和 **`ndo2db`** 守护进程运行在同一个主机上,可以使用 Unix 套接字作为 **`output_type`**,其名称由 **`output`** 参数定义。**`tcp_port`** 仅用于 **`output_type=tcpsocket`**,因此被注释掉。
如果 **`ndomod`** 模块无法通过套接字接口释放数据(例如,守护进程刚刚重启),这些数据将暂时保存在文件 **`buffer_file`** 中。在 **`output_buffer_items`** 参数中要保存的条目数不应设置得太低。这里的一个经验法则是将所有定义的主机和服务的数量乘以五。这是一个经验值:当重新加载或 Nagios 重新启动时,NDOUtils 将每个主机和每个服务的起始状态写入数据库,以及所有计划的和已开始的检查。这些可能还会补充新的或仍在进行的检查的结果。
**`file_rotation_*`** 参数仅在 **`output_type=file`** 时需要,这需要使用额外的守护进程 **`FILE2SOCK`**。然而,出于性能考虑,建议您使用套接字接口而不是基于文件的接口。由于额外的守护进程,文件接口也使得配置更加复杂。
参数 **`reconnect_interval`** 和 **`reconnect_warning_interval`** 也适用于无法建立使用 **`ndo2db`** 守护进程的连接的情况。它们指定了 Nagios 多久尝试与他们建立联系,以及如果无法建立连接,日志文件中多久出现一次警告。这两个参数应保留为默认值。
## 17.4.2 配置数据库访问
对于 **`ndo2db`** 守护进程的配置文件模板,几乎没有需要调整的地方。除了套接字接口的路径外,还必须指定对数据库进行写访问的相关密码:
/etc/nagios/ndo2db.cfg
ndo2db_user=nagios
ndo2db_group=nagios
socket_type=unix
socket_name=/var/nagios/ndo.sock
tcp_port=5668
db_servertype=mysql
db_host=localhost
db_port=3306
db_name=nagios
db_prefix=nagios_
db_user=nagios
db_pass=secret
max_timedevents_age=1440
max_systemcommands_age=1440
max_servicechecks_age=1440
max_hostchecks_age=1440
max_eventhandlers_age=10080
两个 **`ndo2db_*`** 参数指定了守护进程启动后运行的用户和组权限。**`socket_type`** 和 **`socket_name`** 必须设置为 **`ndomod.cfg`** 中的配置。
当前可以指定的唯一数据库类型是 **`db_servertype`** 的 **`mysql`**;对于 **`db_port`**,通常输入 MySQL 的标准端口(**`3306`**)。在 **`db_name`** 中的数据库名称必须与在 **`CREATE DATABASE`** 命令中选择的名称匹配(在这种情况下,**`nagios`**),并且数据库用户和密码也必须以与设置数据库时相同的方式给出。在任何情况下都不应更改 **`db_prefix`** 参数的值,否则在 **`mysql.sql`** 脚本中创建的表的名称也必须进行调整。
以 **`max_*`** 开头的参数定义了 NDOUtils 数据在系统命令、计划事件、服务和主机检查以及事件处理程序中应在数据库中保留多长时间(以分钟为单位)。值 1440 对应于一天。如果您仅使用 NagVis 与 NDOUtils,则不需要更长时间。短间隔对数据库和硬盘都较为友好。
## 17.4.3 启动 **`ndo2db`** 守护进程
当一切配置完成后,首先手动调用**`ndo2db`**守护进程:
/usr/local/nagios/bin/ndo2db-3x -c /etc/nagios/ndo2db.cfg
之后,建议您通过复制和修改分发中提供的脚本**`/etc/init.d/skeleton`**来创建一个 init 脚本。守护进程必须与 Nagios 版本匹配:**`ndo2db-3x`**与 Nagios 版本 3.x 一起工作,**`ndo2db-2x`**与版本 2.x 一起工作。启动后,您应该检查配置中指定的套接字是否存在:
linux:~ # ls -l /var/nagios/ndo.sock
srwxr-xr-x 1 nagios nagios 0 Jul 18 21:16 /var/nagios/ndo.sock
如果在运行守护进程时出现**`Socket already in use`**消息,那么要么守护进程已经在运行,要么在守护进程停止时没有移除套接字**`ndo.sock`**。在这种情况下,您应该在重新启动之前手动删除它。
## 17.4.4 在 Nagios 中加载事件代理模块
为了使 Nagios 在启动时加载 NDOUtils 的事件代理模块,以下条目被添加到配置文件**`/etc/nagios/nagios.cfg:`**
/etc/nagios/nagios.cfg:
...
=== NDO ===
broker_module=/usr/local/nagios/bin/ndomod-3x.o config_file=/etc/nagios/
ndomod.cfg
在此示例中使用了 Nagios 版本 3.x 的模块;如果您使用的是 Nagios 2.x,则输入**`ndomod-2x.o`**。重新加载激活模块:
linux:~ # /etc/init.d/nagios reload
在重新加载后不久,所有主机和服务对象都应该记录在数据库中:
user@linux:~$ mysql --user=nagios -p nagios
mysql> select name1,name2 from nagios_objects WHERE objecttype_id=2 ;
+---------+----------------------+
| name1 | name2 |
+---------+----------------------+
| AHDC01 | CPU_LOAD |
| AHDC01 | DISK_C |
| AHDC01 | DISK_D |
...
表**`nagios_objects`**包含所有对象,**`objecttype_id=2`**显示所有服务。或者对象类型**`1`**指代主机,**`3`**指代主机组,**`4`**指代服务组。关于表的完整描述可以在 NDOUtils 中包含的文件**`NDOUTILS DB Model.pdf`**中找到,该文件位于子目录**`./docs`**中。
* * *
^([184]) 关于事件处理器,请参阅第 619 页的附录 C(附录 C. 事件处理器)
# 第十八章. NagVis
NagVis^([185]) 是 Nagios 的一个插件,它将用户选择背景图像显示主机和服务状态。这必须是 PNG 格式;您可以选择使用地图、您自己的系统文档图、服务器室的照片或系统环境的示意图作为背景,如图图 18-1 所示。
通过 Web 界面,您可以在背景上放置任何您想要的对象。NagVis 根据对象的状态显示不同的图标:红色表示 CRITICAL 状态,黄色表示 WARNING,绿色表示 OK,灰色背景上的问号表示 UNKNOWN。如果设置了确认,则通过带有工人图片的绿色按钮表示。
主机和服务的图标不同;在默认模板中,主机图标是矩形的,而服务图标是圆形的。完成的 NagVis 显示——NagVis 将其称为 *地图*——在 图 18-2 中显示。NagVis 主页上提供了更多示例——例如使用地理地图或服务器室的照片作为背景。^([186)]

图 18-1. 作为 NagVis 模板的系统环境示意图
除了主机和服务外,主机和服务组还可以集成到 NagVis 显示中,以及额外的地图。因此,可以使用地理概览图作为起始页面,每个监控位置的图标都链接到针对该位置的详细 NagVis 地图。
如果一个图标包含多个状态,例如主机和服务组,NagVis 会显示具有最高优先级的状态,其中 CRITICAL 的优先级高于 WARNING,WARNING 胜过 UNKNOWN,UNKNOWN 比确认得到更多关注,而 OK 是所有状态中优先级最低的。如果主机组中的任何主机处于 CRITICAL 状态,整个主机组都会相应地显示。
对于主机和主机组,NagVis 提供了选择仅考虑主机状态以确定显示状态,或者包括依赖于这些主机的服务(参见 18.1.2 初始配置)。在后一种情况下,如果主机的任何一个服务处于关键状态,则会显示一个红色的停止灯。
特别值得注意的是 NagVis 只评估硬状态的能力(参见 18.1.2 初始配置)。对于使用 Web 界面的常规工作,如果并非每个临时的软 CRITICAL 状态都立即生成红灯,这会非常有用。

图 18-2. 显示系统环境
特别会让面向对象编程的粉丝感到高兴的是,NagVis 充分利用了面向对象的概念。例如,系统从全局配置继承默认值,用于单个地图和地图级别的设置,并将这些值传递给单个对象,同时始终可以选择在本地覆盖设置。这在很大程度上简化了配置,NagVis 还在图形编辑器(也称为 *Web 用户界面* 或 WUI)中指出了哪些设置是针对对象的,哪些是继承的(图 18-8 下发布;下面的描述指的是版本 1.3。
# 18.1 安装
NagVis 使用 NDOUtils 并用 PHP 实现。因此,除了 第十七章]) 根据发行版和使用的 PHP 版本,包名可能会有所不同。对于 Debian "Etch" 和 PHP5,您需要 **`libapache2-mod-php5, php5, php5-common, php5-gd`** 和 **`php5-mysql`** 包。
虽然在许多情况下它们被打包在同一台主机上,但 NagVis 不一定必须安装在 Nagios 和 NDOUtils 相同的计算机上。NDO 数据库的配置——NagVis 文档将其称为 *后端*——可以引用(如 18.1.2 初始配置,解压到您选择的目录中:
linux:~ # tar xvzf /pfad/zu/nagvis-1.3.tar.gz
...
如果存在先前的安装,您应该首先备份它。然后,您将创建的目录(在我们的例子中,**`nagvis-1.3`**)以名称 **`nagvis`** 复制到 **`/usr/local/nagios/share:`**
linux:~ # mv nagvis-1.3 /usr/local/nagios/share/nagvis
linux:~ # ls -F /usr/local/nagios/share/nagvis
INSTALL LICENCE README config.php etc/ index.php nagvis/ var/ wui/
重复的目录名称 **`nagvis`** 有时会导致混淆,但这是正确的:
/usr/local/nagios/share/nagvis
/usr/local/nagios/share/nagvis/nagvis
/usr/local/nagios/share/nagvis/wui
**`/usr/local/nagios/share/nagvis`** 代表 NagVis 安装的根目录,而子目录 **`nagvis`** 包含 NagVis 应用程序及其配置。最后,子目录 **`wui`** 包含图形编辑器,它允许通过浏览器编辑 NagVis 地图。
目前,必须手动设置目录和文件的正确访问权限。为此,您首先需要确定 Web 服务器运行的用户的权限(也参见 1.2 编译源代码,第 39 页):
linux:~ # grep "^User" /etc/apache2/apache2.conf
User www-data
linux:~ # id www-data
uid=33(www-data) gid=33(www-data) Groups=33 (www=data),9001 (nagcmd)
第一个 **`grep`** 命令在 Web 服务器(在此情况下,Apache2)的配置文件中查找相应的用户,然后 **`id`** 命令搜索此用户的初始组。这可以在 **`gid=`** 指定之后找到。现在将根据这些权限设置访问权限:
linux:~ # chown www-data.www-data -R /usr/local/nagios/share/nagvis
linux:~ # chmod 664 /usr/local/nagios/share/nagvis/etc/nagvis.ini.php
linux:~ # chmod 775 /usr/local/nagios/share/nagvis/nagvis/images/maps
linux:~ # chmod 664 /usr/local/nagios/share/nagvis/nagvis/images/maps/*
linux:~ # chmod 775 /usr/local/nagios/share/nagvis/etc/maps
linux:~ # chmod 664 /usr/local/nagios/share/nagvis/etc/maps/*
linux:~ # chmod 775 /usr/local/nagios/share/nagvis/var
linux:~ # chmod 664 /usr/local/nagios/share/nagvis/var/*
在可以使用 Web 用户界面之前,您必须创建中央配置文件并确保只有经过成功认证后才能访问 NagVis。
## 18.1.2 初始配置
中央 NagVis 配置文件 **`config.ini.php`** 的模板可以在目录 **`/usr/local/nagios/share/nagvis/etc`** 中找到,只需重命名和修改即可:
linux:~ # cd /usr/local/nagios/share/nagvis/etc
linux:nagvis/etc # cp config.ini.php.dist config.ini.php
linux:nagvis/etc # chown www-data.www-data config.ini.php
linux:nagvis/etc # chmod 664 config.ini.php
命令 **`chown`** 和 **`chmod`** 确保为 Web 用户(在此处,**`www-data`**)及其组设置了正确的访问权限。
除了后端(即 NDO 数据库)的配置之外,包含的 **`config.ini.php`** 已经有可用的默认值。因此,以下描述仅限于介绍最重要的参数:^([188])
[global]
language="german"
refreshtime=60
在 **`[global]`** 部分中,您可以使用 **`language`** 设置语言;默认为 **`english`**。`refreshtime` 定义浏览器中显示刷新的秒数。
部分 **`[defaults]`** 指定了从映射配置继承的默认值。如果需要,可以通过映射覆盖这些值。最好在这里定义大多数对象都相同的设置,以避免在对象定义中重复明确地定义它们:
[defaults]
backend="ndomy_1"
icons="std_medium"
recognizeservices=1
onlyhardstates=1
**`backend`** 指定用作默认后端的 NDO 数据库。此名称可以是任何您喜欢的,但后端本身必须在单独的部分中定义(参见 18.1.2 初始配置)。如果您刚开始,最好保留提供的名称,**`ndomy_1`**。
参数 **`icons`** 定义了要使用的图标集,该图标集位于目录 **`./nagvis/nagvis/images/iconsets`** 中。包含四个集合:**`std_small, std_medium, std_big`** 和 **`folder`**。其他图标可以从 NagVis 主页下载,^([189]) 或者您可以自己创建它们.^([190])
设置 **`recognizeserivces=1`** 确保在确定整体状态时,包括伴随服务的当前状态。值 0 关闭此行为。
另一方面,**`onlyhardstates=1`**指示 NagVis 只考虑硬状态。默认值**`0`**也包括软状态。
**`[wui]`**部分允许为 NagVis 编辑器设置参数:
[wui]
autoupdatefreq=25
maplocktime=5
**`autoupdatefreq`**确定 Web 用户界面自动保存更改的频率(以秒为单位),而**`maplocktime`**指定在当前正在编辑的地图上进一步更改应被阻止的分钟数,从上次更改的时间起。这是为了防止多个用户同时编辑同一地图。
从文件系统(**`base`**)的角度以及从浏览器角度分别针对 NagVis 数据和 NagVis CGIs,NagVis 安装的路径在**`[paths]`**部分指定:
[paths]
base="/usr/local/nagios/share/nagvis/"
htmlbase="/nagios/nagvis"
htmlcgi="/nagios/cgi-bin"
此处列出的默认值与上述标准安装相匹配。
后端配置,即访问 NDO 数据库的配置,位于文件底部:
[backend_ndomy_1]
backendtype="ndomy"
dbhost="localhost"
dbport=3306
dbname="nagios"
dbuser="nagios"
dbpass="verysecret"
dbprefix="nagios_"
dbinstancename="default"
maxtimewithoutupdate=180
本节名称必须包含在`[defaults]`下通过**`backend`**参数指定的名称,根据模式**`[backend_`****``*`value_of_backend]`*``**。默认值此处为**`ndomy_1`**。如果**`backend`**参数值与定义的任何后端部分不匹配,NagVis 将拒绝工作。
**`backendtype`**定义后端类型,目前**`ndomy`**——基于 MySQL 的 NDO 数据库——是唯一可能的值。
**`dbhost`**和**`dbport`**指定数据库访问的主机名或 IP 地址以及相应的 TCP 端口。**`dbname`**包含 NDO 数据库的名称,而**`dbuser`**和**`dbpass`**提供了访问的用户名和密码。
默认定义的**`dbprefix`**和**`dbinstancename`**值适用于 NDOUtils 标准安装。假设你没有在文件**`ndomod.cfg`**(见 17.4.1 调整事件代理配置第 384 页)中更改参数**`instance_name`**,以及在文件**`ndo2db.cfg`**(见 17.4.2 配置数据库访问第 385 页)中更改**`db_prefix`**,你可以使用此处给出的值。
你应该特别注意的一个参数是**`maxtime-withoutupdate:`**。这定义了允许 Nagios 状态更新的秒数。如果此处指定的超时时间被超过,NagVis 假定数据已过时,并将其显示为错误。如果 NagVis 访问分布在多个服务器上的 NDO 数据库,服务器之间的时钟时间必须相互同步,否则如果 NagVis 遇到大于**`maxtimewithoutupdate`**秒的时间差,它将拒绝工作。
在这一点上,我们将提到另一个涉及 NDO 数据库与 NagVis 之间数据交换的问题:NagVis 评估当前程序状态。然而,在 3.0b1 之前的 Nagios 版本中,它仅在夜间日志文件更改后将其写入 NDO 数据库。从 3.0b1 版本开始,Nagios 每五秒更新一次状态,这样 NagVis 总是有最新的信息。
## 18.1.3 用户身份验证
NagVis 要求用户进行身份验证。如果没有用户身份验证,它将只显示错误消息.^([191])
如果 Nagios 的**`share`**目录不可用于身份验证,例如在 1.5.1 设置 Apache 中的 Apache 配置中,您应该在 Apache 配置文件**`/etc/apache2/conf.d/nagios`**中进行更改。认证数据最好从 CGI 目录中获取(参见第 47 页的 1.5 配置 Web 界面)。

图 18-3。在点击显示的图形后,将出现菜单
* * *
^([185]) [`www.nagvis.org/`](http://www.nagvis.org/)
^([186]) [`www.nagvis.org/screenshots`](http://www.nagvis.org/screenshots)
^([187]) 如果在 NagVis 配置文件**`config.ini.php`**(参见 18.1.1 安装源代码)中将参数**`usedgdlibs`**设置为**`0`**,则可以不使用 GD 库来管理。
^([188]) 完整的文档可以在[`www.nagvis.org/docs/1.3/nagvis_config_format_description`](http://www.nagvis.org/docs/1.3/nagvis_config_format_description)找到。
^([189]) [`www.nagvis.org/downloads`](http://www.nagvis.org/downloads)
^([190]) 相应的指南可以在[`www.nagvis.org/docs/extending/iconsets`](http://www.nagvis.org/docs/extending/iconsets)找到。
^([191]) FAQ 条目[`www.nagvis.org/docs/general/faq#how/to/run/nagvis/without/authentication/`](http://www.nagvis.org/docs/general/faq#how/to/run/nagvis/without/authentication/)描述了在不进行身份验证的情况下使用 NagVis 的方法,但出于安全考虑,您应该避免这样做。
# 18.2 创建 NagVis 地图
通过 URL [`nagiosserver/nagios/wui/index.php`](http://nagiosserver/nagios/wui/index.php) 访问 NagVis 配置界面。在这里,您将**``*`nagiosserver`*``**替换为您自己的 Nagios 主机名(图 18-3 显示了起始页面)。
它通过在您点击右键鼠标按钮时打开的菜单来操作。对于将 NagVis 菜单与其自己的菜单叠加的浏览器,第二次右键单击鼠标按钮将导致浏览器菜单消失。
如果您没有可用的 PNG 格式的合适背景图形,您可以通过菜单项**管理 | 背景**(如图图 18-4
图 18-4。创建一个新的空背景
此图像以原始大小显示在屏幕上,即未缩放。为了避免滚动,它不应太大,适当的大小取决于屏幕分辨率,并考虑可能的窗口边框。
之后,图像大小只能有限度地更改:尽管您可以随时上传或创建背景图像,但已经放置的对象不会受到背景大小或其他特性的任何更改的影响,因此它们可能无法正确地适应新的背景图像。此时唯一的选择是重新定位所有对象。最佳方法是首先在最终环境中仅使用少数几个对象进行实验,然后再设置广泛的地图。

图 18-5。如果地图图标集的条目为空,NagVis 将使用中央配置的默认值。
您现在为生成的或上传的图像创建一个新的地图。通过菜单项**管理 | 地图**(图 18-3 直接调用它。

图 18-6. 通过图形界面插入对象
在 图 18-5 中创建的地图的 **``*`mapname`*``** 为 **`Test`**。在地图本身中,你现在可以使用鼠标右键插入对象(见 图 18-6). 对象可以是图标、线条或特殊对象。图标和线条代表主机或服务的当前状态,也可以代表整个主机或服务组。图标只能反映地图的整体状态。特殊对象是表示无状态对象(例如,也可能是图标)或文本框的图形,这些文本框也可以提供超链接。
要插入主机组,请在菜单中选择 **添加对象 | 图标 | 主机组**。然后,将鼠标放在所需位置,并用鼠标左键定义图标的目的地(位置可以在以后更改)。
完成此操作后,将打开一个对话框,如图 18-7 所示。条目 **backend_id** 可以保持为空,此时 NagVis 将使用中央配置文件 **`config.php.ini`** 中的 **`backend`** 参数的值。在 **hostgroup_name** 下拉菜单中,NagVis 允许您从所有定义的主机组中选择。
可以通过输入数值或使用鼠标来根据 **x** 和 **y** 坐标定位图标。对于简单的图标,点 (x, y) 对应于中心,对于线条对应于起点或终点。z 坐标仅在图标重叠时使用。值 **`0`** 描述的是后面的底层图像,并保留用于背景,而具有最高 **z** 值的对象就在最前面。如果插入对象时显式地留空 **z** 坐标,它将自动接收值 **`1`**。

图 18-7. 在图形界面中定义主机组
参数 **`recognize_services`** 允许覆盖 **`config.ini.php`** 中的 **`recognizeservices`** 设置(见 18.1.2 初始配置),而 **`only_hard_states`** 对参数 **`onlyhardstates`** 执行相同的操作(18.1.2 初始配置)。
以这种方式插入的对象始终以所选图标集中的 OK 图标的形式出现在图形编辑器中;Web 界面不考虑其实际状态。
如果将鼠标移至图标上,将打开一个悬停菜单,如图图 18-8 所示。它清楚地区分了哪些设置是继承的,哪些是在对象中直接指定的。如果您点击那里的**更改**链接,可以再次更改设置。

图 18-8. 如果将鼠标移至插入的对象上,将打开一个悬停菜单
当您的工作完成时,不要忘记通过上下文菜单中的**保存**(见第 396 页的图 18-3)保存您的更改)。然后,**在 NagVis 中打开地图**菜单项将带您进入完成后的视图,现在它确实显示了实际状态。
在图 18-9 中,已为主机组图标添加了一个文本框。在此文本框下方显示的字段是一个悬停菜单,当鼠标移至对象上时,它会显示关于对象及其状态的信息。本例显示,主机组中的两个主机显示为“不正常”状态,并且这已经通过确认得到了证实。

图 18-9. 最终视图中带有文本框和悬停菜单的对象
完成的地图可以通过 URL 直接调用[`nagiosserver/nagios/nagvis/nagvis/index.php?map=mapname`](http://nagiosserver/nagios/nagvis/nagvis/index.php?map=mapname)。
## 18.2.1 以文本形式编辑配置
NagVis 将地图的整个配置存储在文本文件中,这些文件也可以使用文本编辑器进行编辑。这些文件位于目录**`/usr/local/nagios/share/nagvis/etc/maps/`**中。如果您使用的是已知栅格的背景图像,您可以在 WUI 中插入多个对象,并使用刚刚确定的坐标在编辑器中继续编辑地图。这就是图 18-2 中显示的地图是如何创建的。背景图像(图 18-1)是用 OpenOffice 创建的,以便获得可重复的栅格;OpenOffice 绘图随后导出为 PNG 文件。
文本文件的配置选项,总体来说非常广泛,已在在线文档中描述.^([192])
## 18.2.2 将 NagVis 地图添加到 Nagios Web 界面
NagVis 地图也可以集成到 Nagios Web 界面中。图 18-10 显示了在**`index.html`**页面添加了第三个框架之后的情况,该框架将一个 32 像素高的地图绑定在主窗口下方。无论管理员当前在做什么,最重要的状态(在这里是主机组)总是直接显示,并且可以通过单次鼠标点击访问。使用 NagVis 时,你的用户界面梦想没有限制!

图 18-10. NagVis 地图作为 Nagios Web 界面中的“脚注”
* * *
^([192]) [`www.nagvis.org/docs`](http://www.nagvis.org/docs)
# 第十九章. 性能数据的图形显示
当 Nagios 快速且选择性地向管理员报告发生的问题时,它基本上只能区分 OK 状态和错误状态,从而避免了管理员收到有关有问题的服务和主机的信息洪水。在一段时间内测量值的图形显示不能集成到这种“交通灯方法”中,但可以通过第三方软件实现。Nagios 支持通过为此创建的接口进行外部处理值。通过它处理的数据在 Nagios 术语中被称为*性能数据*。
Nagios 有两种不同类的性能数据。第一类是 Nagios 内部性能数据,包括测试性能时间统计以及实际测试时间与计划时间之间的差异(*延迟*)。第二类包括插件与测试结果一起传递的性能数据。这包括插件可以测量的所有内容:响应时间、硬盘使用情况、系统负载等。这些都是管理员感兴趣的事情,这也是为什么本书专注于如何处理它们。
Nagios 提取这些数据,要么将其写入文件以便其他程序处理,要么直接传递给在每次服务或主机检查之后运行的第三方软件。
# 19.1 使用 Nagios 处理插件性能数据
只有当相应的插件以预定义的格式提供时,服务检查和主机检查提供的性能数据才能被处理。如图所示,使用**`check_icmp`**插件(6.2 使用 Ping 进行可达性测试, 第 108 页),它以**`|`**符号开头,并且在 Web 界面中不显示:
nagios@linux:libexec/nagios$ ./check_icmp -H vpn01
OK - eli02: rta 96.387ms, lost 0%| rta=96.387ms;200.000;500.000;0; pl=0%;
40;80;;
这种标准化形式在大多数插件中仅在版本 1.4 之后提供.^([193]) 性能数据本身由以下形式的一个或多个变量组成:
name= value ; warn ; crit;min; max
变量 **``*`name`*``** 可以包含空格,但此时它必须被单引号包围。等号之后首先是作为整数或浮点小数的测量值,可以带或不带单位。可能的单位有 **`%`**(百分比)、**`s`**(秒)、**`B`**(字节大小)或 **`c`**(计数器,一个增量计数器)。
此后,由分号分隔,接着是警告和临界限制,然后是最小和最大值。插件可以省略百分比值。您也可以为最小/最大值、警告或临界限制指定 **`0`**,如果不存在此类阈值值。如果有多个变量,它们可以用空格分隔,如 **`check_icmp`** 示例所示。然而,与此相反,最后的指定不应以分号结束,根据开发者指南。
## 19.1.1 模板机制
Nagios 有两种处理性能数据的方法:要么系统使用一个 *模板* 将数据保存到文件中,要么执行一个外部命令。如果您只想将数据持续写入日志文件,模板过程配置起来相对容易一些。
为了使 Nagios 能够处理所有性能数据,该参数
/etc/nagios/nagios.cfg
...
process_performance_data=1
...
必须设置为 **`1`**。Nagios 将主机或服务性能数据写入的文件由参数 **`host_perfdata_file`** 和 **`service_perfdata_file:`**
/etc/nagios/nagios.cfg
...
host_perfdata_file=/var/nagios/host-perfdata.dat
service_perfdata_file=/var/nagios/service-perfdata.dat
host_perfdata_file_template=[HOSTPERFDATA]\t\(TIMET\)\t\(HOSTNAME\)\t$HOST
EXECUTIONTIME\(\t\)HOSTOUTPUT\(\t\)HOSTPERFDATA\(
service_perfdata_file_template=[SERVICEPERFDATA]\t\)TIMET\(\t\)HOSTNAME\(\t\)
SERVICEDESC\(\t\)SERVICEEXECUTIONTIME\(\t\)SERVICELATENCY\(\t\)SERVICEOUTPUT\(\
t\)SERVICEPERFDATA$
...
如果 **`host_perf data_file`** 被注释掉,如本例所示,Nagios 不会保存任何主机检查的性能数据。但鉴于它们仅在所有服务检查失败时才使用,主机检查的本质在于它们只提供零星且不规律的数据。这就是为什么在大多数情况下不值得评估它们的原因。
**`*_perf data_file_template`** 参数定义了输出格式。上面显示的定义,**`service_perfdata_file_template`**,以以下模式提供(单行)日志文件条目:
[SERVICEPERFDATA] 1114353266 linux01 PING 0.483 0.104 OK
- 10.128.254.12: rta 100.436ms, lost 0% rta=100.436ms;3000.000;6000.000
;0; pl=0%;40;80;;
每一行以一个 **`[SERVICEPERFDATA]`** “戳记”开始,后面跟着测试时间(以纪元秒 **`($TIMET$)`** 表示),主机名和服务描述(**`$HOSTNAME$`** 和 **`$SERVICEDESC$`**),Nagios 进行测试所需的时间(**`$SERVICEEXECUTIONTIME$`**),以及性能计划时间和实际时间之间的延迟(**`$SERVICELATENCY$`**),每个值之间用制表符分隔。
然后 Nagios 将 Web 界面的输出写入日志文件(**`$SER-VICEOUTPUT$`**),最后写入实际性能数据(**`$SERVICEPERF-DATA$`**)。参数定义中的**`\t`**确保日志中的各个细节通过制表符分隔。使用**`*_perfdata_file_mode`**参数,您可以定义 Nagios 是将数据追加到现有文件(**`a`**)还是覆盖现有文件(**`w`**):
/etc/nagios/nagios.cfg
...
host_perfdata_file_mode=a
service_perfdata_file_mode=a
...
这适用于可以读取(之前已设置)命名管道数据的程序。这种方法提供了更好的性能,并且不需要硬盘上的任何空间。然而,如果处理软件没有运行,数据可能会丢失:Nagios 会尝试一段时间继续写入管道,但如果数据无法读出,则会超时并终止此过程。
从日志文件读取的程序通常会在之后删除它,以防止文件系统溢出。如果程序没有检索任何数据,文件会迅速增长,但只要文件系统还有空间,就不会丢失任何数据。
最好将外部评估软件作为永久服务运行。但您也可以配置 Nagios,使其定期触发程序进行进一步处理:
/etc/nagios/nagios.cfg
...
host_perfdata_file_processing_interval=0
service_perfdata_file_processing_interval=0
host_perfdata_file_processing_command=process-host-perfdata-file
service_perfdata_file_processing_command=process-service-perfdata-file
使用**`*_perfdata_file_processing_interval`**参数,您设置一个秒数间隔,在此之后 Nagios 将定期运行相应的**`*_perf data_file_processirLg_command`**。此命令被定义为正常的 Nagios 命令对象:
misccommands.cfg
...
define command{
command_name process-service-perfdata-file
command_line /path/to_the/evaluation_program
}
...
只要外部软件本身负责处理性能数据文件,您就无需使用**`*_perf data_file_processing_*`**参数。
## 19.1.2 使用外部命令处理性能数据
作为模板方法的替代方案,Nagios 还可以直接调用一个命令,该命令接管数据的进一步处理。这是在每个测试结果之后直接进行的;因此,在每个单独的检查之后,都会启动一个外部程序。如果您有大量需要检查的服务,这可能会根据软件的不同而显著降低性能。
命令本身是通过**`process_perfdata_command`**参数定义的,而不是通过**`perfdata_file`**参数:
/etc/nagios/nagios.cfg
...
process_performance_data=1
service_perfdata_command=process-service-perfdata
...
与服务性能数据相同,您还可以使用**`host_perfdata_command`**参数处理主机检查的结果。**`process-service-perfdata`**本身再次指的是一个正常的 Nagios 命令对象:
misccommands.cfg
...
define command{
command_name process-service-perfdata
command_line /pfad/zum/programm "\(LASTSERVICECHECK\)||\(HOSTNAME\)||\(
SERVICEDESC\)||\(SERVICEOUTPUT\)||\(SERVICEPERFDATA\)"
}
...
这将打开外部程序,并将必要的信息作为参数传递给它。这应包括至少最后一次服务检查的时间戳(**`$LASTSERVICECHECK$`**)、主机名(**`$HOSTNAME$`**)、服务描述(**`$SERVICEDESC$`**),以及实际的服务性能数据(**`$SERVICEPERFDATA$`**)。分隔符取决于使用的程序:此示例使用**`||`**,这是 Nagiosgraph 程序使用的分隔符。
* * *
^([193]) 一些工具,如 Nagiosgraph 和 NagiosGrapher,利用了剩余文本通常也包含性能数据的事实。如果它们相应地配置,它们能够提取其中包含的性能数据。这样,它们可以进一步处理不符合标准格式的数据。
# 19.2 使用 Nagiosgraph 在 Web 上创建图表
使用来自 [`nagiosgraph.sf.net/`](http://nagiosgraph.sf.net/) 的程序 Nagiosgraph,插件提供的性能数据可以在 Web 界面中以时间顺序的形式以图形方式显示。该软件由两个 Perl 脚本组成。脚本 **`insert.pl`** 将 Nagios 性能数据写入循环冗余数据库,这是一个环形缓冲区,其中最新数据会覆盖最旧数据^([194])。这种方法的优点是所需空间小,这可以在事先定义。
这个技巧包括根据数据的不同年龄以不同的分辨率保存数据:较旧的数据以较低的分辨率(例如,每天一个测量值),当前数据以较高的分辨率(例如,每五分钟一个测量值)。在设置数据库时,您还定义了数据保留的时间长度。这从一开始就定义了空间需求。
假设 Nagiosgraph 检测到性能数据,当它首次出现时,程序将为每个新服务创建一个单独的循环冗余数据库。包含的 **`map`** 配置文件仅描述了一些服务,因此通常需要一些手动工作——以及基本的 Perl 知识。
第二个 Nagiosgraph 脚本 **`show.cgi`**,一个 CGI 脚本,以动态 HTML 页面的形式表示数据库中的信息。为此,它(在配置完成后)以以下形式运行
http://nagsrv/path/to/show.cgi?host=host&service=service_description
Nagiosgraph 然后为所需服务显示四个图表(每日、每周、每月和年度摘要)。
## 19.2.1 基本安装
安装在 Linux 发行版中的 RRDtool 软件包是 Nagiosgraph 的先决条件。或者,您可以从 [`www.rrdtool.org/`](http://www.rrdtool.org/) 获取当前源代码。出于性能考虑,建议您还安装包含的 Perl 模块 **`RRDs`**。
建议将 Nagiosgraph 的 tar 文件解压缩到目录 **`/usr/local/nagios`**:
nagios@linux:local/nagios$ tar xvzf nagiosgraph-0.5.tar.gz
nagiosgraph/INSTALL
nagiosgraph/README
nagiosgraph/README.map
nagiosgraph/insert.pl
nagiosgraph/insert_fast.pl
nagiosgraph/map
nagiosgraph/nagiosgraph.conf
nagiosgraph/show.cgi
nagiosgraph/testcolor.cgi
nagiosgraph/testentry.pl
**`insert.pl`** 提取 Nagios 传输的数据并将其插入到 RRD 数据库中。如果该数据库不存在,则脚本将创建它。或者,**`insert_fast.pl`** 可以承担这项任务。此脚本使用 Perl 模块 **`RRDs`**,这比每次调用外部程序 **`rrdtool`**(这是 **`insert.pl`** 所做的)要高效得多。
另一个名为 **`testentry.pl`** 的 Perl 脚本可以帮助您测试自己的 **`map`** 条目。但既然您必须直接将它们写入此文件,您也可以更改 **`map`** 文件本身(如下所示)——前提是您已经创建了备份副本。CGI 脚本 **`testcolor.cgi`** 更像是一个开发者遗留在包中的工具,而不是对用户有任何帮助的工具。
除了已经提到的 **`map`** 配置文件外,还有一个名为 **`nagiosgraph.conf`** 的第二个配置文件,并且其路径必须在 **`insert.pl`**(或 **`insert_fast.pl`**)和 **`show.cgi`** 中正确定义,因此建议您检查这一点:
my $configfile = '/usr/local/nagios/nagiosgraph/nagiosgraph.conf';
## 19.2.2 配置
### 配置文件 **`nagiosgraph.conf`**
所有其他相关路径——例如到 **`map`** 文件和到 **`rrdtool`** 的路径——都在 **`nagiosgraph.conf`** 中调整:
rrdtool = /usr/bin/rrdtool
rrddir = /var/lib/rrd/nagiosgraph
logfile = /var/nagios/nagiosgraph.log
mapfile = /usr/local/nagios/nagiosgraph/map
debug = 2
colorscheme = 4
Nagiosgraph 在 **`rrddir`** 目录中创建 RRD 数据库。在这里,用户 **`nagios`** 必须有写权限,而以该用户的权限运行的 Web 服务器用户必须有读权限:
linux:~ # mkdir -p /var/lib/rrd/nagiosgraph
linux:~ # chown nagios.nagcmd /var/lib/rrd/nagiosgraph
linux:~ # chmod 755 /var/lib/rrd/nagiosgraph
对于这两个用户都需要写访问权限的日志文件(Web 用户因为 CGI 脚本也会将信息记录到日志文件中),也是至关重要的:
linux:~ # touch /var/nagios/nagiosgraph.log
linux:~ # chown nagios.nagcmd /var/nagios/nagiosgraph.log
linux:~ # chmod 775 /var/nagios/nagiosgraph.log
Nagiosgraph 的详细程度可以通过 **`debug`** 调整。可能的调试级别在包含的配置文件中有文档说明:**`2`** 表示“错误”,“**4**”表示“信息”——在这里 Nagiosgraph 已经非常详细,你必须注意文件系统不要溢出。除了调试目的(例如设置系统时)外,最好选择 **`2`**。
使用 **`colorscheme`**,它可以接受从 1 到 8 的值,你可以影响图表中的颜色数量——最好是尝试不同的选项,看看哪个配色方案最适合你的个人品味。
### Nagios 配置
Nagiosgraph 直接从 Nagios 抓取性能数据。因此,**`nagios.cfg`** 不需要任何 **`*_perfdata_file_*`** 参数。
/etc/nagios/nagios.cfg
...
process_performance_data=1
service_perfdata_command=process-service-perfdata
...
**`process_performance_data`** 开启了性能数据的处理;**`service_perfdata_command`** 指向包含外部命令的 Nagios 命令对象:
misccommands.cfg
...
define command{
command_name process-service-perfdata
command_line /usr/local/nagios/nagiosgraph/insert_fast.pl "\(LASTSERV
ICECHECK\)||\(HOSTNAME\)||\(SERVICEDESC\)||\(SERVICEOUTPUT\)||\(SERVICEPERFDATA\)"
}
...
参数 **`command_line`** 的定义必须写在一行中(不使用反斜杠 **`\`**),就像通常一样。
为了使 CGI 脚本可以直接从 Nagios Web 界面运行,定义了一个 **`serviceextinfo`** 对象:
define serviceextinfo{
service_description PING
host_name *
notes_url /nagiosgraph/show.cgi?host=\(HOSTNAME\)&service=PING
icon_image graph.gif
icon_image_alt show graphics
}
如果在 **`icon_image`** 中定义的图形位于目录 **`/usr/local/nagios/share/images/logos`** 中,Web 界面将所有主机的 **`PING`** 服务在状态显示中标记为这个。在这里可以看到 show.cgi 的强大之处:正是因为这个脚本明确地用主机和服务名称调用,才可能定义像上面的定义。除了单个主机名称外,您也可以指定一个主机组,或者,就像这个例子中一样,一个 **`*`**。这个要求是 PING 确实被定义为每个主机的服务。
**`$HOSTNAME$`** 宏随后自动插入适当的主机。因此,对于特定服务类型(必须在所有主机中具有相同的服务描述)的附加信息,只需一个单一的定义即可满足。
### Apache 配置
为了使 Apache 网络服务器能够接受 CGI 脚本,创建了一个 **`Script-Alias`**,例如:
ScriptAlias /nagiosgraph/ /usr/local/nagios/nagiosgraph/
此条目最好放在 1.5 网络界面的配置(第 47 页)中讨论的配置文件 **`nagios.conf`**。只有在重新加载 Apache 之后,才能从 19.2 使用 Nagiosgraph 的网络图表 中指定的 URL 运行 CGI 脚本。
### 对 map 的调整
根据服务类型,循环冗余数据库也可能保存多个测量系列,这些系列可以通过 CGI 脚本单独请求:
http://nagsrv/path/to/show.cgi?host=host&service=service_description&db=
database,entry1,entry2&db=database,entry3
这里使用的数据库包含至少三个不同的测量系列,前两个系列在一张图中一起显示,而第三个系列则在单独的图中显示。显示在一起和显示分开的内容取决于标准化。在同一个图中显示硬盘的百分比负载和绝对字节数没有太大意义,因为 Y 轴只能有一个刻度。在这里,最好在一张图中显示百分比值,在另一张图中显示绝对字节数。另一方面,可以在一张图中显示系统负载的各种平均值(一分钟、五分钟和十五分钟)。如果您省略所有 **`db`**= 规范,Nagiosgraph 总是会在一张图中显示一个服务的所有测量值。
个体数据库和测量值显示的内容由 **`map`** 文件定义。要了解其中包含的指令如何影响数据的提取,只需将调试级别切换到 **`4`** 并查看日志文件 **`nagiosgraph.log`** 中的输出。每次插入函数运行时,Nagiosgraph 会重新读取配置文件,因此这不会引起任何类型的重置。
在以下日志文件摘录中,三个点标记了我们为了清晰起见不会打印的部分:
... INSERT info:... servicedescr:PING
... INSERT info:... hostname:linux01
... INSERT info:... perfdata:rta=99.278ms;3000.000;7000.000;0; pl=0%;60;
80;;
... INSERT info:... lastcheck:1114853435
... INSERT info:... output:OK - 172.17.4.11: rta 99.278ms, lost 0%
输出来自 **`check_icmp`** 插件。主机名、服务描述、性能数据(**`perfdata:`**)和标准输出行(**`output:`**)各自占一行。在性能数据中,插件使用变量 **`rta`** 宣布 *往返平均*,并使用 **`pl`**(*数据包丢失*)表示丢失的数据包数量。
**`map`** 文件包含 Perl 指令,用于过滤这些输出并提取相应的数据(如果有匹配项)。每个指令都以一个搜索指令开始:
/perfdata:rta=([.\d]+)ms.+pl=(\d+)%/
经典的 Perl 搜索函数由两个连续的斜杠 **`/`** 组成,其中包含一个正则表达式形式的搜索模式。圆括号对包围的部分模式,通过这种方式找到的文本可以通过变量 **`$1`**、**`$2`** 等访问。
因此,第一个括号中的模式匹配单个数字(**`\d`**)或点,^([197]) 并且下一个 + 状态表示可以有多个(或一个也没有)。然而,在第二个圆括号中,允许一个或多个数字,但不能有点。具体来说,**`$1`** 提供响应时间的数值,**`$2`** 提供百分比中的数据包丢失。
**`map`** 文件中的完整指令使用 **`and`** 操作符链接两个 Perl 语句:
-- check_icmp
perfdata:rta=100.424ms;5000.000;9000 .000;0; pl=0%;40;80;;
/perfdata:rta=([.\d]+)ms.+pl=(\d+)%/
and push @s, [ 'ping',
[ 'rta', 'GAUGE', $1 ],
[ 'losspct', 'GAUGE', $2 ],
];
如果第一个——搜索函数——成功,那么轮到 **`push`** 语句。它将方括号中跟随的表达式添加到数组 **`@s`** 中。指令以分号结束。如果搜索函数没有提供结果,则 **`map`** 指令不会在 **`@s`** 数组中保存任何条目。要包含在数组中的表达式具有以下格式:
[ db-name,
[name_of_data_source, type, value ],
[name_of_data_source, type, value ],
...
]
Nagiosgraph 数据库文件的文件名由主机名、服务描述和数据库名组合而成,例如,**`linux01_PING_ping.rrd`**。数据库名称的期望字符串应输入到 **`map`** 文件中(在这种情况下,**`ping`**)代替占位符 *db-name*。
数据源名称可以自由选择,但应包含存储在此处的数据的指示,例如,**`rta`** 表示响应时间或 **`losspct`** 表示丢失的包的百分比。
您指定的 *类型* 由 RRD 工具确定。**`GAUGE`** 表示简单测量值,它们以原样显示。Nagiosgraph 作者 Soren Dossing 推荐使用 **`DERIVE`** 处理计数器,例如在查询网络接口上的数据包计数器。计数器增量增长,当它们溢出时,从零开始。这里感兴趣的是两个时间点之间的差异。如果指定数据源类型 **`DERIVE`**,RRD 数据库将自动确定这些值。
数据库名称、数据源和类型应始终在 **`map`** 文件中以单引号放置,以防止与 Perl 中保留的关键字发生名称冲突。
测量值本身是通过 Perl 方法确定的,占位符 *value* 被相应的指令替换。在最简单的情况下,您可以使用 **`$1`**、**`$2`** 等等(见上面的示例)来接管性能数据中找到的值,或者通过乘以 1024 或计算百分比来计算新值:
-- check_nt -v USEDDISKSPACE
perfdata:C:\ Used Space=1.71Gb;6.40;7.20;0.00;8.00
/perfdata:.Used Space=([.\d]+)Gb;([.\d]+)😭[.\d]+)😭[.\d]+)😭[.\d]+)/
and push @s, [ 'disk',
[ 'used', 'GAUGE', $11024 ],
[ 'usepct', 'GAUGE', ($1/$5)100 ],
[ 'freepct', ' 'GAUGE', (($5-$1)/$5)100 ],
];
-- check_disk (unix)
perfdata:/=498MB;1090;1175;0;1212
m@perfdata:./([^ =]+)=([.\d]+)MB;([.\d]+)😭[.\d]+)😭[.\d]+)😭[.\d]+)@
and push @s, [ $1,
[ 'used', 'GAUGE', $210242 ],
[ 'warn', 'GAUGE', $3*10242 ],
[ 'crit', 'GAUGE', $4*1024**2 ],
];
第一条记录评估了 Windows 服务器上**`check_nt`**(见 20.2.1 NSClient,第 476 页)对硬盘空间的查询。性能数据还包含除**`$1`**中的占用空间外,还有**`$5`**中的数据载体大小。这可以用来计算可用百分比(**`freepct`**)和已用百分比(**`usepct`**)。
第二个示例通过将指定的 MB 数空闲硬盘空间乘以 1024²来转换成字节,评估 Unix 主机上通过**`check_ disk`**获得的数据。关键和警告限制始终保持不变,这导致出现水平线,如图 19-1 所示:下方的线在 12.1 GB 处代表警告限制,中间的线代表当前负载,上方的线在 18.1 GB 处,代表关键限制。每个单独的图表的键列出了最小值、最大值和平均值作为数值。这种对两个限制值的区分没有任何用处,但无法避免,因为 Nagiosgraph 不知道这些是常数:它将警告和关键限制值视为任何其他测量值。
如果插件不提供任何性能数据,但提供在正常输出中使用的值,则可以将搜索功能应用于输出(**`/output:.../`**)而不是性能数据。例如,Nagiosgraph 论坛在[`sourceforge.net/forum/forum.php?forum_id=394748`](http://sourceforge.net/forum/forum.php?forum_id=394748)提供帮助。

图 19-1. Nagiosgraph 表示的主机`linux0l`上文件系统`/net/linux01/a`的使用空间和限制值
对**`map`**的更改至关重要。因此,建议您首先复制文件,然后编辑副本,并使用**`perl -c`**进行语法检查:
nagios@linux:libexec/nagios$ cp map map.new
nagios@linux:libexec/nagios$ vi map.new
nagios@linux:libexec/nagios$ perl -c map.new
nagios@linux:libexec/nagios$ mv map.new map
如果语法检查无误,您可以安装新的文件作为**`map`**。
* * *
^([194]) 关于此主题的更多信息可以在[`www.rrdtool.org/`](http://www.rrdtool.org/)找到。
^([195]) 要安装,请参阅 19.4.1 安装。
^([196]) 关于**`serviceextinfo`**对象的更详细描述包含在 16.4.2 扩展服务信息,第 366 页。
^([197]) 一对方括号包含备选方案。
^([198]) 这将千字节转换为字节。
# 19.3 使用 Perf2rrd 准备性能数据以进行评估
另一个将 Nagios 性能数据传输到 RRD 数据库的工具是 Java 应用程序 Perf2rrd。这需要一个已安装的 Java 运行时环境(1.4.2 插件测试,或者最好是 1.5 配置 Web 界面)。由于虚拟机在较不强大的计算机上会产生明显的负载,并且还需要大量的内存,因此 Perf2rrd 对 Nagios 服务器的要求比 Nagiosgraph 的要求要高得多。
另一方面,在安装方面,在生成 RRD 数据库方面就没有更多的工作要做,因为 Perf2rrd 使用了 Nagios 的模板机制(见 19.1 使用 Nagios 处理插件性能数据,第 404 页)。对于模板中包含的每个服务和每个变量,该工具都会使用以下命名模式创建一个单独的 RRD 数据库:
host+service_description+variable_name.rrd
因此,为了评估**`check_icmp`**变量**`rta`**(往返平均)和**`pl`**(丢包率),文件名分别是**`linux01+PING+pl.rrd`**和**`linux01+PING+rta.rrd`**。
Perf2rrd 只负责在 RRD 数据库中存储数据,并不提供任何图形显示已保存数据的工具。Perf2rrd 的作者 Marc DeTrano 在这里提到了**`drraw`**工具(见 19.4 图形专家 drraw,第 420 页)。使用它可能是有益的,因为一方面**`drraw`**提供了比 Nagiosgraph 提供的单一显示更多的功能,另一方面你不必在 Perl 中与正则表达式抗争。
## 19.3.1 安装
对于安装,你应该从[`perf2rrd.sf.net/`](http://perf2rrd.sf.net/)获取 tar 格式的存档,并将其复制,最好复制到**`/usr/local`**层次结构中:
linux:~ # cd /usr/local
linux:usr/local # tar xvzf /path/to/perf2rrd-1.0.tar.gz
...
perf2rrd/run
...
之后运行的可执行程序是一个名为**`run`**的脚本,该脚本会调用 Java 字节码解释器,**`java`**。除此之外,该目录还包含 Java 类文件和其他实用工具,如果需要,可以使用这些工具重新编译包含的共享库**`librrdj.so`**。对于较新的发行版,这通常是不必要的。
为了让**`run`**能够找到**`java`**程序,它必须位于**`/usr/bin`**。如果不是这样(例如,因为你已经从[`www.sun.com/`](http://www.sun.com/)安装了 Java 存档),那么你应该设置一个链接:
linux:~ # ln -s /usr/local/jre1.5.0_02/bin/java/usr/bin/java
简短的测试可以显示 Perf2rrd 是否正确启动:
nagios@linux:local/perf2rrd$ ./run
perf2rrd starting
Using Nagios Config: /etc/nagios/nagios.cfg
Using RRD Repository: /var/log/nagios/rrd
Unable to create RRD Repository
最后行显示的错误信息目前不是问题,因为我们已经将 RRD 数据库保存在了不同的目录中(Perf2rrd 永久运行)。
## 19.3.2 Nagios 配置
Perf2rrd 在 Nagios 配置中搜索它所需的所有数据:Nagios 应将性能数据写入哪个文件,用于此的写入模式,以及模板的格式:
/etc/nagios/nagios.cfg
...
process_performance_data=1
...
service_perfdata_file=/var/nagios/service-perfdata.dat
service_perfdata_file_template=\(TIMET\)\t\(HOSTNAME\)\t
\(SERVICEDESC\)\t\(SERVICEEXECUTIONTIME\)\t\(SERVICELATENCY\)\t
\(SERVICEOUTPUT\)\t\(SERVICEPERFDATA\)
service_perfdata_file_mode=w
...
由于**`service_perfdata_file_mode=w`**,这里使用的命名管道必须手动创建——Perf2rrd 1.0 在 Nagios 2.0 中与正常文件接口(**`service_perfdata_file_mode=a`**)存在问题:
linux:~ # mknod /var/nagios/service-perfdata.dat p
linux:~ # ls -l /var/nagios/service-perfdata.dat
prw-r--r-- 1 nagios nagios 0 May 1 10:49 /var/nagios/service-perfdata.dat
在模板中缺少了介绍性的[**`SERVICEPERFDATA`**]戳记(参见 19.1 使用 Nagios 处理插件性能数据),因为 Perf2rrd 1.0 无法正确解析此戳记。更改 Nagios 配置需要重新加载:
linux:~ # /etc/init.d/nagios reload
最后,你为 RRD 数据库创建目录:
linux:~ # mkdir /var/lib/rrd/perf2rrd
linux:~ # chown nagios.nagios /var/lib/rrd/perf2rrd
## 19.3.3 实际应用中的 Perf2rrd
每次启动 Perf2rrd 时都加载 Java 虚拟机需要相当多的资源。因此,你不应该使用**`service_perfdata_file_processing_command`**参数在 Nagios 的特定间隔启动 Perf2rrd,也不应该使用**`one-shot mode`**,即通过**`./run -o`**,其中软件一次处理一个文件。理论上,这可以通过 cron 作业定期运行 Perf2rrd。相反,建议你让程序永久运行。
当首次使用时,我们建议你开启调试模式,这将显示发生的任何问题。选项**`-d`**指定工具应创建和更新 RRD 数据库的目录:
nagios@linux:local/perf2rrd$ ./run -d /var/lib/rrd/perf2rrd -x
perf2rrd starting
Using Nagios Config: /etc/nagios/nagios.cfg
Using RRD Repository: /var/lib/rrd/perf2rrd
Debug Mode is on
Reading perfdata from named pipe.
Perf Data File is : /var/nagios/service-perfdata.dat
I believe we are using Nagios ver. 2
Object Cache File is : /var/nagios/objects.cache
Nagios interval_length 60
called update with: .../eli02+PING+rta.rrd 1114938329:0.079
called update with: .../eli02+PING+pl.rrd 1114938329:0.0
/var/lib/rrd/perf2rrd/sap-14+SAP-3202+time.rrd created.
called update with: .../sap-14+SAP-3202+time.rrd 1114938688:0.030775
...
Nagios 配置文件、RRD 存储库和数据传输模式(**`named pipe`**)的输出紧随 Nagios 使用的(并通过**`interval_length`**参数设置的)时间单位。通常这是 60 秒,即**`5`**分钟的检查间隔为五分钟。确保此参数被正确识别非常重要,因为 Perf2rrd 通过将**`normal_check_interval`**和**`interval_length`**参数相乘来确定 RRD 数据库的*步长间隔*。
在步长间隔内发生的所有测量值都由数据库进行平均。如果这个时间段太小,数据库可能永远不会发布任何值,因为它期望保存的数据比实际获得的多得多。
当 Nagiosgraph 使用固定的五分钟间隔时,Perf2rrd 会调整自身以适应 Nagios 配置。然而,软件仅在创建 RRD 数据库时考虑间隔;稍后更改 Nagios 配置不会产生进一步的影响。你可以做的唯一改变是删除 RRD 数据库并重新设置它。
### 永久运行的 Perf2rrd
在命名管道上运行 Perf2rrd 有一个缺点:如果 Nagios 重新启动,它会先关闭管道然后再重新打开。不幸的是,当管道关闭时,Perf2rrd 也会随之关闭。
这可以通过 Daniel J. Bernstein 的 Daemon Tools 来防止。它们监控程序并在这些程序停止时重新启动它们。它们自己通过 init 进程的 **`/etc/inittab`** 条目启动,并在它们在某个时刻自行关闭时重新启动。可以从 [`cr.yp.to/daemorLtools/install.html`](http://cr.yp.to/daemorLtools/install.html) 获取 Daemon Tools 的 tar 文件,并将其解压到 **`/usr/local/src`** 目录中:
linux:~ # cd /usr/local/src
linux:local/src # tar xvzf /path/to/daemontools-0.76.tar.gz
admin
admin/daemontools-0.76
admin/daemontools-0.76/package
admin/daemontools-0.76/package/README
...
admin/daemontools-0.76/src
这将创建 **`admin/daemontools-0.76`** 目录,其中包含子目录 **`package`** 和 **`src`**。从那里你应该运行 **`install`** 脚本,它会编译并安装程序:
linux:local/src # cd admin/daemontools-0.76
linux:admin/daemontools-0.76 # package/install
二进制文件会落在新创建的目录 **`daemontools-0.76/com-mand`** 中,并保留在那里。安装程序还会设置指向它们的符号链接,这些链接指向新创建的文件夹 **`/command`**。
**`install`** 脚本还在 **`/etc/init-tab`** 文件中包含以下行,以确保 Daemon Tools 永久运行:
SV:123456:respawn:/command/svscanboot
程序 **`svscanboot`** 会定期搜索新的或崩溃的守护进程。为此,它会扫描 **`/service`** 目录,该目录也是在安装过程中创建的。只需一个符号链接就可以让 Perf2rrd 被监控:
linux:~ # ln -s /usr/local/perf2rrd /service/perf2rrd
Daemon Tools 在此目录中搜索名为 **`run`** 的脚本并启动它。为了使 **`run`** 能够找到 RRD 存储库的路径,在脚本文件中输入了实际的命令行选项而不是 **`$*`**:
exec java -cp $classpath perf2rrd $*
exec java -cp $classpath perf2rrd -d /var/lib/rrd/perf2rrd
现在,启动和结束 Perf2rrd 由程序 **`svc`** 负责:
linux:~ # /command/svc -d /service/perf2rrd
linux:~ # /command/svc -u /service/perf2rrd
**`-d`** 选项(表示 *down*)会停止指定的服务,而 **`-u`** (*up*) 选项会再次启动它。在开始时运行它并不是必需的,因为 Daemon Tools 会定期扫描 **`/service`** 目录以查找新的服务并自动启动它们。这一点很重要,因为本书基于的 Nagios-2.0 测试版在配置的命名管道无法读取时存在问题。那时,它可能根本不会再提供任何数据,直到重新加载或重启。在印刷时,无法确定 Nagios 2.0 最终版本是否修复了这个问题。
* * *
^([199]) 使用 **`a`**,Nagios 将数据追加到正常日志文件中;使用 **`w`**,它通过命名管道使其可访问。参见 19.1 使用 Nagios 处理插件性能数据,第 404 页。
# 19.4 图形专家 **`drraw`**
从由 Perf2rrd 或 Nagios-graph 生成的 RRD 数据库中,CGI 脚本**`drraw`**创建交互式图形——简单的相对快速,而对于更复杂的图形,则需要了解一些 RRDtools 的知识^([200))。
## 19.4.1 安装
对于**`drraw`**的安装,您需要从[`www.taranis.org/drraw/`](http://www.taranis.org/drraw/)获取当前的 tar 文件,并将其解压到 Web 服务器 CGI 层次结构中的自己的子目录中^([201)]:
linux:~ # cd /usr/lib/cgi-bin
linux:lib/cgi-bin # tar xvzf /path/to/drraw-2.1.1.tar.gz
drraw-2.1.1/
...
drraw-2.1.1/drraw.cgi
drraw-2.1.1/drraw.conf
drraw-2.1.1/icons/
...
然后将此目录重命名为**`drraw`**^([202))
linux:lib/cgi-bin # mv drraw-2.1.1 drraw
**`drraw.cgi`**本身除了 Perl 外,还需要 Perl CGI 模块(**`CGI.pm`**)和至少版本 1.0.47 的 RRDtools;低于 1.0.36 的版本将无法工作。如果您的发行版不包含当前版本,您应从[`www.rrdtool.org/`](http://www.rrdtool.org/)获取源代码并自行编译:
linux:~ # cd /usr/local/src
linux:local/src # tar xvzf /path/to/rrdtool-1.0.49.tar.gz
...
linux:local/src # cd rrdtool-1.0.49
linux:src/rrdtool-1.0..49 # ./configure
...
linux:src/rrdtool-1.0..49 # make
...
linux:src/rrdtool-1.0..49 # make install
...
linux:src/rrdtool-1.0..49 # make site-perl-install
CGI 脚本**`drraw.cgi`**使用 Perl 模块**`RRDs`**,在执行**`make site-perl-install`**安装后,会自动找到。
## 19.4.2 配置
**`drraw`**的配置包含在文件**`drraw.conf`**中:
linux:cgi-bin/drraw # **egrep -v '#|\(' drraw.conf**
...
%datadirs = ('/var/lib/rrd' ⇒ '[RRDbase]',
);
\)vrefresh = '120';
@dv_def = ( 'end - 6 hours', 'end - 28 hours', 'end - 1 week', 'end - 1
month', 'end - 1 year' );
@dv_name = ( 'Past 6 Hours', 'Past 28 Hours', 'Past Week', 'Past Month',
'Past Year' );
@dv_secs = ( 21600, 100800, 604800, 2419200, 31536000 );
\(saved_dir = '/var/lib/drraw/saved';
\)tmp_dir = '/var/lib/drraw/tmp';
...
显示的提取指定了 RRD 存储库(此处:**`/var/lib/rrd`**)作为最重要的细节,但也可以指定多个目录:
%datadirs = ('/var/lib/rrd' ⇒ '[RRDbase]',
'/data/rrd' ⇒ '[RRDdata]',
);
方括号中的文本(例如,[**`RRDbase`**])将在 Web 界面上稍后出现,这允许区分不同的不同存储库。变量**`@dv_def`**、**`@dv_name`**和**`@dv_secs`**影响布局和图形数量。
上面的配置比标准配置多生成一个图形。这代表过去六小时:**`@dv_def`**中的扩展语句**`'end--6 hours'**描述了**`rrdtool`**(见**`man rrdgraph`**)的时间段,在**`@dv_name`**中给出了合适的标题**`'Past 6 Hours'****,而**`@dv_secs`**包含六小时,转换为(**`21600`**)秒,由**`drraw`**作为单独的图形显示的时间段。
存储库必须可读,由运行 Web 服务器的用户权限读取,并且在**`$saved_dir`**和**`$tmp_dir`**中指定的目录也必须可读。如果除**`www-data`**之外的用户运行此程序,则必须相应地调整以下命令:
linux:~ # mkdir -p /var/lib/drraw/{saved,tmp}
linux:~ # chown -R www-data.www-data /var/lib/drraw
数据到达临时目录**`$temp_dir`**,其内容可以随时删除,而在**`$saved_dir drraw`**中存储程序需要访问已创建图形的配置数据。这些数据不得丢失。
**`drraw`**在三个阶段实现简单的访问保护:只读(**`0`**)、受限编辑(**`1`**)和完全访问(**`2`**)。登录到 Web 服务器的用户自动获得级别 2。未经授权的用户被视为**`guest`**并分配级别**`0`**。为了避免在开始时进行身份验证的麻烦,您可以在配置文件中的以下指令中授予用户**`guest`**完全访问权限:
%users = ( 'guest' ⇒ 2 );
## 19.4.3 实际应用
Web 服务器 CGI 目录中的 CGI 脚本可以通过 URL [`nagiosserver/cgi-bin/drraw/drraw.cgi`](http://nagiosserver/cgi-bin/drraw/drraw.cgi)访问。

图 19-2. `ddraw`启动菜单
新图形在启动图片中的**创建新图形**菜单项中生成,启动图片如图 19-2]),可以进一步限制可用的数据源;此表达式也可以是简单的文本,例如**`sap-12`**。

图 19-3. 选择数据源
一旦您选择了 RRD 数据库,您只需指定要使用的*循环冗余存档*(RRA)。这些存档中的每一个都以特定的形式保存数据,通过合并函数处理:**`AVERAGE`**函数平均测量周期内累积的所有测量数据,**`MIN`**只保存区间内数据的最低值,而**`MAX`**只保存最高值。由于原始数据已丢失,创建循环冗余数据库时必须指定存档;如果当时考虑到这一点,则只能稍后回忆最大值。
如果您无法记住存在哪些存档,您可以使用按钮**`RRD Info for selected DB`**来显示它们。点击**`Add DB(s) to Data Sources`**按钮将带您进入一个对话框,您首先需要向下滚动一点才能到达项目**`Data Source Configuration`**(图 19-4])
**更新** 按钮提供了完成图形的预览,同时揭示了使用的 **`rrdtool`** 选项 (图 19-5). 当你保存时,使用 **保存图形**,你将获得一个如下形式的链接
http://nagiosserver/cgi-bin/drraw/drraw.cgi?Mode=view;Graph=11149589.4932
通过这些教程,你可以随时访问图形。或者你现在可以在 **`drraw`** 的 **所有图形** 下找到该图形。

图 19-4. 精细调整图形配置

图 19-5. 预览并指定 `rrdtool` 选项

图 19-6. 完成的图形表示不同的时间段
当你保存图形时提到的链接可以记录在 **`service-extinfo`** 对象中,使其可以通过 Nagios 接口直接访问:
define serviceextinfo{
service_description PING
host sap-12
notes_url /nagiosgraph/drraw/drraw.cgi?Mode=view;Graph=11149589.4932
icon_image graph.gif
icon_image_alt View graphics
}
使用模板和仪表板,**`drraw`** 包含其他一些功能,由于篇幅原因,这里不能详细讨论。模板允许在同一个图形中显示相同类型的多个来源。这些来源可以在 **创建新图形** 中指定 (参见 图 19-3). 由于你只能一次添加一个来源,因此你必须为每个单独的来源点击 **添加** 按钮,然后再继续下一个。
仪表板展示了一个包含多个预览图形的显示。如果你点击其中一个图形,你会看到详细的表示。交互式菜单 **创建仪表板** 包含简要说明,你可以在这里获得关于两个功能的帮助。
* * *
^([200]) 除了主页上的文档 [`www.rrdtool.org/`](http://www.rrdtool.org/) 之外,包含的教程 (`man rrdtutorial`) 是一个有用的起点,同样还有手册页 **`man rrdgraph`**。
^([201]) 这个目录取决于你使用的发行版或 Apache 配置。
^([202]) 也可以使用符号链接,但那时 Apache 必须配置为遵循符号链接,这通常不是自动完成的。
^([203]) POSIX 正则表达式;参见 **`man 7 regex`**。
^([204]) 在 RRDtools 作者 Tobias Oetiker 的主页 [`people.ee.ethz.ch/~oetiker/webtools/rrdtool/tut/index.en.html`](http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/tut/index.en.html) 上有许多教程。
# 19.5 大部分自动化:NagiosGrapher
Netways 提供的 NagiosGrapher,The Nagios Exchange Platform 的托管者[`www.nagiosexchange.org/`](http://www.nagiosexchange.org/),是一个强大的性能数据表示工具,但已经非常强大。它还保存数据在轮询数据库中,并使用 RRDtools 进行处理和表示。它声称易于安装,并且与“竞争者”相比,在很大程度上是自动工作的。然而,后者承诺至今尚未实现;就像 Nagiosgraph 一样,你必须配置搜索模式以解释插件输出或性能数据。RRD 数据库由 NagiosGrapher 自动生成;此外,工具**`serviceextinfo`**也会生成条目。
一旦它识别出性能数据,你就不必再担心将其集成到 Nagios 中。只需重新加载即可使在此期间生成的**`serviceextinfo`**条目在 Nagios 中可用。这些条目是“智能”创建的,所以如果你在服务摘要中点击相应的图标(见图 19-7,在 434 页),你将直接进入性能数据的图形显示。
在功能性和安装努力方面,NagiosGrapher 位于 Nagiosgraph 和 Perf2rrd 之间:所需的初始配置比 Nagiosgraph 要多一些,但图形输出的变化可能性要大得多,而且你不必像 Perf2rrd/**`drraw`**那样逐个生成每个图形。
## 19.5.1 安装
除了 RRDtools(至少在版本 1.2 中)和程序**`auto-conf`**之外,NagiosGrapher 还需要一系列 Perl 模块:**`CGI`**,**`CGI::Carp`**,**`Calendar:: Simple`**,**`Carp`**,**`Data:: Dumper`**,**`File::Basename`**,**`File::Copy`**,**`GD`**,**`IO::Handle`**,**`Image::Magick`**,**`POSIX`**,**`RRDs`**,**`Storable`**,**`Time::HiRes`**,**`Time :: Local`**,和**`URI::Escape`**。
安装它们有两种选择,即从发行版中包含的软件包或从 CPAN 安装。在 Debian "Etch"和类似的基于 Debian 的系统上,如果你选择安装**`autoconf`**,**`rrdtool`**,**`perl-modules`**,**`libcalendar-simple-perl`**,**`libgd-gd2-perl`**,**`perlmagick`**,**`librrds-perl`**,和**`liburi-perl`**这些软件包,你将拥有所有模块。在其他发行版中,你必须搜索上述模块,最好使用发行版中的图形软件包安装器。你可以在执行**`configure`**命令后运行**`make testdeps`**来查看你是否已安装所有所需的模块。使用**`make fixdeps`**命令从 CPAN 安装每个最新模块版本。
NagiosGrapher 的源代码可以从 NagiosExchange 获得,205 并解压到目录 **`/usr/local/src`**:
linux:~ # cd /usr/local/src
linux:local/src # tar xvjf/path/to/NagiosGrapher-1.6.1.tar.bz2
...
linux:local/src # cd NagiosGrapher-1.6.1
linux:src/NagiosGrapher-1.6.1 # autoconf
命令 **`autoconf`** 生成一个 **`configure`** 脚本。在运行此脚本之前,编辑文件 **`config.layout`**,它提供了各种 *布局*。在 NagiosGrapher 文档中,这个术语意味着所有必需的安装路径的定义。
**`config.layout`** 包含一系列与发行版相关的建议,需要根据本书中的约定在某个方面进行更改。为此,最好复制与您的发行版匹配的部分,并将其重命名为 **`<Layout nagiosbook>`**,并修改多个条目。206 对于 Debian "Etch",以下条目适用(更改的值以粗体显示):
config.layout
在此情况下,参数 perl_inc 中定义的 Perl 模块路径对应于 Ton Voon 为 Perl 模块 Nagios::Plugin 建议的目录(参见 使用 CPAN 的方法)。
新布局包含在 configure 脚本中:
linux:src/NagiosGrapher-1.6.1 # **./configure --with-layout=nagiosbook**
...
您可以运行 make testdeps 来检查是否已满足所有依赖项,特别是 Perl 模块的依赖项:
linux:src/NagiosGrapher-1.6.1 # **make testdeps**
/usr/bin/perl ./tools/testdeps.pl
Checking Data::Dumper ... found
...
Checking IO::Handle ... found
Checking URI::Escape ... found
Checking Calendar::Simple ... not installed!
make: *** [testdeps] Error 1
如果发生错误,例如在这个例子中,您必须安装适当的模块(这里 Calendar::Simple)。这可以通过 CPAN 使用以下命令完成:
linux:src/NagiosGrapher-1.6.1 # **make fixdeps**
...
对于基于 Debian 的发行版,包命名方案相当简单:Perl 模块 Calendar:: Simple 被转换为包 lib-calendar-simple-perl,可以通过 apt-get 或 aptitude 安装:
linux:src/NagiosGrapher-1.6.1 # **apt-get install libcalendar-simple-perl**
...
再次运行 make testdeps 可以显示是否现在已满足所有要求。
已经安装的 NagiosGrapher 通过 make update 进行更新,因为 make install(用于新安装)不考虑已存在的配置文件,并简单地覆盖它们。207 make install 创建所有必要的目录,确保设置了正确的访问权限,并将所有文件复制到它们应该去的地方:
linux:src/NagiosGrapher-1.6.1 # **make install**
mkdir -p /etc/nagios/serviceext
chown -R nagios /etc/nagios/serviceext
mkdir -p /var/lib/rrd/nagios_grapher
chown -R nagios /var/lib/rrd/nagios_grapher
...
==================================================
Just a few steps to run the grapher ...
...
make 的输出以关于 NagiosGrapher 和 Nagios 配置的一些说明结束,我们将在 19.5.1 安装 和 图形重处理的选项 中更详细地探讨。
NagiosGrapher 的一个核心组件是守护进程 collect2.pl,它通过位于 /etc/init.d 的启动脚本 nagios_grapher 启动:
linux:~ # **/etc/init.d/nagios_grapher start**
为了使守护进程在系统启动时自动启动,在使用系统 V init 的发行版中设置了相应的符号链接。在 Debian/Ubuntu 中,这是通过系统脚本 update-rc.d 完成的:
linux:~ # **update-rc.d nagios_grapher defaults 98**
OpenSUSE 包含用于此目的的脚本 insserv:
linux:~ # **insserv nagios_grapher**
在 Fedora 中,此任务由 chkconfig 执行:
linux:~ # **chkconfig --add nagios_grapher**
linux:~ # **nagios on**
19.5.2 配置
配置文件 ngraph.ncfg
配置文件 ngraph.ncfg 包含一个全局 config 部分,其中包含路径和一般设置。之后是一个包含指令,带有参数 cfg_dir,它在 Nagios 中,将指定目录中所有配置文件集成在一起。与 Nagios 不同,NagiosGrapher 的配置文件都以 .ncfg 结尾。
即使是快速浏览也能看出,语法符合 Nagios 使用的约定:
# /etc/nagios/ngraph.ncfg
define config {
interface file
perffile_path /var/nagios/
pipe /var/nagios/rw/ngraph.pipe
port 5667
buffer 1024
pidfile /var/nagios_grapher/nagios_grapher.pid
user nagios
group nagios
step 300
heartbeat AUTO
rrdpath /var/lib/rrd/nagios_grapher/
tmppath /tmp/nagiosgrapher/
fontfile /usr/share/fonts/truetype/ttf-dejavu/DejaVuSansCon
densed.ttf
serviceext_type MULTIPLE
serviceextinfo /etc/nagios/serviceextinfo.cfg
serviceext_path /etc/nagios/serviceext
url /nagios/cgi-bin/graphs.cgi
#notes_url /wiki/index.php/$HOSTNAME$#$SERVICEDESC$
notes_url
nagios_config /etc/nagios
cgi_config /etc/nagios/cgi.cfg
icon_image_tag dot.png' border="0"></a><A TARGET="_blank" HREF="g
raphs.cgi?###URL###"><img src='###IMAGESRC###' '
icon_image_src /nagios/images/logos/graph.png
icon_image_script /nagios/cgi-bin/rrd2-system.cgi?###URL###&start=-5
400&title=Actual&width=20&height=20&type=AVERAGE&only-graph=true
icon_image_static true
log_file /var/nagios/ngraph.log
log_level 1023
rrd_color_background ffffff
rrd_color_font 333333
rrd_color_arrow ff0000
rrd_color_frame ffffff
rrd_color_grid
rrd_color_canvas ffffff
rrd_color_shadea c0c0c0
rrd_color_shadeb c0c0c0
fe_use_browser_all false
fe_use_browser_for nagiosadmin
fe_use_browser_url false
fe_use_timefilter true
use_authentication true
...
}
# Includes
cfg_dir=/etc/nagios/ngraph.d
config 部分包含以下参数:
interface
这定义了连接到 Nagios 的类型。可能的连接类型有 pipe、network 和 file。对于 pipe 类型,Nagios 和 collect2.pl 守护进程通过命名管道(参见 pipe 参数)进行通信;对于 network 类型,Nagios 通过 UDP 传输协议通过网络套接字发送性能数据(参见参数 port)。
与前面描述的接口类型不同,file 类型(从版本 1.7 开始可用)使用模板机制,这意味着 Nagios 将性能数据写入一个文件,该文件由守护进程 collect2.pl 定期评估。这使得首次可能进行大量处理性能数据,从而节省资源。默认接口类型在版本 1.6 之前是 pipe,从版本 1.7 开始是 file。
perffile_path
这定义了 Nagios 通过模板机制写入所有性能数据的文件目录。
pipe
这定义了一个命名管道,Nagios 通过程序 fifo_write 向其写入数据,并且收集脚本 collect2.pl 从中再次读取它们。从版本 1.6.1 开始,命名管道由 make install 自动创建。
port
这指定了 network 通信类型的 UDP 端口。默认值为 5667。
buffer
这确定通过 UDP 发送性能数据缓冲区的大小(以字节为单位)。默认值为 1024 字节。
pidfile
这定义了 NagiosGrapher 在启动时写入其自身进程 ID 的文件。
user, group
这些定义了以哪个用户和组权限运行的守护进程 collect2.pl 的权限。在这里,指定 Nagios 工作时使用的用户和组权限是有意义的。
step
这定义了 RRD 数据库的秒级步长。在此期间记录的所有值都由 RRDtools 汇总成一个值。因此,step 也描述了 RRD 数据库中数据的最低时间分辨率。该值仅对新建的 RRD 数据库有效,对现有数据库的后续修改没有影响。
heartbeat
心跳定义了一个以秒为单位的时间段,在此期间,RRD 数据库始终期望接收数据。如果在此期间没有任何测量值到达,NagiosGrapher 将生成一个无效条目(nan,即非数字)。
为了在上述示例中生成有效的条目,每600秒至少必须有一个测量值到达。由于分辨率为60秒,数据库包含“心跳”期间十个条目。如果这些值中有一个缺失,NagiosGrapher 将简单地用最后一个有效值替换它。如果十分钟内只有一个测量值到达,它将在数据库中记录十次。
rrdpath
这指定了 RRD 数据库的目录。它必须对用户nagios可写,并且(连同数据库文件)对 Web 服务器用户可读。该目录在安装 NagiosGrapher 时自动创建。
tmppath
这定义了 NagiosGrapher 临时保存内部 XML 文件的位置。
fontfile
这指定了 RRDtools 用于标注图形所使用的字体文件。
serviceext_type
这描述了如何创建serviceextinfo对象。使用SINGLE类型,NagiosGrapher 将所有内容写入serviceextinfo中指定的文件。
Nagios 2.0 也可以递归地读取目录,在这种情况下,最好使用MULTIPLE类型。然后 NagiosGrapher 为每个主机创建一个包含相应serviceextinfo对象的单独文件。目录由serviceext_path参数指定。这必须通过cfg_dir指令通知 Nagios。
url
这包含从 Web 服务器的角度(即从服务器根目录开始的路径)或从浏览器的角度(即完整的 URL)到 CGI 脚本graphs.cgi的路径。
notes_url
NagiosGrapher 自动生成serviceextinfo对象;能够设置参数notes_url(来自 16.4.2 扩展服务信息)也很有用,例如,生成一个指向 Wiki 条目的服务相关链接。
nagios_config
这揭示了 NagiosGrapher 标准配置文件的位置。
cgi_config
这指定了 Nagios CGI 配置文件。NagiosGrapher 使用此文件来找出除了联系组之外,谁有权查询所有主机的信息。
icon_image_tag
此参数对应于稍后在serviceextinfo对象中作为icon_image参数找到的条目。在serviceextinfo对象中,NagiosGrapher 将文本###URL###替换为主机和服务名称。另一方面,条目###IMAGESRC###则由 NagiosGrapher 替换为参数icon_image_src的内容。
在这里,程序通过一个技巧欺骗了 Nagios:dot.png 是一个一像素大小的图形,它在屏幕上是不可见的。为了创建一个围绕它、可见的第二个图标 graph.png,设置了一个超链接到 CGI 脚本 graphs.cgi。
通常情况下,如果你点击 icon_image 中指定的图像,Nagios 会带你到 扩展信息 页面,并且图形可以通过 url(Nagios:notes_url)仅通过另一个鼠标点击来访问。使用这里使用的技巧,你可以直接这样做。
在 icon_image_tag 后面的规范必须写在单行上。图 19-7 显示了图标 graph.png,它在 Nagios 界面中可见,多亏了自动生成的 serviceextinfo 对象。

图 19-7. NagiosGrapher 图标(箭头)在 Nagios 网络界面中表示对该服务的相关评估
icon_image_static
这指定了 图 19-7 中集成的图标是静态生成还是动态生成。可能的值是 true(静态图标)或 false(动态生成图标)。
icon_image_src
这指定了一个静态图标,NagiosGrapher 将其集成到 icon_image_tag 中。
icon_image_script
这定义了一个脚本,它生成的是图形的迷你视图而不是动态图标。
log_file
这定义了 NagiosGrapher 写入信息的日志文件。如果你想要日志轮转,你必须自己设置,因为 NagiosGrapher 不会自动清理。由于 Nagios 需要对该文件的写入权限,因此最好将其存储在 Nagios 的 var 目录中(在这种情况下:/var/nagios)。
log_level
此参数指定日志文件应包含什么信息。可能的值有 1(检测到的服务和值)、2(Nagios 提供的、NagiosGrapher 未识别的性能数据)、4(程序状态)、8(关于 serviceextinfo 对象的信息)、16(RRD 操作)和 32(从管道中读取的输入)。对于更广泛的调试,还有值 64(正则表达式解析的详细信息)和 128(关于配置文件解析的高级信息)。
如果您想记录这些信息类型中的几个,只需将相关值相加即可,因此使用255可以获得最全面的结果;第 445 页展示了此例。建议您仅将这些日志级别用于调试目的,并且通常应使用0或4。
rrd_color_*
rrd_color选项为 Web 界面增添了颜色(图 19-8):rrd_color_background定义整个图像的背景颜色,rrd_color_font定义字体颜色,rrd_color_arrow定义箭头尖的颜色,rrd_color_frame定义键的框架颜色,rrd_color_grid定义网格颜色,rrd_color_canvas定义图表本身的背景。rrd_color_shadea定义框架顶部和左边的颜色,rrd_color_shadeb则定义框架右边和底部的颜色。颜色以十六进制表示的 RGB 值指定,前面有一个#,这是网页的标准做法。更改这些选项将在下次重新加载网页时立即生效。

图 19-8. rrd_color_*颜色选项的影响
fe_use_browser_all
从版本 1.2 开始,NagiosGrapher 提供了一种方法,可以从任何主机的特定服务显示切换到其他服务的显示。为此,它将一个选择窗口集成到graphs.cgi显示中(参见图 19-9)。
值1激活下拉菜单host和service,0则隐藏它们。

图 19-9. NagiosGrapher 是否显示host和services字段由fe_use_browser参数决定
fe_use_browser_for
此选项允许特定用户使用主机/服务选择。可以指定多个用户,用逗号分隔。为了确保只有此处指定的用户可以看到host和service的选择字段,fe_use_browser_all也必须同时设置为0。
fe_use_browser_url
此选项允许通过 URLgraphs.cgi?browser=l插入host和service的选择字段,前提是值为1。如果值为0,则无法实现。
fe_use_timefilter
这控制了通过开始和结束选择的时间是否出现在浏览器菜单中(参见第 436 页的图 19-9)。值true显示选择,false隐藏它。
use_authentication
这定义了 NagiosGrapher 是否应该考虑 Nagios 的认证结果。值true允许观察者仅访问他作为联系人负责的主机和服务的资源。值false完全关闭认证,这样每个人都可以访问一切。
在 19.5.1 安装中提到的cfg_dir配置参数定义了一个包含附加配置文件的目录,特别是各种图表的定义:
cfg_dir=/etc/nagios/ngraph.d
NagiosGrapher 递归地检查任何名称的配置文件;它们只需要以.ncfg结尾。参数必须位于config{}块之外;参数和值之间必须有一个等号。
配置图形——基本原理
ngraph对象用于定义要提取并写入 RRD 数据库的数据,但对象还包含有关显示形式的信息。像 Nagios 一样,NagiosGrapher 将信息临时保存在缓存文件中,因此每次更改配置文件后都必须重新启动数据收集脚本collect2.pl,使用/etc/init.d/nagios_grapher restart。collect2.pl在完成此操作时还会更新对象缓存。
在安装过程中,NagiosGrapher 为ngraph对象提供了一些模板;这些模板可以在/etc/nagios/ngraph.d/templates下的standard和extra子目录中找到。这些模板都以.ncfg_disabled结尾,这样它们就不会被 NagiosGrapher 考虑。为了使用它们,需要重命名文件扩展名:
nagios@linux:nagios/ngraph.d$ **cp** \
**templates/standard/check_ping.ncfg_disabled ./check_ping.ncfg**
然而,check_ping.ncfg_disabled中的示例仅适用于check_ping,而不是check_icmp(参见 6.2 使用 Ping 进行可达性测试)。为了使 NagiosGrapher 能够图形化显示check_icmp插件性能数据中的平均响应时间rta(往返平均)和pl(数据包丢失),
nagios@linux:libexec/nagios$ **./check_icmp -H linux01**
OK - linux01: rta 96.387ms, lost 0%| rta=96.387ms;200.000;500.000;0; pl=
0%;40;80;;
以下ngraph对象被使用:
# check_icmp.ncfg
...
# Ping Packet loss
define ngraph{
service_name PING
graph_perf_regex pl=([0-9]*)%
graph_value Loss
graph_units %
graph_legend Packet Loss
graph_legend_eol none
page Packet Loss
rrd_plottype LINE2
rrd_color ff0000
}
# Ping RTA
define ngraph{
service_name PING
graph_perf_regex rta=([0-9]*\.[0-9]*)
graph_value RTA
graph_units ms
graph_legend Time to answer
page RTA
rrd_plottype AREA
rrd_color 00a000
}
service_name
这由一个正则表达式组成,即^([209]),NagiosGrapher 通过它来识别在传递的数据中要显示的服务。如果使用相同插件的服务对象中提供的服务描述具有相同的前缀,则一个ngraph定义就足够了:Disk_ 匹配 Disk_usr,以及 Disk_var 或 Disk_tmp。为了使这生效,性能数据必须结构相同,如果使用相同的插件,这总是成立的。
graph_perf_regex
使用这个正则表达式,NagiosGrapher 可以在性能数据中找到要搜索的值。圆括号中的模式必须与值本身匹配。
如果插件没有提供任何性能数据,可以使用graph_log_regex代替。那里指定的搜索模式由 NagiosGrapher 应用于插件的正常文本输出。
graph_value
RRD 数据库中变量的名称对于每个服务必须是唯一的,并且不得包含空格或特殊字符(例外:下划线是允许的)。
graph_units
此参数定义 y 轴的单位。
graph_legend
这包含变量的键。
graph_legend_eol
这确定是否以及如何在这些图例的条目之后插入换行符。可能的值:left(换行,行左对齐),right(换行,行右对齐),center(换行,行居中对齐),justify(换行,完全对齐),和none(无换行,左对齐)。您可以将空格数附加到所有值上,用冒号与它分隔:none: 20不会创建换行符,但条目后面跟着 20 个空格。
graph_legend_max
这定义了图例的列宽。而不是手动使用空格格式化,使用graph_legend_eol,此参数指定图例条目的列应该有多宽。较长的条目将被截断。
page
这个可选参数确保 NagiosGrapher 在标准化不匹配的情况下以不同的图表显示变量。所有要在单个图形中使用的值都赋予相同的page条目。对于选择要显示的“页面”,CGI 脚本包含其自己的page条目字段(参见图 19-10)。

图 19-10. ping 的平均响应时间,由 NagiosGrapher 表示
对于两个check_icmp输出,建议将Loss的百分比(值范围从 0 到 100)与RTA(可以是几千毫秒)分开。
如果省略 page 参数,则两个图形——一个用于 Packet 丢失,另一个用于 RTA——将显示在一个图形中。
rrd_plottype
此参数定义 RRDtools 应该使用哪种绘图函数:
-
LINE1:简单线条, -
LINE2:双线, -
LINE3:额外的粗线, -
AREA:填充的表面, -
STACK:将当前值添加到前一个值上。在这种情况下,显示(线条或表面)取决于前一个值。
rrd_color
这是图形的 RGB 十六进制颜色表示(*`rrggbb`*)。
图 19-10 展示了 NagiosGrapher 如何显示主机 sap-13 上 PING 服务的平均响应时间 RTA。可以在 Web 表单的顶部选择相应的 页面 输出。此外,您还可以调整单个图形的 宽度 和 高度,以及 刷新 速率。
从版本 1.7 开始,NagiosGrapher 也具有缩放功能:如果您点击 图 19-10 中的任何一个图形,您可以看到更详细的视图。您可以使用鼠标在图表中选择一个时间段,NagiosGrapher 将在鼠标按钮释放后显示该时间段的数据图。
图形重新处理的高级选项
您可能并不总是希望直接显示测量值。使用 RRDtools 的 CDEF 功能,您可以添加从记录的值计算出的新值。
例如,我们将使用 check_disk 插件的输出(7.1 硬盘空闲容量, 第 158 页),该插件确定文件系统占用的量:
DISK OK - free space: /usr 287 MB (19%);| /usr=1225MB;1359;1465;0;1511
使用的空间以深灰色区域显示,空闲容量以浅灰色显示。性能数据提供了当前使用的空间(1225MB)和不可疑的警告限制,以及最小和最大值(文件系统的尺寸)。剩余的空闲容量是最大值和当前占用空间之间的差值。此外,MB 的单位有些不幸:图形将显示 10 GB 为 10k MB。因此,您首先确定插件返回的值,然后您可以按需对其进行缩放:
# (1) readout current occupancy of hard drive space,
# but do not show it as a graphic
define ngraph{
service_name fs_
graph_perf_regex =([.].+)MB;[.].+;[.].+;[.].+;[.]. +
graph_value disk_used
graph_units Bytes
graph_legend used space
rrd_plottype AREA
rrd_color 00a000
hide yes
}
在 service_name 后指定的正则表达式匹配所有以 fs_(代表 文件系统)开头的服务描述,即 fs_root、fs_usr、fs_var、fs_tmp 等。参数 hide 确保 CGI 脚本不显示图形。相反,NagiosGrapher 只将数据存储在数据库中。
在第二步中,使用 RRD 功能 CDEF 对确定的值进行标准化:
# (2) display used hard drive space in scaled form
define ngraph{
service_name fs_
type CDEF
graph_value DISK_USED
graph_legend used space
graph_calc disk_used,1024,1024,*,*
rrd_plottype AREA
rrd_color 666666
hide no
}
type将条目标识为CDEF定义,它从已存在的值中计算新值。graph_value必须是唯一的,这就是为什么此处为条目提供了自己的名称。
graph_calc最终处理数据。此参数期望以逆波兰表示法(RPN)的指令。在此,要处理的价值依次推入堆栈,稍后将其移除并操作。
在 RPN 中,将 2 + 3 相加表示为2,3,+。在示例中,我们将图形重新处理的高级选项中定义的变量disk_used乘以 1024²,以便结果以字节为单位。hide no现在确保此值被显示。
要根据相同的模式显示可用空间,我们首先确定整个可用空间(disk_max),NagiosGrapher 不应显示,计算disk_max与上述disk_used值之间的差异,并将结果转换为字节:
# (3) defining the space available,
# but not displaying it in the graphic
define ngraph{
service_name fs_
graph_perf_regex =[.].+MB;[.].+;[.].+;[.].+;([.].sb>+)
graph_value disk_max
graph_legend max space
rrd_plottype LINE2
rrd_color 0000a0
hide yes
}
# (4) calculate and display free space
define ngraph{
service_name fs_
type CDEF
graph_value DISK_MAX
graph_legend free space
rrd_plottype STACK
rrd_color CCCCCC
graph_calc disk_max,disk_used,-,1024,1024,*,*
hide no
}
相应的公式是(disk_max-disk_used)x1024²。绘图类型STACK确保从上一个disk_used值确定的价值位于其顶部。图 19-11 显示了相应的输出:屏幕的下半部分表示过去六小时、过去一天和一周内文件系统上的当前使用空间,上半部分显示剩余的空闲硬盘空间。图表还包含月度和年视图,此处未显示。
在这一点上,应再次强调,根据此定义,NagiosGrapher 自动记录所有以fs_开头并与搜索模式匹配的服务,将数据写入 RRD 数据库,并生成相应的serviceextinfo条目,在 Nagios 重新加载后自动出现在 Web 界面中(见第 434 页的图 19-7)。
在对配置文件ngraph.ncfg进行更改后,文件收集器collect2.pl也必须重新启动:
linux:~ # **/etc/init.d/nagios_grapher restart**

图 19-11. 显示计算后的负载数据
Nagios 配置
Nagios 通过命令界面传递数据给 NagiosGrapher,即每个单独的结果都会启动一个外部命令。相应地,Nagios 主配置文件包含以下参数:
# /etc/nagios/nagios.cfg
...
process_performance_data=1
service_perfdata_command=**process-service-perfdata**
命令对象 process-service-perfdata 的定义——最好通过创建一个名为 process_service_perfdata_n.graph.cfg 的单独文件来实现——取决于所使用的接口类型。
对于 interface pipe,使用程序 fifo_write,而对于 interface network,NagiosGrapher 需要程序 udpecho。
命令 fifo_write 的定义如下:
# process_service_perfdata_ngraph.cfg
...
define command{
command_name **process-service-perfdata**
command_line /usr/local/nagios/contrib/**fifo_write** /var/nagios/rw/ngr
aph.pipe '$HOSTNAME$\t$SERVICEDESC$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$\
n' 3
}
...
process-service-perfdata 调用脚本 fifo_write.pl,该脚本作为参数提供了三个参数:命名管道、包含性能细节的字符串以及以秒为单位的超时时间。后者确保如果数据在三秒内无法写入,则脚本将终止操作。command_line 必须像往常一样,写在一行上。
对于程序 udpecho,命令的定义相对简单:
# process_service_perfdata_ngraph.cfg
...
define command{
command_name **process-service-perfdata**
command_line /usr/local/nagios/contrib/**udpecho**
}
...
udpecho 不需要任何参数:它从环境变量 NAGIOS_HOSTNAME, NAGIOS_SERVICE-DESC、NAGIOS_SERVICEOUTPUT 和 NAGIOS_SERVICEPERFDATA 中检索所需信息。Nagios 必须通过 enable_environment_macros=1(见 A.1 主配置文件 nagios.cfg)提供这些信息,以便 udpecho 可以向 NagiosGrapher 提供可用的数据。
对于 file 接口类型,命令 process-service-perfdata 有另一个含义:它不是对每个检查结果都调用,而是通过模板机制将文件移入 Nagios 写入所有性能数据的文件中:
# process_service_perfdata_ngraph.cfg
...
define command{
command_name process-service-perfdata
command_line mv /var/nagios/service-perfdata /var/nagios/service-per
fdata.$TIMET$
}
...
当前的时间戳简单地附加到文件名 service-perf-data。守护进程 collect2.pl 在指定目录中搜索所有名为 service-perfdata.*****`time_stamp`* 的文件,并处理这些文件。
Nagios 写入文件的数据由 nagios.cfg 中的 service_perf data_file_template 指定:
# /etc/nagios/nagios.cfg
...
service_perfdata_file_processing_command=process-service-perfdata
service_perfdata_file=/var/nagios/service-perfdata
service_perfdata_file_template=$HOSTNAME$\t$SERVICEDESC$\t$SERVICEOUTPUT
$\t$SERVICEPERFDATA$\t**$TIMET$**
service_perfdata_file_mode=a
service_perfdata_file_processing_interval=60
...
与 fifo_write.pl 的变体相比,Nagios 现在还传递每个检查的时间戳。这是必要的,因为数据不是立即处理,而是在 service_perfdata_ file_processing_interval 间隔内定期处理——在我们的例子中是 60 秒。
如果你想从这个中挤出更多性能,你可以为 service-perfdata* 文件选择一个临时文件系统,例如 /dev/shm。然后文件不会写入硬盘,而保持在 Nagios 服务器的内存中。
如往常一样,对 Nagios 配置的更改需要重新加载:
linux:~ # **/etc/init.d/nagios reload**
如果将日志级别设置为 255(见配置文件 ngraph.ncfg),则可以在日志文件中清楚地观察到这种成功的迹象。为了清晰起见,我们将省略行首的时间戳:
CFG: buffer ⇒ '1024'
CFG: cgi_config ⇒ '/etc/nagios/cgi.cfg'
...
PRG: Starting up collect2.pl (PID: 25003) ...
PRG: using UDP socket (port: 5667)
...
NET: got udp message from localhost:32783
PIPE: swobspace PING OK - 192.168.1.9: rta 0.104ms, lost 0% rt a
=0.104ms;200.000;500.000;0; pl=0%;20;60;;
REGEX: 2 blocks for 'PING' found.
REGEX: graph_value=RTA
REGEX: output=perfdata
REGEX: regex=m/rta=([0-9]* [0-9]*)/i
REGEX: perfdata=rta=0.104ms;200.000;500.000;0; pl=0%;20;60;;
REGEX: match=0.104
REGEX: graph_value=Loss
REGEX: output=perfdata
REGEX: regex=m/.*pl=([0-9]*)/i
REGEX: perfdata=rta=0.104ms;200.000;500.000;0; pl=0%;20;60;;
REGEX: match=0
VALUES: [swobspace][PING]: RTA=0.104 Loss=0
RRD: rrdtool update /var/lib/rrd/nagios_grapher/swobspace/f66ffe61c885 d
e2d8b6d0c41ff444b39.rrd --template=RTA:Loss N:0.104:0
...
标签PRG标识程序状态,例如这里的重启。PIPE完整地重现从命名管道(主机名、服务描述、插件输出和性能数据,每个用制表符分隔)中获取的所有数据。REGEX显示了如何搜索匹配条目以及如何从中提取值。RRD揭示了使用rrdtool执行的命令,而VALUES显示了识别的值(PING)。
^([205]) www.nagiosexchange.org/42;195
^([206]) 从 NagiosGrapher 1.7 版本开始,文件config.layout已经包含了条目<Layout nagiosbook>。
^([207]) 即使在运行make update时,事先备份配置文件也不会有害。
^([208]) 请参阅第 405 页的 19.1.1 模板机制。
^([209]) 由于我们手头有 Perl 脚本,这当然是一个 Perl 正则表达式。
^([210]) RPN 的介绍可以在people.ee.ethz.ch/˜oetiker/webtools/rrdtool/tut/rpntutorial.en.html找到。
^([211]) 环境宏的描述可以在第 D.1.8 节 使用关于环境的标准宏中找到,从第 631 页开始。
^([212]) 通常:2^n - 1,其中n≥8。
19.6 使用 PNP 进行平滑绘图
PNP 不是 PerfParse——这个递归缩写是对 PerfParse 工具的暗指(本书中未描述),PNP 的作者 Jörg Linge 和 Hendrik B$aUcker 显然在宣扬他们自己的工具处理性能数据的优点:据说它安装起来非常容易(与 PerfParse 相比),并且几乎无需配置即可使用,但提供了广泛的配置选项以供高级使用。
除了提供特定检查的常规图表外,PNP 还创建了一个属于一个主机的所有图表的概述。一个基于 AJAX 的输入字段允许输入主机名。在输入过程中,名称会自动完成,并显示一个匹配列表的替代完成。图形具有复杂的外观,并且可以导出为 PDF 格式。
PNP 直接从插件输出保留区域获取性能数据,也就是说,只有显示性能数据的标准格式的插件才能使用。与 NagiosGrapher 不同,无法从正常文本输出中提取数据。为了弥补这一轻微的限制,PNP 自动输出所有插件的性能数据。如果 PNP 无法识别插件,它将使用通用模板。
在 PNP 主页([213])上,您可以找到英文邮件列表([214])和德语论坛的地址,尽管如此,您可以用英语提问.^([215]) 英文主页是www.pnp4nagios.org/pnp/。
以下描述适用于 PNP 版本 0.4;较旧版本可能不具备此处描述的所有功能。
19.6.1 安装
安装要求相当简单:Apache、Perl(无需任何特殊模块)、PHP4 版本 4.3.0 或 PHP5,以及所有 RRDtools.^([216]) 如果可能,您应该从您的发行版中包含的 Perl 包中安装 Perl 模块 RRDs(例如,Debian 中的librrds-perl)。Perl 脚本process_perfdata.pl将 Nagios 性能数据转发到 PNP,然后直接访问 RRD 数据库,而不运行外部程序。
PNP 源代码从主页^([217]) 下载,并在/usr/local/src目录中适当解包:
linux:~ # **cd /usr/local/src/**
linux:local/src # **tar xvzf** /path/to/**pnp-0.4.tar.gz**
...
linux:local/src # **cd pnp-0.4**
linux:src/pnp-0.4 # **./configure --sysconfdir=/etc/pnp**
...
最后,make all编译必要的 C 程序,make install完全安装 PNP。在configure命令中,--sysconfdir=/etc/pnp允许在/etc/pnp中安装配置示例,这符合本书中使用的约定。其他configure选项可以通过./configure --help查看。
19.6.2 标准配置
在安装 PNP 期间,各种数据被放置在配置目录中(在这种情况下为/etc/pnp),包括config.php,这是 Web 界面的配置文件。在那里,您必须首先检查rrdtool和性能数据目录的路径是否设置正确:
# /etc/pnp/config.php
...
$conf['rrdtool'] = "/usr/bin/rrdtool"
$conf['rrdbase'] = "/usr/local/nagios/share/perfdata"
...
/etc/pnp 还包含数据收集器process_perfdata.pl的示例配置,在文件process_perfdata.cfg-sample和rra.cfg-sample中。这两者都不是绝对必要的:PNP 在没有调整的情况下也能正常工作。但为了使用数据收集器,您需要重命名文件process_perfdata.cfg和rra.cfg,并相应地修改它们。如果已安装 Perl 模块 RRDs,则它在process_perfdata.cfg文件中通过USE_RRDS=1被激活:
# /etc/pnp/process_perfdata.cfg
TIMEOUT = 5
USE_RRDs = **1**
RRDPATH = /usr/local/nagios/share/perfdata
RRDTOOL = /usr/bin/rrdtool
CFG_DIR = /etc/pnp/
RRA_CFG = /etc/pnp/rra.cfg
RRA_STEP =60
LOG_FILE = **/var/nagios/pnp-perfdata.log**
LOG_LEVEL = 0
样本文件中的第二次更改(此处为粗体)指的是 Nagios 日志文件的目录,在本书中命名为/var/nagios。
rra.cfg用作新创建的 RRD 数据库的模板。如果需要修改现有数据库,则必须将其删除;但这样会丢失所有现有数据。该模板在存储长度和时间分辨率之间是一个很好的折衷方案:这会导致具有每小时时间分辨率的数存储长达四年,这样一个大约 400 KB 大小的 RRD 数据库。有关 RRD 数据库设置的说明,请参阅命令man rrdcreate。
在目录 /etc/pnp 中,还有 Nagios 性能数据 C 守护进程 npcd 的配置文件 npcd.cfg 和一个名为 自定义模板 的子目录 check_ commands。这两者将在 19.6.4 大量处理性能数据 中讨论。
调整 Nagios 配置
Nagios 有多种方式可以将性能数据传递给 PNP 数据收集器 process_perfdata.pl。最简单的方式是系统为每个事件运行一个单独的程序,称为 service-perf-data-pnp。为此,在文件 /etc/nagios/nagios.cfg 中通过参数 process_performance_data 启用性能数据处理,并通过 service_perfdata_command 定义要执行的命令:
# /etc/nagios/nagios.cfg
...
illegal_macro_output_chars='~$&|"<>
# -- perfdata
process_performance_data=1
service_perfdata_command=**service-perfdata-pnp**
...
不同的插件性能数据包含设置在单引号中的名称。为了防止这些名称在插件输出中丢失,参数 illegal_macro_output_chars 中 不得 使用单引号.^([218])
命令 service-perfdata-pnp 运行 process_perfdata.pl:
# /etc/nagios/global/commands/service-perfdata-pnp.cfg
define command{
command_name service-perfdata-pnp
command_line /usr/bin/perl /usr/local/nagios/libexec/process_perfdat
a.pl
}
内嵌的 Perl 解释器 ePN(见第 669 页的 附录 G)不能执行此 Perl 脚本,因此必须显式使用 /usr/bin/perl。如果 ePN 没有编译到 Nagios 中,可以省略 /usr/bin/perl 路径。
性能数据是通过环境变量 NAGIOS_SERVICEPERFDATA 由 process_perfdata.pl 采集的,因此通常必须不关闭环境变量.^([219])
19.6.3 PNP 网页界面
如果你运行 nagios_server/nagios/pnp/index.php,你将被带到 PNP 概览页面(见 图 19-12). 这显示了 PNP 找到的第一个主机的数据,按字母顺序排列。右上角的输入字段使用 AJAX 实现,并显示一个匹配已输入文本的命中列表,从中选择所需的主机。相关的概览页面以 24 小时视图展示所有服务。
这也可以直接通过 nagiosserver/nagios/ pnp/index.php?host=hostname 访问。如果你将 *`hostname`* 替换为 elix01,你将到达该名称的主机概览页面(图 19-12)。

图 19-12. elix01 在一页上的所有服务
在服务图形或概述中右侧的辅助链接上单击鼠标,会导致所选显示以不同的时间分辨率显示(图 19-13):四小时、一天和(未显示)一周、一个月和一年。PNP 在此处显示的周期在配置文件config.php中定义:
$views[0]["title"] = "4 Hours";
$views[0]["start"] = ( 60*60*4 );
$views[1]["title"] = "24 Hours";
$views[1]["start"] = ( 60*60*24 );
$views[2]["title"] = "One Week";
$views[2]["start"] = ( 60*60*24*7 );
$views[3]["title"] = "One Month";
$views[3]["start"] = ( 60*60*24*30 );
$views[4]["title"] = "One Year";
$views[4]["start"] = ( 60*60*24*365 );
具体的title标签可以自由选择,因此您也可以使用其他语言中的文本。然而,图像本身无法本地化。

图 19-13. PNP 中的系统负载:主机elix01,服务lx-load
start细节指定了图形在定义的参考点之前多少秒开始。通常使用当前时间作为参考点,但也可以使用包含的日历来选择。为此,您点击日历图标(见图 19-14),用鼠标点击选择时间后的结束时间,然后选择日期。选择时间需要一些习惯:单击会增加显示的值,同时按住
键会减少显示的时间值。您也可以按住左鼠标按钮并拖动鼠标向左增加值,或向右拖动以减少值。

图 19-14. PNP 的日历功能
为了直接显示特定的服务,只需将详细资料svc=*****`servicename`*添加到 URL 中,这样您就有nagiosserver/nagios/pnp/index.php?host=hostname&svc=servicename。
PNP 的一个特定功能是每个图形都可以直接访问,而无需使用 HTML 或 PHP 页面。您需要两个可选参数display和view:nagiosserver/nagios/pnp/index.php?host=host&svc=servicename&display=image&view=0。display目前只能处理值image,而对于view,您输入在config.php中定义的索引:view=0指的是在那里用$views [0] ["start"]定义的时间周期(因此这是默认值,具有四小时概述)。
将 PNP 集成到 Nagios Web 界面
要在 Nagios 3 中直接从 Nagios Web 界面显示单个服务,您需要在服务定义中集成以下 URL 作为action_url:
# Nagios 3
define service {
hostname *hostname*
service_description *servicename*
...
action_url /pnp/index.php?host=$HOSTNAME$&srv=$SERVICEDESC$
}
在 Nagios 2.x 中,你需要对象serviceextinfo来实现相同的目的:
# Nagios 2.x
define serviceextinfo {
hostname *hostname*
service_description *servicedesc*
...
action_url /pnp/index.php?host=$HOSTNAME$&srv=$SERVICEDESC$
}
19.6.4 批量处理性能数据
讨论的常规配置调用每个检查中定义的service_perfdata_command命令。由于嵌入的 Perl 解释器 ePN(见第 669 页的附录 G)无法执行process_perf-data.pl,Nagios 必须为每个需要处理性能数据的服务的 Perl 解释器重新启动。这消耗了资源,并且根据主机的能力和要处理的服务数量,对 Nagios 的性能产生负面影响(要测量 Nagios 性能,请参阅第 653 页的附录 F)。因此,Nagios 实际上是被逼到了绝境,这意味着从计划开始点到实际开始检查之间的延迟时间大大增加,Nagios 的时间表(即调度)失控。
由 PNP 的批量模式与Nagios 性能数据 C 守护进程(NPCD)的组合提供了一种解决方案。^([220)当使用它时,Nagios 将性能数据——由模板(在service_perfdata_file_template中定义)格式化——写入一个文件,该文件由service_perfdata_file_processing_command中的命令定期重命名。NPCD 现在只为每个文件运行一次 Perl 脚本process_perfdata.pl。
service_perfdata_file_template定义了将数据写入service_perfdata_file中指定的文件时的格式:^([221])
# /etc/nagios/nagios.cfg
...
service_perfdata_file_template=DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$
\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SE
RVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::
$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICEST
ATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$
service_perfdata_file=/var/nagios/service-perfdata
service_perfdata_file_mode=a
service_perfdata_file_processing_interval=30
service_perfdata_file_processing_command=service-perfdata-npcd
...
service_perfdata_file_mode指定 Nagios 如何处理文件:值a代表追加。因此,Nagios 将新结果追加到已存在的文件中。每 30 秒(如service_perfdata_file_processing_interval中指定)启动文件处理命令 service-perfdata-npcd。它移动文件,重命名它,并添加当前的时戳,使用 Nagios 宏$TIMET$:
define command{
command_name service-perfdata-npcd
command_line /bin/mv /var/nagios/service-perfdata /var/nagios/perfsp
ool/service-perfdata-$TIMET$
}
重命名和移动不会消耗任何时间。因此,Nagios 可以立即恢复其正常任务,并将性能数据的进一步处理留给外部 NPCD 守护进程。NPCD 有自己的配置文件,在npcd.cfg中,安装期间被复制到目录/etc/pnp:
user=nagios
group=nagios
log_type=syslog
log_level=0
perfdata_spool_dir=/var/nagios/perfspool/
perfdata_file_run_cmd=/usr/local/nagios/libexec/process_perfdata.pl
perfdata_file_run_cmd_args=-b
npcd_max_threads=1
前两个条目指定 NPCD 应以哪个用户和哪个组成员身份启动。守护进程目前只能将其工作记录在 syslog 中。未来的版本也应该允许将其写入单独的文件。log_level=0确保 NPCD 本身保持安静,并将所有错误仅传递给 syslog 守护进程。
参数perfdata_spool_dir将监控的目录重命名。它必须已经存在;NPCD 不会自动创建它。由于在perfdata_file_run_cmd_args, process_perfdata.pl中给出了参数-b,因此以批量模式启动。
NPCD 在 PNP 的"make install"命令期间将自己安装到目录/usr/local/nagios/bin。运行make install-init会在/etc/init.d中放置一个额外的启动脚本,您需要检查配置文件的路径:
...
CONF=/etc/pnp/npcd.cfg
...
通过以下命令启动守护进程:
linux:~ # /etc/init.d/npcd start
根据您的发行版,rc目录中的初始化脚本链接到相关的运行级别:
linux:~ # ln -s /etc/init.d/npcd.sh /etc/init.d/rc2.d/S99npcd
linux:~ # ln -s /etc/init.d/npcd.sh /etc/init.d/rc3.d/S99npcd
linux:~ # ln -s /etc/init.d/npcd.sh /etc/init.d/rc5.d/S99npcd
19.6.5 图形应该如何显示?
PNP 图形的外观由模板决定。包含的示例位于目录/usr/local/nagios/share/pnp/templates.dist中。您不应该修改这些文件,因为它们将在下一次更新时被覆盖。目录templates用于一些模板。PNP 会取command_name中定义的检查名称,并在这里搜索一个名为*command_name.php*``的匹配模板。
如果 PNP 既找不到./templates或./templates.dist中的这个文件,它将使用默认模板default.php。
有时在templates.dist中已经存在一个合适的模板(例如,check_ping.php用于插件check_icmp),其名称与命令名称不匹配(在check_icmp的情况下,我们将其定义为command_name check_icmp)。然后您必须在./templates中创建一个指向所需文件的符号链接:
linux:~ # **cd /usr/local/nagios/share/pnp/templates**
linux:pnp/templates # **ln -s../templates.dist/check_ping.php \
check_icmp.php**
一个简单的模板,可以用于所有传输简单响应时间的插件是response.php:
<?php
#
# For all plugins that provide response times
# $Id: response.php 53 2006-06-07 07:16:50Z linge $
#
$opt[1] = "--vertical-label \"Response Time\" \
--title \"Response Time For $hostname / $serviced
esc\" ";
$def[1] = "DEF:var1=$rrdfile:$DS[1]:AVERAGE " ;
$def[1] .= "AREA:var1#00FF00:\"Response Times \" " ;
$def[1] .= "LINE1:var1#000000:\"\" " ;
$def[1] .= "GPRINT:var1:LAST:\"%3.41g %s$UNIT[1] LAST \" ";
$def[1] .= "GPRINT:var1:MAX:\"%3.41g %s$UNIT[1] MAX \" ";
$def[1] .= "GPRINT:var1:AVERAGE:\"%3.4lg %s$UNIT[1] AVERAGE \" ";
?>
变量$opt[1]定义了rrdtool的选项,变量$def[1]定义了 RRD 图形。如果您想创建自己的模板,您需要更详细地了解rrdtool。图形的定义在man rrdgraph中有详细解释,更多信息可以在主页上找到.^([222])
自定义模板
PNP 基于定义的命令对象的名称。如果这不足以提供信息,例如在command_name check_nrpe的情况下,那么将使用目录/etc/pnp/check_commands中的所谓自定义模板。然而,这些模板必须包含原始命令的名称,在我们的例子中是check_nt.cfg:
#
# Adapt the Template if check_command should not be the PNP Template
#
# check_command check_nt!MEMUSE!80%!90%
# ________0__________| | | |
# ________1________________| | |
# ________2_____________________| |
# ________3________________________|
#
CUSTOM_TEMPLATE = 0,1
#
如果 check_nt 没有将 MEMUSE 作为第一个参数给出,那么插件 check_nt 的实际命令,只有这个参数才能区分是测量内存使用还是 CPU 负载,例如。参数 CUSTOM_TEMPLATE 组合了 PNP 在搜索模板时使用的命令:下面的例子组合了 check_nt(条目编号 0)和 MEMUSE(条目编号 1)。这意味着 PNP 将搜索名为 check_nt_MEMUSE.php 的模板。如果 CUSTOM_TEMPLATE = 1,PNP 将搜索 MEMUSE.php。现在在目录 ./templates 中设置了一个合适的符号链接:
linux:~ # **cd /usr/local/nagios/share/pnp/templates**
linux:pnp/templates # **ln -s ../templates.dist/check_nt_mem.php**\
**check_nt_MEMUSE.php**
^([213]) www.pnp4nagios.org/pnp/
^([214]) lists.sourceforge.net/mailman/listinfo/pnp4nagios-users(通常关于 PNP 使用)和 lists.sourceiorge.net/mailman/listinio/ pnp4nagios-devel(功能请求、错误、补丁等)
^([215]) nagios-portal.de/forum/board.php?boardid=58
^([216]) www.rrdtool.org/,也参见 19.4.1 安装。
^([217]) www.pnp4nagios.org/pnp/
^([218]) 性能数据由宏 $SERVICEPERFDATA$ 提供;参见 D.1.1 主机宏。
^([219]) 这只有在 Nagios 3.0 之后才成为可能,因为有了 enable_environment_macros 参数(参见 A.1 主配置文件 nagios.cfg)。关于环境变量的更多信息,请参见第 631 页的 D.1.8 关于环境的标准宏的使用。
^([220]) 名称中的 C 指的是与 Perl 脚本相比,C 程序的执行速度要快得多,因为 Nagios 每次都需要重新启动 Perl 解释器。
^([221]) 这只是一行,这里为了显示目的进行了换行。
^([222]) www.rrdtool.org/
19.7 其他工具和图形评估的限制
除了这里介绍的工具之外,www.nagiosexchange.org/ 还提供了用于性能数据图形评估的更多工具。其中许多也是基于 RRDtools 和循环冗余数据库,其结果是它们对于多年精确评估并不太有用,就像这里描述的那样。
几个工具,如当前的 APAN^([223]) 版本,将它们的数据保存在 SQL 数据库中,从而实现长期统计而不会丢失数据。
PerfParse^([224]) 非常广泛,它将数据存储在 MySQL 或 PostgreSQL 数据库中,并包括其自己的广泛评估工具。因为它使用了各种当前库,而这些库并不包含在每个发行版中,所以安装障碍相当高。然而,对于那些 RRD 工具提供不足的人来说,应该看看 PerfParse 工具是否可以提供所需的功能。
尽管提供了所有这些选项,Nagios 性能数据的图形显示也有其局限性。如果你通过 ping 远程主机来检查 WAN 连接并测量平均响应时间,如果检查间隔只有每五分钟一次,那么所有漂亮的图形都没有什么意义。你每五分钟只能收到一个瞬间的快照,这并不能提供任何关于连接在一段时间内流量负载的严重线索。
要能够合理评估插件每分钟、五分钟和十五分钟报告的 Unix 计算机负载,检查间隔应该是一分钟。不那么关键的数据包括已使用的硬盘空间或温度。同样非关键的是网络流量的显示,插件以计数器的形式显示这些值。基于 RRD 的工具可以自动检测两次测量之间的差异并显示它们;检查间隔是一分钟、两分钟还是五分钟,这里都没有关系;没有数据丢失。
如果 Nagios 的测量精度不尽如人意,你可以并行部署其他工具,例如 Cricket^([225]) 或 Cacti.^([226])。如果外部工具(如 Munin^([227]))与 RRD 数据库一起工作,你可以检查这些关键值,以便它们包含在复杂的 Nagios 通知系统中。或者,外部工具可以提供一个接口,用于进一步处理记录的数据。这些可以作为被动测试结果传递给 Nagios,例如使用 NSCA(见第十四章)。
但额外的工具总是有增加配置努力的缺点。这是否合理,或者 Nagios 性能监控是否足够,取决于特定情况下所需的信息。
^([223]) apan.sf.net/
^([224]) perfparse.sf.net/
^([225]) cricket.sourceforge.net/
^([226]) www.cacti.net/
^([227]) munin.projects.linpro.no/
第四部分. 第四部分 特殊应用
第二十章:监控 Windows 服务器
您并不总是处理由仅包含 Linux 或 Linux/Unix 计算机的同质服务器景观。只要您只是监控纯网络服务,操作系统就没有区别。但如果你想要查询本地、非网络功能的资源,那就完全是另一回事了。
对于基于 Unix 的系统,如 Mac OS X,您通常可以使用之前描述的工具(本地插件、NRPE、NSCA)。在 Windows 上,您必须寻找其他解决方案。在某种程度上,可以在模拟 Unix 的环境中运行和/或编译本地插件(例如,Cygwin[1])。
由于操作系统家族的不同哲学,也有一些独特之处,即一个操作系统中存在的功能在另一个操作系统中无法与之相比。因此,尽管 Windows 事件日志在 Unix 中的 syslog 中起到了类似的作用,但从技术角度来看,查询方式完全不同。在这里,你不能简单地编译 Unix 插件在 Windows 上,然后使用它。
对于 Windows 服务器的一种监控方法是使用 SNMP,Microsoft 提供了本机实现,只需安装即可。由于 Windows 代理的 SNMP 查询在原则上与其他 SNMP 代理的查询没有区别,我们建议您参考 第十一章,第 227 页。然而,Microsoft 的实现并不总是可靠,尤其是在显示图表——尤其是 CPU 负载和硬盘空间方面。

图 20-1. check_nt 查询本地 Windows 资源关于 NSClient 机制。
但如果你在 Windows 服务器上安装了一个可以通过网络访问的服务,你也可以查询本地 Windows 资源。以前,只有一个工具可用,那就是 NSClient,但如今你有多种程序可供选择:NSClient、NSClient++、OpMon Agent 或 NC_Net。对于所有这些,都会使用 check_nt 插件查询基本参数,如 CPU 和硬盘负载、内存使用或 Windows 计数器(参见 图 20-1),这是 Nagios 的标准插件之一。

图 20-2. check_nrpe 使用 NRPE 机制通过 NSClient++、OpMon Agent 和 NRPE_NT 执行检查。
此外,NSClient++和 OpMon Agent 支持 NRPE(见第十章"), 从第 213 页开始)。通过check_nrpe(图 20-2)查询本地安装的插件。
NC_Net 反过来也允许被动检查,其结果通过 NSCA 发送到 Nagios 服务器(第十四章"), 第 299 页)。如果您使用check_ncnet(图 20-3)而不是标准插件check_nt,则可以访问一组扩展的命令(20.3.3 安装 check_ncnet 插件, 第 480 页)。

图 20-3. check_ncnet 允许被动检查。
最后,还有一个纯 NRPE 服务用于 Windows:NRPE_NT,其配置与 Unix 相同。然而,由于 NSClient++和 OpMon Agent 增加了额外的 NRPE 功能,因此它已经失去了一些重要性。
20.1 通过 WMI 进行无代理检查
通过Windows 管理规范,或简称 WMI,微软提供了一个允许网络查询系统属性的接口,前提是执行查询的用户拥有足够的权限。WMI 查询从中央 Windows 系统执行;NRPE 用于 Nagios 服务器与 WMI 代理之间的通信(图 20-4). 只需要一个 Windows 服务器,在该服务器上安装一个 NRPE 服务以及所有所需的插件,形式为 WMI 脚本——尽管要这样做,您必须熟悉微软的 WMI 世界。

图 20-4. 使用 Nagios 的 WMI 接口
在 NagiosExchange^([229])的类别 | 检查插件 | 操作系统 | Windows | Windows NRPE下可以找到大量的配置示例,例如,在wmi 无代理插件条目下.^([230])在此处我们将不深入探讨 WMI 接口的细节。
^([228]) www.cygwin.com/
^([229]) www.nagiosexchange.org
^([230]) www.nagiosexchange.org/66;235
20.2 安装和配置附加服务
与 WMI 方法相比,NSClient、NS-Client++、OpMon Agent 和 NC_Net 等附加服务必须在每个 Windows 服务器上单独安装。
20.2.1 NSClient
作为最古老的包,NSClient 已经过广泛的测试,并且被广泛使用,但它已不再积极开发。最新的当前版本是 2003 年 10 月的版本;该包可以从 Nagios Exchange 下载.^([231])。它也适用于 Windows NT、Windows 2000 和 Windows XP。
对于 Windows 2003,特别是 Windows 2003 R2,原始包不再适用,因为出现了许多错误信息
PDH.dll Collect CPU - ERROR:...
出现在事件日志中,这会显著增加执行时间。在 NagiosExchange 上可以找到一个重新编译的版本,在包 nsclient_-_no_pdh.zip 中,^([232]) 该版本不存在此问题。
对于 NSClient 的安装,您需要解压存档 nsclient_201.zip 或 nsclient_-_no_pdh.zip。这会创建按照架构命名的子目录:Win_NT4_Bin 用于 Windows NT 和 Win_2k_XP_Bin 用于 Windows 2000 及更高版本。将相应文件夹的内容复制到目录 C:\Programs\NSClient,然后从该目录安装 NSClient 作为服务:
C:\Programs\NSClient> **pNSClient.exe /install**
C:\Programs\NSClient> **net start nsclient**
运行 pNSClient.exe /install 安装服务,而开关 /uninstall 则再次删除服务。您应该确保操作系统通过服务管理自动启动。
NSClient 有两个参数:port 和 password,默认值为 1248(端口号)和 none(密码)。这些值只能通过 regedit 在 HKEY_LOCAL_MACHINE\SOFTWARE\NSClient\Parms 注册表下进行更改。
20.2.2 NC_Net
NC_Net,由 Tony Montibello 开发,是 NSClient 的继承者之一,其调用也与 NSClient 兼容。因此,在 Windows 服务器上,可以直接用 NC_Net 替换 NSClient,无需更改 Nagios 配置。NC_Net 的发展非常活跃。本书付印时的当前版本为 4.x,基于 DOT.NET 框架,版本 2.0。默认情况下,从 Windows Server 2003 R2 开始才包含此框架,但即使在那时也不是自动安装的。对于那些不能或不想安装新框架的用户,较旧的 NC_Net 版本 2.28 可以在 DOT.NET 1.1 下运行,非常稳定且已建立良好。
NC_Net 版本 2.28 可在 NC_Net 主页上找到,^([233]) 而所有更新的版本都可以在 SourceForge 上找到.^([234])。请确保首先卸载任何之前安装的版本。由于 NC_Net 使用 Microsoft Installer,您可以通过软件管理工具来完成此操作。即使可能存在的 NSClient 也应首先删除。
双击文件 NC_Net_setup.msi 将安装服务,但你应该在服务管理中检查它是否真的正在运行,以及是否已将 自动 作为启动类型输入。
NC_Net 具有与 NSClient 相同的参数,包括 密码 和 端口,但也可以在服务管理中的 属性 下的 启动参数 行中指定:
port 4711 password *password*
20.2.3 NSClient++
NSClient++结合了两种查询方法。一方面,它与 NSClient 兼容,可以使用 check_nt 进行常规查询。另一方面,它包含一个内置的 NRPE 服务,可以像 NRPE_NT(见第 488 页的 20.4.1 NRPE_NT,经典工具])不仅提供了下载区域和以 Wiki 形式存在的文档,还提供了一个错误跟踪系统,允许你报告任何错误并提交请求,包括跟踪开放票据。
安装
当前 NSClient++版本可以作为 zip 文件从主页^([236])或从 SourceForge.^([237])下载。此文件的内容被解压,例如在 D:\Program Files\Nagios\nsclient++ 中,然后从这里将其作为服务安装,并启动程序:
D:\Program Files\Nagios\nsclient++> **NSClient++/install**
D:\Program Files\Nagios\nsclient++> **NSClient++/start**
如果你想使用传统的 net start 命令而不是管理工具来启动和停止服务,你需要知道它被称为 nsclientpp(而不是 nsclient++):
D:\> **net start nsclientpp**
D:\> **net stop nsclientpp**
配置
NSClient++需要一个配置文件 NSC.ini,该文件位于 NSClient++-EXE 文件所在的同一目录中。在所有情况下都需要编辑分发中的 NSC.ini。
此文件分为多个部分:
[modules]
; loadable modules
[Settings]
; general settings
[log]
; Logging and debugging
[NSClient]
; Parameters for NSClient-compatible queries
[Check System]
; Fine-tuning configuration for system checks (CPU, memory, ...)
[NRPE]
; Parameters for NRPE
[NRPE Handlers]
; NRPE commands
每个部分都以方括号中的关键字开始,注释行以分号开头。[modules] 部分加载单个模块。以下模块目前可用:
[modules]
FileLogger.dll
CheckDisk.dll
CheckSystem.dll
NSClientListener.dll
NRPEListener.dll
; SysTray.dll
; CheckHelpers.dll
; CheckWMI.dll
内部模块 FileLogger.dll 将 NSClient++的工作记录到文件中,并且不提供任何检查。
CheckDisk.dll 检查文件大小和硬盘使用情况,而 CheckSystem.dll 检查 CPU、内存、计数器、运行时间和服务及进程状态。
NSClientListener.dll 确保与 NSClient 的兼容性。如果此模块未加载,则使用 check_nt 的查询将失败。模块 NRPEListener.dll 实现了 NRPE 服务。这意味着您可以选择是否使用 NSClient++ 作为 NSClient 或作为 NRPE_NT 的替代品,或者同时使用这两个功能。
SysTray.dll 在服务器上安装一个系统托盘图标,以便访问 NSClient++。
CheckHelpers.dll 是一个测试模块,它总是提供一个特定的返回值(例如,OK),并且对于正常操作不是必需的。
CheckWMI.dll 提供了 WMI 接口的查询,但尚未完全完成。
全局部分 [Settings] 包含跨越部分边界的设置,包括密码参数和 allowed_hosts,这些设置由 [NSClient] (配置) 和 [NRPE] (Windows 中的 Perl 插件) 部分继承,除非在这些选项中设置了不同的值:
[Settings]
; obfuscated_password=Jw0KAUUdXlAAUwASDAAB
; password=secret-password
allowed_hosts=
use_file=1
obfuscated_password,就像 password 一样,目前仅由 NS-Client 兼容的 NSClient++ 部分使用,而不是 NRPE。这两个参数都设置了 check_nt. obfuscated_password 的密码,这会将其隐藏,使其不会在 INI 文件中以明文形式出现。然而,这并不是真正的加密。obfuscated_password 是通过运行 nsclient++ /encrypt 生成的。此实用程序会要求输入密码,然后以加密形式显示它.^([238])
参数 allowed_hosts 控制哪些 IP 地址可以访问 NSClient++。如果留空,则没有访问限制。您可以通过逗号分隔来指定多个 IP 地址,但在此处不能使用主机名。
最后,use_file 控制是否使用配置文件(use_file=1)。如果在此处输入的值是 0,NSClient++ 将在注册表中搜索设置。通过注册表进行配置目前仍然是实验性的,并且由于缺乏足够的保护,存在安全风险,因此我们不会对此进行更详细的探讨。
下一节是关于日志记录的:
[log]
debug=0
; file=NSC.log
date_mask=%Y-%m-%d %H:%M:%S
使用 debug=1,可以开启调试(默认情况下是禁用的,使用值 0)。file 指定日志文件。如果您省略此参数或(如所示)将其注释掉,NSClient++ 将将其错误消息写入 nsclient.log,位于二进制文件所在的同一目录中。即使调试被关闭,软件也会这样做。使用 date_mask,您可以指定每条日志消息开始时的时间戳的日期格式。此格式与 man date 中描述的格式相对应。
[NSClient] 部分设置了一些关于与 NSClient 兼容性的选项。尽管这里不能配置其他内容,但 NSClient 函数(见第 472 页的 20.3 The check_nt Plugin]
参数 allowed_hosts 覆盖了 [Settings] 部分的设置。通过这种方式,NSClient++ 可以使用与 NRPE 不同的配置来与 check_nt 一起工作:
[NSClient]
; allowed_hosts=
port=12489
; bind_to_address=
port 和 bind_to_address 参数指定 NSClient++ 接受 check_nt 查询的套接字。端口的默认值为 1248,这在一些 Windows 服务器(例如,Exchange 服务器)上通常会引发问题(也请参阅第 471 页)。因此,你应该将其更改为更高的端口号(例如,12489)。
bind_to_address 指定服务将监听的预期主机的 IP 地址。如果计算机有多个网络接口并且需要设置特定的 IP 地址,则需要此参数。
[Check System] 部分允许对系统检查进行微调。通常你在这里不需要配置任何内容:
[Check System]
; CPUBufferSize=1h
; CheckResolution=10
CPUBufferSize 决定了 NSClient++ 存储 CPU 负载信息的时间长度。允许的值范围从一秒(1s)开始,最大值通常是几周(10w)。然而,为了长期保存数据,你需要大量的内存。对于大多数用途,默认值一小时就足够了。
CheckResolution 指定了存储的测量值的分辨率,单位为十分之一秒。因此,值 10 表示每秒确定一个值。CheckResolution 目前仅影响 CPU 测量值。
[Check System] 部分的其他参数很少需要,并在 Wiki 中有文档说明。240]
在 20.4.3 NRPE with NSClient++(第 493 页)中处理了两个部分 [NRPE Handlers] 和 [NRPE] 中的 NRPE 服务的配置,并且描述了可以通过 NRPE 调用的 NSClient++ 的内部函数,在 20.4.4 Internal NSClient++ functions]。因此,它可以被认为是 NSClient 程序的继任者。像其前身一样,该软件在 GNU 公共许可证下发布。
要安装它,请将当前 zip 文件从www. opservices.com.br/downloads/解压到C:\Program Files\Nagios\opmonagent,并输入以下命令:
C:\Program Files\Nagios\opmonagent> **opmonagent/install**
C:\Program Files\Nagios\opmonagent> **net startopmonagent**
OpMon Agent 也将其配置存储在 INI 文件中。原始的opmo-nagent.ini看起来如下:
[OPMONAGENT]
enable=1
password=None
port=5667
allow_from=127.0.0.1,192.168.10.2,192.168.2.1
autodetect_counters=1
use_counters=W2K
max_connections=300
debuglevel=0
[NRPE]
enable=1
port=5666
command_timeout=60
allow_from=127.0.0.1,192.168.10.1,192.168.2.1
NSClient 功能在[OPMONAGENT]部分进行配置。enable=1允许通过check_nt进行查询,但如果此参数设置为0,OpMon Agent 将忽略此设置。
password设置密码,值None表示不需要密码。否则,密码将以明文形式写在等号之后。
在此处输入 5667 作为标准端口,但如果你想使用常用的端口 1248,只需更改条目并重新启动服务。allow_from限制了对特定主机的访问。
autodetect_counters=1尝试根据 Windows 的语言设置和确切版本自动确定 Windows 性能计数器的确切名称。如果你通过值0关闭此功能,必须在use_counters中显式指定名称。此参数的可能值列在counters.def文件中,该文件位于与opmonagent.ini相同的目录中。
max_connections限制可能的同时连接数。debuglevel的值大于0时开启调试模式。
在未来,应该可以在[NRPE]部分配置 OpMon Agent 的 NRPE 功能,这些功能将在稍后的版本中引入。本书付印时的 OpMon Agent 当前版本 2.4 尚未提供对 NRPE 的官方支持。
20.2.5 矫正端口 1248 的问题
所有与 NSClient 兼容的服务默认在端口 1248 上运行。这有时可能成为一个问题,因为 Windows 操作系统与 RPCs(远程过程调用)进行密集型工作。端口是动态分配的,从端口 1025 开始。因此,在特定情况下——例如,对于拥有许多服务或许多同时连接的服务器——当 NSClient 作为服务启动时,端口 1248 通常已经被占用。对于 Exchange 服务器,重启后这种情况相当常见。因此,你应该将其更改为一个高端口,如 12489,这样就不会有问题。
如果你不是第一次安装 Nagios,而是在使用现有的安装,你可能无法轻松地更改所有要监控的主机的端口。对于 Nagios 2.x,除了为每个端口定义单独的命令外,别无选择。在 Nagios 3.0 中,这可以做得更加优雅。解决方案是使用自定义变量(见第 685 页的 H.2 变量和宏,第 75 页)中,现在全局指定为标准端口(在此示例中为 1248):
define host{
name host_t
register 0
...
_NSCLIENT_PORT 1248
...
}
对于已经转换为新端口的已转换主机,你用新端口覆盖 _NSCLIENT_PORT 变量:
define host{
host_name winsrv
use host_t
...
_NSCLIENT_PORT 12489
}
对于所有其他主机,模板中定义的值将适用。命令对象的定义会考虑到所需的端口,通过评估变量来实现,如下所示:
define command{
command_name check_nt
command_line $USER1$/check_nt -H $HOSTADDRESS$ -p $_HOSTNSCLIENT_POR
T$ -v $ARG1$ $ARG2$
}
这意味着对于每个新转换的主机,只需以这种方式设置变量即可,所有服务定义保持不变。
^([231]) www.nagiosexchange.org/49;65
^([232]) www.nagiosexchange.org/49;508
^([233]) www.shatterit.com/NC_Net
^([234]) sourceforge.net/projects/nc-net
^([235]) trac.nakednuns.org/nscp/
^([236]) trac.nakednuns.org/nscp/downloads
^([237]) sourceforge.net/projects/nscplus/
^([238]) 使用的算法没有文档说明,因此应谨慎使用此实用程序。
^([239]) MEMUSE 命令(见主内存使用]) trac.nakednuns.org/nscp/wiki/Documentation
^([241]) www.opservices.com.br/
20.3 check_nt 插件
当安装标准 Nagios 插件时,check_nt 插件会自动加载到硬盘上。这里可以查询的检查对应于 NSClient 在 NSClient、NS-Client++、OpMon Agent 和 NC_Net 中提供的功能范围。要使用 NC_Net 的扩展,你必须从www.shatterit.com/NC_Net下载扩展源代码(文件check_nt.c)并自行编译。
下面描述的 check_nt 参数的实际效果取决于使用 -v 选项指定的命令:^([242]):
-H *`地址`* / --host=*****`地址`*
安装 NSClient/NC_Net 的主机的 IP 地址或主机名。
-v *`命令`* / --variable=*****`命令`*
要执行的命令。
-p *`端口`* / --port=*****`端口`*
这为 NSClient/NC_Net 定义了一个替代端口(见 20.2.5 纠正端口 1248 的问题,第 471 页)。默认为 TCP 端口 1248。
-w *`整数`* / --warning=*****`整数`*
这定义了一个警告限制。此选项不是所有命令都可用。
-c *`整数`* / --critical=*****`整数`*
临界限制选项也不是所有命令都可用。
-l *`参数`*
这用于传递参数,例如硬盘检查的驱动器或检查进程时的进程名称。
-d *`选项`*
在检查服务或进程时,您可以同时指定多个服务或进程。通常check_nt只显示有缺陷的项(-d SHOWFAIL)。要显示所有项,您必须指定SHOWALL作为*`选项`*。
-s *`密码`*
如果 NC_Net 或 NSClient 使用密码参数启动相应的服务,则才需要认证密码。
-t *`超时`* / --timeout=*****`超时`*
在*`超时`*秒后,插件终止测试并返回 CRITICAL 状态。默认为10秒。
20.3.1 通常支持的命令
对于这里介绍的命令,使用 NSClient、NSClient++、NC_Net 或 OpMon 没有区别;它们都可以与未打补丁的check_nt一起运行。
查询客户端版本
通过运行命令返回已安装的 NSClient 或 NC_Net 服务的版本
check_nt -H *address* -v CLIENTVERSION
所有其他参数都被忽略:
nagios@linux:nagios/libexec$ ./**check_nt -H winsrv -v CLIENTVERSION**
NC_Net 2.21 03/13/05
本书的第一版为每个check_nt功能定义了单独的命令。但这一点根本不必要,正如 Ethan Galstad 在 Nagios 的在线文档中所示:^([243])。
define command{
command_name check_nt_nsclient
command_line $USER1$/check_nt -H $HOSTADDRESS$ -v $ARG1$ $ARG2$
}
对于 Nagios 3.0,如果 NSClient 端口以主机依赖的方式定义(见 20.2.5 纠正端口 1248 的问题,第 471 页),则命令对象check_nt将如下所示:
define command{
command_name check_nt
command_line $USER1$/check_nt -H $HOSTADDRESS$ **-p$_HOSTNSCLIENT_POR**
**T$** -v $ARG1$ $ARG2$
}
要执行的命令行期望两个参数:宏$ARG1$在每种情况下都扩展为要调用的命令,而$ARG2$的内容取决于相应的命令,并在某些情况下可能为空:
define service{
host_name winsrv
service_description NSClient
check_command check_nt!**CLIENTVERSION**
...
}
命令CLIENTVERSION没有其他参数,因此第二个参数简单地被省略。
这项不起眼的服务在描述依赖关系方面极为有用。如果 NSClient/NC_Net 在 Windows 服务器上失败,Nagios 通常会通知管理员所有可能失败的服务。通过查询 CLIENT-VERSION,可以清楚地看出问题出在 NSClient 不可用。如果您定义了适当的依赖关系,Nagios 可以提供更精确的信息.^([244]) 下面是 NSClient 应用程序的示例:
define servicedependency{
host_name winsrv
service_description NSClient
dependent_host_name winsrv
dependent_service_description Disks,Load,Memory
notification_failure_criteria c,u
execution_failure_criteria n
}
以 NSClient 作为主服务,其他服务依赖于它,只要 NSClient 处于 CRITICAL 或 UNKNOWN 状态,Nagios 就不会让管理员收到这些其他服务的消息。
在 Nagios 2.x 中,您必须为每个主机单独设置依赖对象。在 Nagios 3.0 中有 相同的宿主依赖:如果您省略了 dependent_host_name 条目,这里定义的依赖关系适用于同一主机。这允许以合理的方式使用主机组:
# Nagios 3.0
define servicedependency{
hostgroup_name WINDOWS_SERVER
service_description NSClient
dependent_service_description Disks,Load,Memory
notification_failure_criteria c,u
execution_failure_criteria n
}
在这里,每个案例中的 Disks 服务仅依赖于同一主机的 NSClient 服务。在 Nagios 2.x 中使用主机组时,Disks 将依赖于主机组 WINDOWS.SERVER 中所有主机的所有 NSClient 服务——而这通常不是所希望的。
CPU 负载
处理器负载的严重程度可以通过 CPU-LOAD 命令揭示:
check_nt -H *address* -v CPULOAD -l *interval, warning limit, critical_limit*
它期望一个由逗号分隔的三元组参数,包括要平均的时间间隔长度(以分钟为单位),以及警告和临界限制的两个阈值(以百分比表示):
nagios@linux:nagios/libexec$ .**/check_nt -H winsrv -v CPULOAD -l 5,80,90**
CPU Load 10% (5 min average) | '5 min avg Load'=10%;80;90;0;100
因此,CPULOAD,配合 5,80,90,计算五分钟的平均值,如果确定值超过 80 百分比,则发出警告。如果 CPU 负载超过 90%,命令将返回 CRITICAL。
此处的输出还包含 | 符号之后的附加性能数据,Nagios 在 Web 界面中忽略这些数据。如果您对多个时间间隔的平均值感兴趣,只需在第一个值之后添加更多的三元组值:
nagios@linux:nagios/libexec$ .**/check_nt -H winsrv -v CPULOAD \**
**-l 5,80,90,15,70,80**
CPU Load 10% (5 min average) 10% (15 min average) | '5 min avg Load'=10
%;80;90;0;100 '15 min avg Load'=10%;70;80;0;100
在此示例中,CPULOAD 检查两个间隔:过去五分钟和过去 15 分钟。在第二种情况下,有不同的限制值。插件总是返回更严重的值;例如,如果一个间隔发出 CRITICAL 而另一个只是 WARNING,它将返回 CRITICAL。
因此,服务定义看起来是这样的:
define service{
host_name winsrv
service_description CPU Load
check_command check_nt!**CPULOAD**!-l 5,80,90,15,70,80
...
}
主内存使用
在指定限制值时,监控主内存使用量的命令——与 CPULOAD 相比——基于“正常”Nagios 插件的语法:
check_nt -H *address* -v MEMUSE -w *integer* -c *integer*
MEMUSE 返回内存使用百分比。应该记住,Windows 这里指的是内存和交换文件的总和,即整个可用的虚拟内存。命令期望警告和临界限制以百分比给出,不包含百分号:
nagios@linux:nagios/libexec$ .**/check_nt -H winsrv -v MEMUSE \**
**-w 70 -c 90**
Memory usage: total:4331.31Mb - used: 257.04Mb (6%) - free: 4074.27Mb (9
4%) | 'Memory usage'=257.04Mb;3031.91;3898.18;0.00;4331.31
在示例主机 winsrv 上,只使用了六分之一的虚拟内存。输出中没有显示主内存本身的物理大小(此处:256 MB)已经超过的事实。
然而,请求内存使用情况并不一定有意义,就像在 Unix 中一样:Windows 会定期将程序和数据代码从主内存交换出来,即使它还有额外的储备。在 Unix 中,程序和数据只有在需要比当前空闲空间更多的空间时才会进入交换分区。在这方面,Windows 整个虚拟内存的负载是更重要的参数。
上文提到的命令再次打包到一个服务对象中:
define service{
host_name winsrv
service_description MEM Usage
check_command check_nt!**MEMUSE**!-w 70 -c 90
...
}
硬盘容量
通过 USEDDISKSPACE: 测试文件系统的负载
check_nt -H *address* -v USEDDISKSPACE -l *drive letter* -w *integer* -c *integer*
在 Windows 风格中,文件系统指定为驱动器字母,百分比限制值:
nagios@linux:nagios/libexec$ .**/check_nt -H winsrv -v USEDDISKSPACE\**
**-l C -w 70 -c 80**
C: - total: 4.00 Gb - used: 2.06 Gb (52%) - free 1.94 Gb (48%) | 'C: Use
d Space'=2.06Gb;2.80;3.20;0.00;4.00
nagios@linux:nagios/libexec$ **echo $?**
0
在示例中,check_nt 应该在驱动器 C 超过 70% 容量时发出警告,如果负载超过 80%,则发出 CRITICAL。当前值位于 52%,因此 check_nt 返回 OK,你可以使用 echo $? 来检查。
相应的服务对象可能看起来像这样:
define service{
host_name winsrv
service_description Disk_C
check_command check_nt!**USEDDISKSPACE**!-l C -w 70 -c 80
...
}
运行时间
通过命令 UPTIME: 可以揭示上次重启执行的时间
check_nt -H *address* -v UPTIME
定义警告或临界限制是不可能的,这就是为什么这样的查询仅用于信息目的(插件返回 OK 或 UNKNOWN,如果使用不当):
nagios@linux:nagios/libexec$ .**/check_nt -H winsrv -v UPTIME**
System Uptime - 17 day(s) 9 hour(s) 54 minute(s)
因此,主机 winsrv 已经运行了 17 天。相应服务对象的一个合适定义可能如下所示:
define service{
host_name winsrv
service_description UPTIME
check_command check_nt!**UPTIME**
...
}
服务的状态
可以使用 SERVICESTATE 来检查 Windows 服务的当前状态:
check_nt -H *address* -v SERVICESTATE -d SHOWALL -l *service1, service2*,...
使用可选的 -d SHOWALL 可以确保输出文本列出所有服务。如果你省略此选项,插件只提供有关那些 not 正在运行的服务的信息。
在 -l 选项之后找到要为 NSClient 指定的服务描述名称是一项挑战。不是由服务管理器(例如,Routing and RAS)显示的 display name,而是对应的注册表条目。因此,你需要在注册表编辑器 regedit 的部分树 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services 中搜索具有相应显示名称的节点。它包含要查找的服务描述,对于 Routing and RAS 来说,可能是类似于 Remote-Access 的内容。
如果你使用 NC_Net,你的任务会更容易:该软件接受服务描述和显示名称,其中不区分大小写。以下两个示例使用显示名称:
nagios@linux:nagios/libexec$ .**/check_nt -H winsrv1 -v SERVICESTATE \**
**-l "RemoteAccess"**
RemoteAccess: Stopped
nagios@linux:nagios/libexec$ .**/check_nt -H winsrv2 -v SERVICESTATE \**
**-l "Routing and RAS"**
All services are running
在第一种情况下使用了服务名称;在第二种情况下使用了显示名称。第一个查询的服务没有运行,正如输出 Stopped 所示,并且 check_nt 返回 2(CRITICAL)作为返回值。第二个命令中提到的服务正在运行,这就是为什么如果没有给出 -d SHOWALL 选项,插件不会显示它。这里的返回值是 0(OK)。也可以在单个查询中查询多个服务(用逗号分隔)。这里的最坏情况结果决定了返回值。匹配的服务对象可能看起来像这样:
define service{
host_name winsrv
service_description Routing and RAS
check_command check_nt!**SERVICESTATE**!-l RemoteAccess
...
}
进程状态
与服务类似,PROCSTATE 监控正在运行的过程:
check_nt -H *address* -v PROCSTATE -d SHOWALL -l *process1, process2*,...
进程名称,几乎总是以 .exe 结尾,最好在任务管理器的进程列表中确定;这里也忽略了大写和小写:
nagios@linux:nagios/libexec$ .**/check_nt -H winsrv -v PROCSTATE** \
**WinVNC.exe,winlogon.exe,notexist.exe**
notexist.exe: not running
与服务类似,您也可以指定一个由逗号分隔的多个进程列表。没有 -d SHOWALL, PROCSTATE 时,PROCSTATE 只显示那些 not 正在运行的进程,在这个例子中,notexist.exe。对应的服务定义可能看起来像这样:
define service{
host_name winsrv
service_description WinVNC
check_command check_nt!**PROCSTATE**!-l winvnc.exe
...
}
文件年龄
值得注意的是,使用 FILEAGE 监控自上次修改关键文件以来经过的时间,尤其是对于日志文件和其他经常更改的文件:
check_nt -H *address* -v FILEAGE -l *path* -w *integer* -c *integer*
FILEAGE 可以用来检查文件的年龄,例如一个应该定期写入数据的日志文件。文件名使用完整路径指定,并且反斜杠必须写两次:C:\\xyz.log。如果超过指定的阈值(以分钟为单位),插件会发出 WARNING 或 CRITICAL。然而,默认情况下,它以纪元秒为单位给出文件的年龄:^([245])
nagios@linux:nagios/libexec$ .**/check_nt -H winsrv -v FILEAGE \**
**-l "C:\\test.log" -w 1 -c 20**
1113158517
nagios@linux:nagios/libexec$ **echo $?**
1
可以再次使用 echo $? 检查状态。同样,服务定义不包含任何秘密:
define service{
host_name winsrv
service_description Log file
check_command check_nt_fileage!C: xyz.log!60!1440
...
}
查询 Windows 计数器和实例
NSClient 和 check_nt 的组合提供了另外两个功能:使用 COUNTER 查询 Windows 计数器和使用 INSTANCES 查询 Windows 性能计数器对象。然而,查询性能计数器在不同服务之间有一些小的细节差异(例如,在计数器名称中使用双反斜杠而不是单反斜杠)。因此,我们将在第 481 页关于 NC_Net 扩展功能的讨论中描述这两个功能。如果您想使用 OpMon Agent、NSClient 或 NSClient++ 中的计数器,我们建议您查看每个服务的原始文档。
当使用 NSClient++ 时,建议您使用内部函数 CheckCounter,该函数在 使用 CheckMem 检查内存负载 中有描述。
20.3.2 NC_Net 的高级功能
NC_Net 的功能范围正在不断扩展;本章描述了超越 NSClient 2.28 版本的可能性。这些功能只能与修改后的 check_nt 插件一起使用。扩展版本基于原始 check_nt 版本 1.4.1。但是,两个插件可能会继续以不同的方式开发,从而产生分歧。
因此,我们将 NC_Net 版本重命名为 check_ncnet,这样我们就可以保持两个版本独立,并同时运行它们。因此,本书中的 check_nt 示例演示了所有 NSClient 兼容服务可用的功能;如果使用 check_ncnet,则可以结合扩展插件使用 NC_Net 功能。
20.3.3 安装 check_ncnet 插件
check_ncnet 仅存在于源代码中;它由一个单独的文件组成,不幸的是,这个文件与原始插件 check_nt.c 具有相同的名称。该文件在安装 NC_Net 时会出现在硬盘上,但也可以从 www.shatterit.com/nc_net 独立下载。
目前,只有与整个 Nagios 插件包结合时,源代码才能无问题地编译(参见 1.4 安装和测试插件,第 43 页)。为此,你需要在子目录 plugins 中用扩展版本覆盖现有的文件 check_nt.c。为了安全起见,应该将旧的 check_nt 二进制文件重命名;然后运行 make check_nt 重新编译源文件。之后,将名为 check_ncnet 的二进制文件复制到 Nagios 的 libexec 目录中,与其他插件一起:
linux:~ # **cp check_nt.c /usr/local/src/nagios-plugins-1.4/plugins**
linux:~ # **cd /usr/local/src/nagios-plugins-1.4/plugins**
linux:nagios-plugins-1.4/plugins # **mv check_nt check_nt_orig**
linux:nagios-plugins-1.4/plugins # **make check_nt**
...
linux:nagios-plugins-1.4/plugins # **mv check_nt check_ncnet**
linux:nagios-plugins-1.4/plugins # **cp check_ncnet** \
**/usr/local/nagios/libexec/**.
Windows 性能计数器
通过所谓的性能计数器,Windows 为系统中所有可以用数字表示的内容提供值:硬盘使用率、CPU 使用率、登录次数、终端服务器会话数、网络接口的负载等等。check_ncnet 使用 ENUMCOUNTER 命令查询这些值:
check_ncnet -H *address* -v ENUMCOUNTER -l *category1, category2*
如果你省略了 -l 参数,ENUMCOUNTER 将会显示所有性能计数器类别:
nagios@linux:nagios/libexec$ .**/check_ncnet -H winsrv -v ENUMCOUNTER**
... Processor; ... Terminal services; .NET CLR loading procedure; tot
al RAS services; Process; ...
否则,它将显示使用 -l 指定的类别中的所有计数器。几个类别由逗号分隔。终端服务 类别包含三个计数器对象:
nagios@linux:nagios/libexec$ .**/check_ncnet -H winsrv -v ENUMCOUNTER** \
**-l Terminal services**
Terminal Services: Total Sessions; Active Sessions; Inactive Sessions
nagios@linux:nagios/libexec$ .**/check_ncnet -H winsrv -v ENUMCOUNTER** \
**-l "Terminal Services","Process"**
Terminal Services: Total Sessions; Active Sessions; Inactive Sessions-Process: %
Processor Time; % User Time; % Privileged Time; Virtual Bytes Peak; Virtual Bytes;
Page Faults/sec; Working Set Peak; Working Set; ...
精确的对象名称对于后续使用很重要,其中百分号(例如,在 % Processor Time 中)是名称的一部分。如果计数器或类别名称包含空格,你必须记住在提出请求时将其放在引号内。
存储在 Windows 性能计数器对象中的描述可以通过 ENUMCOUNTERDESC 命令显示。
几个计数器类别包含实例,查询计数器对象时你必须指定这些实例。因此,你应该首先使用 INSTANCES 函数检查你想要的类别是否与实例一起工作:
check_ncnet -H *address* -v INSTANCES -l *category1, category2*
对于终端服务,情况并非如此:
nagios@linux:nagios/libexec$ .**/check_ncnet -H winsrv -v INSTANCES** \
**-l "Terminal Services"**
Terminal Services:
典型的具有实例的类别是 Processor or Process:
nagios@linux:nagios/libexec$ .**/check_ncnet -H winsrv -v INSTANCES** \
**-l "Process"**
Process: svchost#6,svchost,Idle,explorer,services,...
这里可以明显看出实例的含义:Windows 将每个正在运行的进程视为 Process 性能计数器类别中的一个实例。如 20.3.3 安装 check_ncnet 插件 中所示,包含处理器时间百分比使用的计数器对象(% Processor Time)属于这个类别。它只能查询单个实例,例如对于 explorer 进程,或者查询所有进程。在后一种情况下,你指定 _Total 而不是实例。
因此,为了访问 Windows 性能计数器,你总是需要提供以下详细信息:
*\category\counter object*
*\category(instance)\counter object*
只有当类别有可用的实例时,才会指定实例。类别名称和第一个括号之间不能有空格。相应的查询命令称为 COUNTER;占位符 *`name`* 被上述组合替换:
check_nt -H *adresse* -v COUNTER -l *name, formatbeschreibung* -w *ganzzahl* -c
*ganzzahl*
此功能询问在 -l 选项之后指定的 Windows 性能计数器对象的确切名称。作为整数值给出的警告和临界限制指的是测量的尺寸:如果涉及一个有百分比数字的对象(例如,处理器负载),只需想象在其上添加一个百分号;进程、会话等的数量只是未指定单位的值。
活动会话的数量是通过 Active Sessions 对象检查的,该对象没有实例:
nagios@linux:nagios/libexec$ .**/check_ncnet -H winsrv -v COUNTER** \
**-l "\Terminal Services\Active Sessions"**
1
nagios@linux:nagios/libexec$ .**/check_ncnet -H winsrv -v COUNTER** \
**-l "\Process(Idle)\% Processor Time"**
98
因为 Idle 实例总是查看已用和备用处理器负载之间的差异,所以两者的总和总是 100%,所以在第二个示例中查询 _Total 伪实例并没有太多意义。
通常 COUNTER 不格式化其输出。这可以通过在对象名称后跟一个以逗号分隔的描述来改变,该描述采用 printf 格式,^([246]):
nagios@linux:nagios/libexec$ **./check_ncnet -H winsrv -v COUNTER** \
**-l "\Process(Idle)\% Processor Time","Idle Process: %.2f %%"**
Idle Process Usage is: 54.00 % | 'Idle Process Usage is: %.2f %%'=54.000000%;
0.000000;0.000000;
不仅使输出更清晰,还返回额外的性能数据。一个对应的服务定义可能看起来像这样:
define service{
host_name winsrv
service_description Terminal Sessions
check_command check_nt!**COUNTER**!-v "\Terminal Services\Active Sessions"
-w 20 -c 30
...
}
列出进程和服务
要找出进程的名称,你可以通过任务管理器逐个查找,或者使用 ENUMPROCESS: 显示所有正在运行的进程列表
nagios@linux:nagios/libexec$ **./check_ncnet -H winsrv -v ENUMPROCESS**
System Idle Process; System; smss.exe; csrss.exe; winlogon.exe;
services.exe; lsass.exe; svchost.exe; svchost.exe; svchost.exe;
...
列出所有已安装服务的等效命令是 ENUMSERVICE:
check_ncnet -H *host* -v ENUMSERVICE -l *typ*, short
可选的 −1 限制输出到特定类别(见 表 20-1):
nagios@linux:nagios/libexec$ **./check_ncnet -H winsrv -v ENUMSERVICE**
\ **-l manual,short**
ALG; AppMgmt; BITS; COMSysApp; dmadmin; EventSystem; HTTPFilter; LPDSVC; MSIServer;
Netman; Nla; NtFrs; NtLmSsp; NtmsSvc; RasAuto;
...
使用short选项,ENUMSERVICE显示服务名称,这些名称是按照在注册表中输入的顺序显示的;如果您省略了关键字,则显示显示名称。
表 20-1. ENUMSERVICE的限定选项
| 类型 | 描述 |
|---|---|
all |
所有服务 |
running |
所有当前活动服务 |
stopped |
所有已停止的服务 |
automatic |
自动启动的服务 |
manual |
必须手动启动的服务 |
disabled |
已禁用的服务 |
查询 Windows 事件日志
使用EVENTLOG命令,可以查询 Windows 事件日志:
check_ncnet -H *adress* -v EVENTLOG -w *integer* -c *integer* -l *eventlog, event_type,
interval,source_filter, description_filter, id_filter*
使用它确实需要一些习惯,然而:^([247]) 接下来的三个参数 -l 选择要考虑的事件类型和时间。
占位符*`eventlog`*被替换为三个日志区域之一application, security和system,您想要查看的区域。如果EVENTLOG要包含所有三个,只需指定any;但是您不能只选择三个区域中的两个。
对于*`event type`*,您可以选择error, Warning, Information,或者选择any以选择所有三个。
用*`interval`*代替,您指定一个以分钟为单位的时间间隔:5将选择在过去五分钟内发生的事件;例如,1440代表一整天。
最后三个参数实际上充当过滤器,可以从所有源自特定来源(*`source_filter`*占位符)的结果中确定特定结果,这些结果在其描述中包含特定模式(*`description_filter`*),或者具有特定的事件 ID(*`id_filter`*)。
每个过滤器由两部分组成:在第一部分中,一个整数表示要跟随多少个搜索模式(根据.NET-Regexp类制定的正则表达式),然后指定实际的过滤器条目,用逗号分隔。如果未使用其中一个过滤器,则其占位符被替换为0,这将精确地搜索零个搜索模式。仅查找NC_Net事件的源过滤器将被称为1,NC_Net;如果您要搜索NC_Net和Perflib事件,它将被称为2,NC_Net,Perflib。
-l any, any,5,0,0,0评估过去五分钟内所有事件范围的所有条目。-l application,error,1440,0,0,0确定在过去 24 小时内事件范围application中发生的所有error类型的事件。使用−1 application, error, 60,1,NC_Net,0,0,时间窗口设置为 60 分钟,并使用字符串NC_Net过滤事件源。最后-l application,any,60,0,2, start, stop,0在事件描述中搜索两个关键字:start和stop。
使用警告和临界限制,您可以指定在插件返回警告或临界值之前需要多少匹配条目。如果您省略这两个参数,Nagios 会在没有发生任何事件的情况下显示 OK;否则,它将显示 CRITICAL。
以下示例询问在过去 24 小时内 applications 区域有多少条消息:
nagios@linux:nagios/libexec$ .**/check_ncnet -H winsrv -v EVENTLOG** \
**-l "Application,any,1440,0,0,0"**
9 Errors with ID: 13001;2003;1010;6013;1111;262194;26;262194;26 LAST - I
D 262194;Not all data for the file "\Device\LanmanRedirector" were sa
ved. Possible causes are computer hardware or the network connection. P
lease specify a different file path.
我们定义的服务在 System 区域的所有类中搜索过去五分钟内发生的错误。(在指定时间范围时,通常应确保它与 normal_check_interval 中的时间范围相关联。)该服务检查找到的条目的描述,以查找文本 data loss。这里不使用源和 ID 过滤器:
define service{
host_name winsrv
service_description Eventlog data loss
check_command check_ncnet!**EVENTLOG**!-l System,any,5,0,1,data loss,0
is_volatile 1
normal_check_interval 5
max_check_attempts 1
...
}
日志文件具有在特定情况下仅指出问题一次的特性,即使问题持续存在。因此,您必须确保 Nagios 在事件首次发生时立即发出通知,并省略重复测试和软状态。这可以通过 max_check_attempts 1 实现:这立即设置硬状态,并立即发出通知。
但如果硬状态保持不变,这在实践中意味着在此期间可能会出现新的错误(五分钟后的下一次测试不再记录旧状态),而状态没有改变;管理员只有在 notification_interval 过期后才会再次被通知。对于此类情况,Nagios 提供了 is_volatile 参数(见 14.5.2 Nagios 配置:易变服务,第 309 页),系统会为每个单独的错误提供通知。
显示和操作 NC_Net 配置
ENUMCONFIG 函数以可读的形式显示 NC_Net 的当前设置:
nagios@linux:nagios/libexec$ **./check_ncnet -H winsrv -v ENUMCONFIG**
Date: 16.04.2005 18:15:10;
Version: NC_Net 2.21 03/13/05;
NC_Net Config Path: c:\Programs\shatter it\nc_net\config\;
Startup Config: c:\Programs\shatter it\nc_net\config\startup.cfg;
Debug Log: c:\Programs\shatter it\nc_net\config\deb.log;
...
Port: 1248;
Pass: None;
...
Date 显示当前查询日期,Version 表示使用的 NC_Net 版本。NC_Net Config Path 描述配置目录的路径,Startup Config 表示使用的配置文件。Debug Log 指定包含调试输出的日志文件,但仅当配置文件中设置了 MYDEBUG true 参数时。Port 揭示 NC_Net 监听的端口,而 Pass 显示是否已为连接使用了密码(None: 无密码)。
此外,还有 CONFIG 命令,用于通过网络操作 NC_Net 安装的配置。出于安全考虑,您应仅将其用于测试目的,否则应保持该功能关闭。因此,您应在配置文件 startup.cfg 中保留以下默认设置:
lock_passive_config true
lock_active_config true
这意味着配置不能从外部更改。
其他功能
NC_Net 的功能范围正在不断增长,要详细描述所有功能需要单独的书籍。我们只提几个非常有用的命令:
FREEDISKSPACE
USEDDISKSPACE (主内存使用)期望警告和临界限制的空闲硬盘容量(而不是已用空间)的百分比
WMIQUERY
此功能使能够查询具有 SQL 功能的 WMI^([248])数据库,其中包含.NET 配置数据。
WMICOUNTER
与 Windows 性能计数器类似的对象也存在于 WMI 区域(仅限.NET);可以使用此功能进行查询。
被动检查
从 2.0 版本开始,NC_Net 也支持基于 NSCA 机制的被动检查(参见第十四章"), 第 299 页)。简短的文档可以在包含的passive.cfg文件中找到。
更多信息可以在安装包中包含的文件readme.html中找到,但也可以直接在www.shatterit.com/nc_net/files/readme.html查看。
^([242]) 你可以在 20.3 The check_nt Plugin 中详细了解它们。
^([243]) nagios.sourceforge.net/docs/3_0/monitoring-windows.html
^([244]) 此问题与 NRPE 类似,通过定义依赖关系得到解决(参见 12.6 Accounting for Dependencies between Hosts and Services,第 285 页)。
^([245]) 即,自 1970 年 1 月 1 日以来经过的秒数。
^([246]) man 3 printf
^([247]) 根据他的评论,作者 Tony Montibello 希望在 2.25 版本中更改定义服务的语法。但截至包括 2.28 版本,此解决方案尚未实施。
^([248]) 简称Windows Management Instrumentation。
20.4 NRPE for Windows
除了 NRPE_NT(一个移植到 Windows 的 NRPE 守护进程)之外,NSClient++和现在的 OpMon Agent 也提供 NRPE 服务。其任务是如果特定的测试只能在本地进行且没有合适的网络协议来查询相关资源,则在目标系统上执行插件。与 Unix 版本(参见第 213 页的第十章"))一样,除了守护进程(在这种情况下:NRPE_NT)外,所需的插件必须安装在本地目标系统上,并且必须在本地配置文件中输入测试。
NRPE 也可以用于其他目的:一旦安装在 Windows 服务器上,除了 Nagios 插件外,您还可以使用该机制远程运行其他脚本。如果您想通过 Eventhandler 远程重启 Nagios 服务,这也可以用 NRPE_NT 轻松完成^([249])。
20.4.1 NRPE_NT,经典工具
NRPE_NT 可以像第十章中介绍的 Nagios 远程插件执行器一样使用——实际上,这只是该工具的 Windows 版本。然而,目前看来,这个工具似乎不会继续积极开发。
从 Nagios Exchange 的当前 zip 存档,^([250]) SourceForge^([251])或www.miwi-dv.com/nrpert解压到合适的目录,例如D:\Programs\Nagios\nrpe_nt:
D:\Programs\Nagios\nrpe_nt> **unzip nrpe_nt.0.8-bin.zip**
...
它包含一个名为bin的子目录,其中包含守护进程NRPE_NT.exe,用于 SSL 的两个 DLL(libeay32.dll和ssleay32.dll),一个简单的插件脚本示例(test.cmd)以及配置文件nrpe.cfg。
使用命令nrpe_nt -i从该目录安装服务,之后只需启动即可,无论是在 Windows 服务管理器中还是在命令行中:
D:\Programs\Nagios\nrpe_nt\bin> **nrpe_nt -i**
D:\Programs\Nagios\nrpe_nt\bin> **net start nrpe_nt**
配置文件nrpe.cfg与 NRPE 2.0 的 Unix 版本略有不同(见 10.3 监控计算机上的 NRPE 配置,第 218 页):在 NRPE_NT 中,只有include_dir指令不起作用。
Windows 中的文件也具有经典的 Unix 文本格式^([252]),因此您需要合适的编辑器(notepad.exe不足以使用)或者您必须在 Linux 中编辑它,之后将其复制到测试系统中。
由于 Windows 中没有 inet 守护进程,您必须在nrpe.cfg中指定端口(标准:server_port=5666)以及 NRPE 应从哪些主机接收请求(您应只在此处输入 Nagios 服务器;例如:allowed_hosts=172.17.129.2)^([253])。参数nrpe_user和nrpe_group在 Windows 中没有意义,其他参数与 10.3 监控计算机上的 NRPE 配置中讨论的参数相对应。
在可执行命令的定义中(这里针对包含的测试插件),您必须记住 Windows 典型的语法,包括硬盘驱动器字母和反斜杠:
command [check_cmd]=D: \Programs\Nagios\nrpe_nt\plugins\test.cmd
在此示例中,插件位于名为plugins的单独子目录中。在更改配置文件后,您应该始终重新启动 NRPE_NT:
D:\Programs\Nagios\nrpe_nt\bin> **net stop nrpe_nt**
D:\Programs\Nagios\nrpe_nt\bin> **net start nrpe_nt**
功能测试
在将 NRPE_NT 投入服务之前,您应该检查它是否正常工作。为此,以用户 nagios 在 Nagios 服务器上运行插件 check_nt,仅指定一个主机,不使用其他参数:
nagios@linux:nagios/libexec$ **./check_nrpe -H winsrv**
NRPE_NT v0.8/2.0
如果服务已正确安装和配置,它将以版本号回复。另一个简单的测试是通过包含的 test.cmd 插件进行的。它提供一段简短文本,并以返回值 1 结尾:
@echo off
echo hallo from cmd
exit 1
要执行的命令(在上一节中定义)通过 -c 选项传递给插件 check_nt:
nagios@linux:nagios/libexec$ **./check_nrpe -H winsrv -c check_cmd**
hallo from cmd
nagios@linux:nagios/libexec$ **echo $?**
1
使用 echo $? 确定的返回值在这种情况下必须是 1,因为脚本以 exit 1 退出。
20.4.2 Windows 中的 NRPE 插件
在互联网上可以找到一系列在 Windows 中运行且适合与 NRPE 一起使用的插件。首选的起点是 NagiosExchange 的子类别 检查插件 | 操作系统 | Windows NRPE.^([254]) 其中一些是基于与 Unix 等效程序相同的源代码的程序,这些程序只是重新编译为 Windows。然而,移植还包括需要安装 Perl 的 Perl 脚本——在大多数情况下,必须在 Windows 中首先安装脚本语言。
Cygwin 插件
在 检查插件 | Windows^([255]) 类别中,Nagios Exchange 包含了用于下载的 CygwinPlugins 软件包。它包括为 Windows 编译的 Nagios 标准插件,这些插件是在 Cygwin 工具的帮助下编译的.^([256]) 该软件包基于较旧的插件版本 1.3.1,但对于大多数用途来说已经足够了。除了可执行插件(*.exe)之外,该软件包还包含所有必要的 DLL 文件。因此,只需将 zip 存档解压到一个目录中即可:
D:\Tmp> **unzip CygwinPlugins1-3-1.zip**
D:\Tmp> **dir NagPlug**
check_dummy.exe check_ssh.exe check_udp.exe cygwin1.dll
check_http.exe check_tcp.exe cygcrypto-0.9.7.dll negate.exe
check_smtp.exe check_time.exe cygssl-0.9.7.dll urlize.exe
为了简化,只需将创建的目录 NagPlug 的内容复制到一个单独的插件目录中:
D:\Tmp\NagPlug> **copy * D:\Programme\Nagios\plugins**
插件功能与 Linux 中相同。表 20-2 指的是本书中相应的部分。
表 20-2. Cygwin Plugins for NRPE_NT
| 插件 | 页面 | 描述 |
|---|---|---|
check_dummy.exe |
188 | 测试插件 |
check_http.exe |
119 | 网站的可达性 |
check_smtp.exe |
113 | 测试邮件服务器 |
check_ssh.exe |
131 | SSH 可用性 |
check_tcp.exe |
132 | 通用插件 |
check_time.exe |
178 | 两个主机的时钟时间比较 |
check_udp.exe |
135 | 通用插件 |
negate.exe |
188 | 取消插件返回值 |
urlize.exe |
189 | 将 Nagios Web 界面中的插件输出转换为链接 |
与 Unix 类似,配置文件 nrpe.cfg 中的每个相应的命令定义都必须写在单独一行上:
command [check_web]=D:\Programme\nagios\plugins\check_http -H www.swobspa ce.de
command [check_identd]=D:\Programme\nagios\plugins\check_tcp -H linux01 -p 113
第一行检查主机www.swobspace.de是否在 HTTP 标准端口 80 上运行 Web 服务器。第二行测试主机linux01上是否有一个identd守护进程(TCP 端口 113)处于活动状态。
如果插件版本 1.3.1 太旧,或者缺少插件,如果你对 C 程序的开发和如何处理 Makefiles 有一些基本知识,你也可以在 Cygwin 环境中自行编译插件。然而,并非所有重新编译的插件都能在 Windows/Cygwin 下工作。例如,check_icmp直接使用网络套接字,Windows 中的套接字构建与 Unix 套接字大不相同;因此,除非首先修改代码,否则该插件在 Windows 中不会工作。有关在 Cygwin 下编译的说明,以及插件版本 1.4.5 的已编译二进制存档,可以在www.psychoticwolf.net/blog/2007/07/nagios_plugins_for_windows.php找到。
Windows 下的 Perl 插件
不幸的是,Cygwin 插件不包含check_ping或check_icmp。你可以使用可从 Nagios Exchange 的Networking类别下载的 Perl 脚本check_ping.pl代替。它使用 Perl 模块Net::Ping进行网络连接。与check_tcp不同,check_ping.pl发送多个数据包,因此可以对响应时间和数据包丢失进行更精确的评估。
可以从 ActiveState 获取最新版且易于安装的 Perl for Windows。^([258]) 下载Active Perl Free Distribution不需要注册,即使下载过程可能会暗示需要注册。在提供的版本中,你应该使用最新的 Perl 版本(目前为 5.8.7),如果使用较旧的版本 5.6.1 会导致问题,则才回退使用。
插件脚本本身包含一个BEGIN语句,你必须将其注释掉才能在 Windows 中使用:
# BEGIN{
# push @INC, "/usr/lib/perl5/site_perl/...
# }
它向端口 7 发送 TCP 回显请求,或者你也可以在Net::Ping->new语句之后添加以下行来显式设置不同的端口:
$p->port = 80;
这将导致对端口 80(HTTP)的 TCP ping。为了使 NRPE_NT 能够执行脚本,你必须显式启动 Perl 可执行文件:
command [check_ping_eli02]=C:\Perl\bin\perl.exe D:\Programme\Nagios\plugi ns\
check_ping.pl --host 172.17.129.2 --loss 10,20--rta 50,250
命令在打印版本中已经换行,但在配置文件中整个命令必须写在单行上。使用--host参数指定一个可解析的主机名或 IP 地址,--loss后面跟着一个表示百分比中数据包丢失警告和临界限制的值对,用逗号分隔(因此这里可能的值在 0 到 100 之间)。--rta选项也要求一个阈值值对作为参数,用于平均响应时间(以毫秒为单位)。由于这是一个 Perl 脚本,所以这些值指定为整数或浮点逗号小数没有关系。
20.4.3 NRPE 与 NSClient++
NSClient++包含其自己的 NRPE 服务,因此在使用它时不需要安装额外的 NRPE 服务。它通过在配置文件NSC.ini的[modules]部分加载库NR.PEListener.dll来激活(配置)。服务的配置由[NRPE]和[NRPE Handlers]部分处理。第一个部分包含 NRPE 基本配置,第二个部分定义要执行的检查。
NRPE 的默认端口是 5666,参数allow_arguments当设置为1时,允许传递参数,并对应于 NRPE 参数dont_blame_nrpe(10.3 监控计算机上的 NRPE 配置):
[NRPE]
port=5666
allow_arguments=1
allow_nasty_meta_chars=1
use_ssl=1
; bind_to_address=
; allowed_hosts=
command_timeout=10
performance_data=1
allow_nasty_meta_chars=1允许在check_nrpe参数中使用特殊字符|'&><' "\[]{}。如果这里输入的值是0而不是1,则不允许使用这些字符。use_ssl应该仅在check_nrpe无法编译带有 SSL 支持时关闭(即设置为0)。
bind_to_address和allowed_hosts参数允许 NRPE 设置与默认设置不同。command_timeout在指定的时间(以秒为单位)后中断要执行的外部命令,但超时只对外部命令有效。基于内部函数的 NRPE 命令不受此影响。最后,performance_data参数控制是否返回性能数据。默认值(值为1)是返回它,而值为0时不返回。
在[NRPE Handlers]部分,定义了实际命令。你可以使用 NRPE 中使用的相同语法,或者使用简短表示法,其中完全省略了关键字command:
command [*command_name*]=*command line*
*command_name=command line*
除了使用外部插件的常规插件调用外,还有一个命令inject。这个命令运行一个内部函数(该函数在 20.4.4 内部 NSClient++函数中描述,见第 495 页):
[NRPE Handlers]
; ---------------------------------------------
; external plugins
; ---------------------------------------------
; NRPE-stylish:
;command [check_tcp]=C:\Plugins\check_tcp -H $ARG1$ -p $ARG2$
; shorter:
check_tcp=C:\Plugins\check_tcp -H $ARG1$ -p $ARG2$
;
check_smtp=C:\Plugins\check_smtp -H $ARG1$ -f wob@example.net
;
check_uptime=inject CheckUpTime ShowAll MinWarn=1d MinCrit=12h
在这个例子中,check_uptime 通过 inject 调用内部函数 CheckUpTime。如果允许通过 NRPE 传递参数,你可以极大地简化 inject 命令的定义:
check_inject=inject $ARG1$
现在你将内部函数以及所有必需的参数,作为调用 check_nrpe 时的参数包括在内:
nagios@linux:nagios/libexec$ **./check_nrpe -H winsrv -ccheck_inject** \
**-a "checkUpTime ShowAll MinWarn=1d MinCrit=12h"**
OK: uptime: 6d 7:19|'uptime'=544771000;86400000;43200000;
如果你将 Nagios 中的命令对象定义得非常通用,命令的确切表述将完全转移到服务定义中:
define command{
command_name check_inject
command_line $USER1$/check_nrpe -u -H $HOSTADDRESS$ -c check_inject -a "$ARG1$"
}
define service{
host_name winsrv
service_description Uptime
check_command check_inject!checkUpTime ShowAll MinWarn=1d MinCr
it=12h
...
}
然而,这里应该指出一个安全问题。如果你像上面描述的那样定义 check_inject=inject $ARG1$,那么你为可能希望 NSClient++ 代码中存在缓冲区溢出攻击的攻击者打开了一扇门。在这种情况下,客户端将能够运行任何命令。因此,你应该只在安全环境中使用这个相当宽泛的命令,并且即使如此,你也应该通过 allowed_hosts 限制允许通过 NRPE 访问 NSClient++ 的主机。另一方面,这样的自由定义在实施阶段会大大简化生活,因为你可以在不调整配置文件 NSC.ini 的情况下,尝试各种组合和检查命令行。
20.4.4 内部 NSClient++ 函数
NSClient++ 提供了一系列可以通过 NRPE 的 inject 命令调用的内部函数,通常也可以通过插件 check_nt 调用。这些函数存储在几个可加载的模块中。表 20-3 提供了特定函数所需模块的概述。
表 20-3. NSClient++ 模块的内部函数
| 模块 | 功能 |
|---|---|
CheckDisk |
CheckFileSize, CheckDriveSize |
| CheckSystem | CheckCPU, CheckUpTime, CheckServiceState, CheckProcState, CheckMem, CheckCounter |
| CheckEventLog | CheckEventLog |
| CheckHelpers | CheckAlwaysOK, CheckAlwaysCRITICAL, CheckAlwaysWARNING, CheckMultiple |
要使用这些函数中的任何一个与 check_nt 结合,你只需要确保所需的模块已在 [modules] 部分加载。通过 NRPE 和 inject 调用提供了额外的配置选项。
因此,对于使用 check_nt 进行的硬盘负载检查,该函数内部使用 CheckDriveSize 函数,你可以只显示警告和临界阈值:
nagios@linux:nagios/libexec$ **./check_nt -H winsrv -vUSEDDISKSPACE** \
**-l C -w 80 -c 90**
...
如果相反,你直接访问 CheckDriveSize,你可以指定更高的和更低的阈值,并且可以使用 UNC 路径而不是硬盘驱动器字母(参见 使用 CheckFileSize 检查文件大小)。
下列列出的许多参数都是可选的,至少按照 Wiki 中的文档来说是这样。然而,这种约定似乎并没有得到统一遵守。例如,性能数据只有在指定了警告和临界阈值时才会获得。您也可以省略一个或两个阈值,调用仍然会执行;所缺少的是性能数据。如果函数允许,ShowAll和nsclient参数也是可选的。
对于所有其他功能,在您将其部署到生产环境之前,您应该测试您的配置是否真正实现了预期的目的,并且 NSClient++是否在没有错误消息的情况下正常工作。
使用CheckFileSize检查文件大小
CheckFileSize测试单个文件或目录的大小:
CheckFileSize MaxWarn=*size* MaxCrit=*size*
MinWarn=*size* MinCrit=*size*
File=*path:alias* ShowAll
最后,这里处理的是递归的。如果您指定File=C:\*.*,例如,您也可以测试驱动器。然而,阈值参数确实需要给出大小值。如果您想按百分比监控驱动器的使用情况,您最好使用CheckDriveSize命令。
在指定阈值大小时,您可以包含一个后缀:B表示字节,K表示KB,M表示 MB,G表示 GB(例如,MaxWarn=2198M)。没有后缀的数字指定的是字节大小。
语法允许指定多个文件和/或目录。在这种情况下,File参数遵循相关的阈值:
user@linux:nagios/libexec$ **./check_nrpe -H 172.17.129.25** \
**-c check_inject -a "CheckFileSize** \
**MaxWarn=500M MaxCrit=1024MFile=E:\Exchsvr\mdbdata_log\*.***\
**MaxWarn=10G MaxCrit=30G File=F:\store02\priv2.edb**
\
**File=G:\store03\pub3.edb ShowAll"**
WARNING: E:\Exchsvr\mdbdata_log\*.*: 77M,
F:\store02\priv2.edb: 11.4G > w
arning, G:\store03\pub3.edb: 3.09G|
'E:\Exchsvr\mdbdata_log\*.*'=80740352
;524288000;1073741824;
'F:\store02\priv2.edb'=12234989568;10737418240 ;322
12254720;
'G:\store03\pub3.edb'=3316719616;10737418240;32212254720;
监控目录时,仅仅提供目录名称是不够的。相反,正如目录E:\Exchsvr\mdbdata_log\的示例所示,您需要使用*.*来指定目录中包含的所有文件和子目录(及其内容)都必须包含在计算中。
当然,您也可以使用通配符,例如,*.log来找出目录中所有以.log结尾的文件的总大小。阈值始终指的是在相应的File参数中指定的所有文件和目录的总和。
如果有多个连续的File指定,则使用它们之前指定的最后一个阈值。ShowAll显示指定所有文件或目录的状态,如果没有给出此参数,则显示只有错误状态的文件和目录。
显示包含测试的文件和目录的完整路径,这可能会变得非常混乱。因此,CheckFileSize允许使用可选的别名。调用
MaxWarn=500M MaxCrit=1024M File:TMP=C:\tmp\*.*
将仅显示别名TMP而不是完整路径:
OK: TMP: 0B|'TMP'=0;524288000;1073741824;
使用CheckDriveSize检查驱动器的使用情况
CheckDriveSize检查驱动器的使用情况。在这里可以非常灵活地给出阈值:您可以使用*Free参数来确定剩余的可用驱动器空间,或者使用*Used参数来建立已使用的驱动器空间:
CheckDriveSize MaxWarnFree=*größe* MaxCritFree=*size*
MinWarnFree=*size* Min
CritFree=*size* MaxWarnUsed=*size*
MaxCritUsed=*size* MinWarnUsed=*size* Min
CritUsed=*size* Drive=*laufwerk* FilterType=*type*
CheckAll CheckAllOthers Sho
wAll
在给出阈值时,你可以再次使用大小,或使用 % 后缀来获取百分比。与 CheckFileSize 不同,大小参数的后缀必须小写:b 表示字节,k 表示 KB,m 表示 MB,g 表示 GB。
对于占位符 *`disk`*,你可以使用相应的磁盘字母或网络共享的 UNC 路径:例如,Drive=\\WinSRV\C$。如果指定了 CheckAllOthers,NSClient++ 将检查所有未单独指定的硬盘。CheckAll 处理所有驱动器,因此可以省略 Drive 参数。一个额外的过滤器允许仅考虑某些驱动器类型:FilterType=FIXED 仅限于永久安装的所有驱动器,而 FilterType=REMOVABLE 只考虑可移动驱动器。过滤器 FilterType=CDROM 描述光盘驱动器,而 FilterType=REMOTE 查看所有网络驱动器。可以组合多个过滤器:
CheckDriveSize CheckAll FilterType=FIXED FilterType=REMOTE
检查所有永久安装的本地驱动器和所有连接的网络驱动器。
使用 CheckCPU 检查 CPU 负载
CheckCPU 检查处理器负载百分比,阈值在此处给出时不带百分号:
CheckCPU warn=*percentage* crit=*percentage*
time=*period* ShowAll nsclient
负载是在使用 time 参数指定的期间计算的。如果没有给出后缀,则期间以秒为单位,否则可以使用后缀 w(周)、d(天)、h(小时)、m(分钟)和 s(秒)。对于更长的期间,必须确保在 [CheckSystem] 配置文件下的 CpuBufferSize 参数具有足够大的值。默认期间为一个小时。
要同时显示多个不同时间间隔的 CPU 负载,可以多次指定 time 参数:
CheckCPU warn=30 crit=80 time=1m time=5m time=15m
ShowAll 影响插件输出的显示(但性能数据除外;以下已省略):
OK CPU Load ok.
OK: 1m: 2%, 5m: 2%, 15m: 2%
OK: 1m: average load 2%, 5m: average load 2%, 15m: average load 2%
第一行显示没有 ShowAll 的输出,第二行显示带有此参数的输出。在此 CheckCPU 会分别显示每个时间间隔的值。第三行演示了参数 ShowAll=long。这不会提供更多信息,只是文本更多。
剩余的参数是 nsclient,它以原始 NSClient 的风格显示输出,并使用 & 符号分隔时间间隔的详细信息:2&2&2。使用此参数时不会显示性能数据。
使用 CheckUpTime 确定运行时间
CheckUpTime 显示自系统启动以来经过的时间。与 CheckCPU 类似,可以使用后缀(s、m、h、d、w)设置阈值:
CheckUpTime MaxWarn=*time* MaxCrit=*time*
MinWarn=*time* MinCrit=*time* ShowAll
nsclient Alias=*string*
ShowAll 即使在没有错误状态时也会显示时间。nsclient 将输出更改为秒的简单值,不包含任何其他文本。使用 Alias,可以将单词 Uptime 替换为不同的文本:
OK: uptime: 1d 20:11
OK: Running_Time: 1d 20:12
第一行显示带有 ShowAll 的正常输出;在第二行中设置了额外的 Alias=Running_Time。
使用 CheckServiceState 进行活动检查
CheckServiceState 检查服务是否处于活动状态(started)或未处于活动状态(stopped)。您可以检查一个或多个单独列出的服务,或者使用 CheckAll 开关,该开关检查所有已设置自动启动标志且应在每次系统启动后运行的服务:
CheckServiceState *service* ShowFail CheckAll
exclude= *servicename*
CheckServiceState ShowFail ShowAll CheckAll exclude=*servicename*
可以显式检查单个服务以获取所需的状态:
CheckServiceState MSExchangeSA=started MSSEARCH=stopped ShowFail
此调用检查 MSExchangeSA 服务是否正在运行,以及 MSSEARCH 服务是否未运行。如果这两个服务中的任何一个的状态与指定状态不同,则显示 CRITICAL。ShowFail 确保只有出现错误的服务出现在输出中。
CheckAll 通常包括所有带有自动启动标志的服务。可以使用 exclude 将单个服务排除在外。
使用 CheckProcState 监控进程
CheckProcState 检查进程的状态,其功能与 CheckServiceState 相同,只是这里可用的选项较少:
CheckProcState ShowAll ShowFail
CheckProcState ShowFail *prozess*
对于单个进程,您可以再次指定所需的状态(*`process`*****=started 或 *`process`*****=stopped);否则,只有 ShowAll 将被保留以控制输出。ShowFail 是默认值,可以省略。
使用 CheckMem 检查内存负载
CheckMem 检查内存的负载水平。这里的 type 参数很有意义:
CheckMem MaxWarn=*size* MaxCrit=*size*
MinWarn=*size* MinCrit=*size* ShowAll
type=*typ*
type=page 和 type=paged 显示整个内存(物理内存加上交换空间),并对应于 check_nt -v MEMUSE 的值。page 和 paged 之间的区别仅在于所使用的例程:前者使用 NSClient 所使用的 PDH 库,该库起源于 Windows NT 时代,而后者使用 Windows 2000 和 Windows 2003 的新例程。type=virtual 指的是使用的交换内存,而 type=physical 指的是使用的物理内存。
CheckMem 的输出仅在出现错误状态时提供整个可用内存的详细信息;对于正常状态,仅显示指定类别的实际使用情况。
与 CheckFileSize 类似,此函数的阈值后缀以大写形式书写:B、K、M 和 G。允许使用带有后缀 % 的百分比。
使用 CheckCounter 检查性能计数器
使用 CheckCounter 可以查询记录了几乎所有 Windows 提供的参数的 Windows 性能计数器:
CheckCounter MaxWarn=*number* MaxCrit=*number*
MinWarn=*number* MinCrit=*number* showAll
Averages=*value* Counter=*countername*
使用 Averages=true,CheckCounter 为性能计数器计算平均值,这些计数器本身不提供平均值。值 false 关闭此功能,因此查询时间更短。Averages 参数对 Windows 已经提供平均值的性能计数器没有影响。
关键在于找到正确的性能计数器。一个起点是性能监视器本身,在 Windows 中通过 perfmon 程序启动。如果你在此处插入新的性能计数器以进行查看,你将看到所有可用的对象(性能计数器类别)和性能指标。所有可用的计数器在 NSClient++ 从命令行直接运行时也会显示。由于计数器数量众多,最好将输出重定向到文本文件:
C:\Programme\Nagios\nsclient++> **nsclient++CheckSystem listpdh > All.txt**
CheckCounter 只接受整数作为阈值,因为计数器通常没有单位。此函数允许指定计数器的别名(参见使用 CheckFileSize 检查文件大小):
CheckCounter "Counter:Logins=\Terminal services\Active
sessions" MaxWarn=2
0 MaxCrit=30 showAll
引号在这里很重要。你必须确保参数本身在引号内。如果指定了别名,NSClient++ 将在输出中将性能计数器替换为别名:
OK: Login: 1|'Login'=1;20;30;
使用 CheckEventLog 评估日志条目
CheckEventLog 在事件日志中搜索特定事件,如果找到的条目数量超过相应的阈值,则发出警告或严重错误。该函数功能强大且复杂——遗憾的是,它并不容易理解:
CheckEventLog file=**typ** filter=*value* truncate=*number*
MaxWarn=*number* MaxCrit=
*number* descriptions filter*modetype*=*string*
Windows 事件日志有各种日志文件:对于应用程序本身(file=Application),对于安全方面(file=Security),以及对于系统参数(file=System)。还有一些是为域控制器准备的。如果你想在多个日志文件中搜索事件,只需重复 file 参数:
file=Application file=Security file=System
第一个 filter 参数用作开关,与后面列出的过滤器表达式结合使用。filter=in 包含所有与实际过滤器表达式匹配的事件,filter=out 排除此类事件。filter=all 要求所有过滤器表达式与事件匹配(逻辑与),但对于 filter=any,一个匹配项(逻辑或)就足够了。
编写过滤器表达式本身需要一些习惯:它以关键字 filter 开始——这是一个不幸的选择,因为相同的关键字已经被使用。接下来是一个模式:+ 或 -,确保如果过滤器匹配,则事件被计数,而 - 排除事件。对于 +,如果过滤器不匹配,即使使用 filter=any 并有另一个过滤器表达式要求计数,事件也会被排除。
模式后面跟着过滤器类型。eventType 描述是否涉及错误或信息(此的可能值包括 error、warning、info、auditSuccess 和 auditFailure):
filter+eventType==warning
此表达式包括所有事件类型匹配 warning 的事件。加号确保无论是否设置了 filter=any,都会考虑此过滤器。
eventSource 过滤器类型指定了事件的来源(例如 Print、Netlogon 或 Service Control Manager)。以下示例搜索所有来源包含部分字符串 KCC 的所有事件:
filter.eventSource=substr:KCC
generated 和 written 过滤器类型指的是时间细节:generated 表示事件条目生成的时间,written 表示事件写入日志文件的时间:
filter-generated⇒2d
此表达式排除所有超过两天的事件。
message 过滤器类型指的是事件条目的文本,并允许根据文本内容进行过滤:
filter.message=regexp:(hans|lisa)
这里使用正则表达式搜索包含文本 hans 或 lisa 的事件。
使用 event ID 过滤器类型可以根据事件编号进行过滤:
filter.eventID==7031
此外,还有 severity 类型,旨在根据事件优先级进行过滤。由于作者不知道这个的合适用途,我们不会更详细地探讨它。
当需要为过滤器表达式写入 = 时以及何时需要 == 并不立即清楚。对于只有文本参数的表达式(eventSource, message),单个等号就足够了。对于所有其他允许比较的表达式,关系符号是表达式本身的一部分:例如,=warning、=7031、>2d。与过滤器类型所属的等号一起,这看起来像双等号或“大于等于”符号——但这不是情况,没有“大于等于”。
以下示例在 System 日志文件中搜索 NSClient++ 服务的崩溃:
user@linux:nagios/libexec$ **./check_nrpe -H 172.17.133.10** \
**-c check_inject -a 'CheckEventLog** \
**file=System filter=in filter=all filter.eventID==7031** \
**filter.generated=<1d filter.message=substr:NSClientpp** \
**MaxWarn=1 MaxCrit=2 descriptions'**
Service Control Manager(error, 7031, error)[NSClientpp (Nagios) 0.2.7 20 07-03-06, 1,
60000, 1, Starten Sie den Dienst neu., ], : 1 > warning|''= 1;1;2;
由于 filter=in filter=all,所有过滤表达式必须同时匹配。正在查找的事件编号是 7031,事件不应早于一天,并且文本中应包含子字符串 NSClientpp。如果找到,测试将返回警告,如果找到两个或更多匹配事件,则返回值是 CRITICAL。这里的 descriptions 开关确保不仅显示来源的名称,还显示整个文本。此外,还有 truncate 参数,它限制返回给 check_nrpe 的整个输出。
当使用CheckEventLog时,“熟能生巧”这句话适用。如果你过滤得太不具体,以至于CheckEventLog不得不处理太多的日志条目,可能会出现奇怪的副作用。有时会显示UNKNOWN: No handler for that command的消息,尽管实际上这是因为缓冲区溢出。如有疑问,您应该开启 NSClient++的调试功能(别忘了停止/启动),并检查与可执行程序和 INI 文件相同的目录中的日志文件,以查找相关的错误条目。有关CheckEventLog的更多信息包含在 Wiki 中.^([259]).
调试函数CheckAlwaysOK、CheckAlwaysWARNING和CheckAlwaysCRITICAL
用于调试目的的函数CheckAlwaysOK、CheckAlwaysWARNING和CheckAlwaysCRITICAL总是返回相同的状态。它们的使用相对简单:所选的调试函数简单地插入到通常定义的函数之前,例如CheckFileSize:
CheckAlwaysOK CheckFileSize ...
使用CheckMultiple汇总几个检查
如果需要将几个检查汇总成一个单独的检查,可以使用Check-Multiple:
CheckMultiple command=CheckFileSize ... command=CheckUpTime ... command=...
所有单独的检查都是依次书写的,每个检查都以command=开始。不需要使用command=""风格的引号。单独检查中出现的最高错误值将作为结果返回。
^([249]) 在 Windows 服务器上远程执行脚本,您还可以使用 Windows 版本的 Secure Shell,这是一个在本书中无法详细讨论的话题。
^([250]) www.nagiosexchange.org/77;139
^([251]) sourceforge.net/project/showfiles.php?group_id=83239
^([252]) Unix 中的换行符仅由一个换行符字符组成,而 Windows 文本文件的换行符由两个字符回车符和换行符组成。
^([253]) 然而,这种安全措施仅限于对 IP 地址的简单比较。
^([254]) www.nagiosexchange.org/NRPE_Plugins.66.0.html
^([255]) www.nagiosexchange.org/49;63.
^([256]) Cygwin 工具包含大量的 GNU 工具,包括编译器、库和 shell,所有这些都是在 Windows 上运行的。这意味着许多 Unix 程序可以直接移植到 Windows 上。通常只需要 Cygwin DLL(cygwin1.dll)。
^([257]) www.nagiosexchange.org/Networking.53.0.html
^([258]) www.activestate.com/store/languages/register.plex?id=ActivePerl
^([259]) trac.nakednuns.org/nscp/wiki/CheckEventLog/CheckEventLog
第二十一章:监控房间温度和湿度
有许多用于监控房间温度和湿度的传感器。大多数都作为独立的网络设备集成到网络中,通常通过 SNMP 进行寻址。
但你至少需要在第一个传感器上花费至少三百美元。在寻找更便宜且模块化的系统时,作者最终发现了www.pcmeasure.com/;到目前为止,它已经满足了他的所有要求。
本章仅限于介绍这种传感器,并不是要贬低其他系统,而是因为仅此一个主题就足以写成一本书。
21.1 传感器和软件
一个完整的物理数据监控系统通常由三个组件组成:一个传感器(例如温度或湿度传感器)、一个适配器,用于连接到 PC 的串行或并行端口,以及一个查询传感器的软件.^([260])
PCMeasure 系统有从一到四个传感器的适配器,可以同时操作。对于电源,适配器需要一个可用的 USB 接口;或者可以选择一个单独的“USB 电源”。除了适配器解决方案之外,还有一个可选的以太网盒,带有四个传感器连接端口,价格略高,可以扩展以接受 12 个传感器。
PCMeasure 测量查询软件适用于 Linux 和 Windows.^([261]) 一些功能仅限于 Windows 版本,这也是为什么它稍微贵一些。对于与 Nagios 一起使用,Linux 版本就足够了,因为只有测量值通过简单的网络协议传输。
传感器本身很有趣:除了温度和湿度传感器(以及两者的组合)之外,还有接触传感器、烟雾和水报警器、运动检测器和电压检测器。这些传感器通常通过双绞线电缆(RJ45 连接器)连接;根据常见问题解答,^([262]) 只要你有好的电缆,它们可以从适配器或以太网盒处使用,最多可达 100 米,即在整个建筑内。
21.1.1 Linux 版的PCMeasure软件
Linux 软件的 tar 归档文件pcmeasure.tar.gz解压到其自己的目录中,例如/usr/local/pcmeasure。配置文件pcmeasure41in.ux.cfg也安装在这里。此文件中的端口条目需要调整,以便只列出连接传感器的端口:
[ports]
com1.1=01
com1代表第一个串行端口;如果你正在使用第一个并行端口,则点号前的条目是lpt1。端口后面的数字指的是传感器使用的适配器插槽,因此,根据你有多少个适配器,这是一个从1到4的数字。等号后面跟着传感器类型:01代表温度传感器,03代表湿度传感器。如果同一适配器的第二个插槽上还有一个额外的湿度传感器,则其地址为coml.2=03。
查询程序pcmeasure需要将配置文件指定为参数:
linux:local/pcmeasure # **./pcmeasure ./pcmeasure4linux.cfg**
它作为后台守护进程运行,只有当它被kill终止时才会结束。原则上,任何具有相应接口读取权限的用户都可以启动它。
21.1.2 查询协议
该软件默认打开 TCP 端口 4000,并接受来自网络的请求。使用的协议相当简单:你发送一个文本,格式如下
pcmeasure.*interface.slot*<CR><LF>
(即,使用 DOS 行结束符)你将收到一个格式如下
*port*;valid=*validity*;value=*value*;...
有效性占位符被替换为1表示有效值,或0表示无效值。端口号规范遵循内部编号系统:lpt1.1对应于port1,com1.1对应于port13。是否一切正常可以通过telnet进行测试:
user@linux:~$ **telnet localhost 4000**
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
**pcmeasure.com1.1**
port13;valid=1;value=22.59;counter0=10627;counter1=14373;
Connection closed by foreign host.
在本例中,当前温度为 22.59°C,且数值有效。
^([260]) PCMeasure 网站截至 2008 年 2 月显示了以下价格:简单温度传感器 30101,36 美元;串行单端口适配器 30201,51 美元;Linux 软件,38 美元(Windows:53 美元)。
^([261]) 下载的访问数据包含在发票中。
^([262]) www.pcmeasure.com/faq.php
21.2 Nagios 插件 check_pcmeasure2.pl
插件check_pcmeasure2.pl^([263])允许通过网络查询单个传感器。在特殊情况下——例如测量气压时——一个调用也可能查询两个传感器。该插件取代了check_pcmeasure.pl,并使用 Perl 模块Nagios::Plugin来正确表示阈值(见 24.1.5 指定阈值,第 557 页)。较旧的check_pc-measure.pl仍在同一链接下提供,但作者不再维护。
除了常用的标准选项外,-h(在线帮助)、-t(超时)、-V(显示版本)和-v(详细,查找错误时的附加信息),check_pcmeasure2.pl还有以下选项:
-H *`address`* / --host=*****`address`*
这是运行软件并连接传感器的测量计算机的计算机名或 IP 地址,或者以太网盒的 IP 地址或主机名。
-S *`sensor`* / --sensor=*****`sensor`*
此开关定义了传感器,例如coml.1或lpt1.2(见上文)。在查询空气压力值时,需要两个传感器,指定时用逗号分隔:--sensor=com1.1,com1.2。
-p *`port`* / --port=*****`port`*
此选项指定了软件或以太网盒子的替代 TCP 端口。默认端口为 4000。
-w *`thresholds`* / --warning=*****`thresholds`*
如果测量值超出此处指定的警告范围(例如,-w 18.0:22.0,参见第 557 页的 24.1.5 指定阈值]) 插件会自动检测该模块是否可用。如果缺失,则不会单独保存数据。
在以下示例中,插件请求连接到 IP 地址192.168.1.199的主机的传感器的温度:
nagios@linux:nagios/libexec$ **./check_pcmeasure2.pl -H 192.168.1.199** \
**-S com1.1 -w 18.0:22.0 -c 16.0:24.0**
WARNING: Value com1.1: 23.5 |value=23.5;18.0:22.0;16.0:24.0;
由于测量值高于 22.0°C 的警告限制,但低于 24°C 的关键限制,因此存在警告。间隔细节与 24.1.5 指定阈值中的图例相对应。
可以使用或不用循环冗余数据库来指定相应的 Nagios 命令:
define command{
command_name **check_temp_max**
command_line $USER1$/**check_pcmeasure2.pl** -H $HOSTADDRESS$ -S $ARG1$
-w $ARG2$ -c $ARG3$
}
define command{
command_name **check_temp_max_rrd**
command_line $USER1$/**check_pcmeasure2.pl** -H $HOSTADDRESS$ -S $ARG1$
-w $ARG2$ -c $ARG3$ -R $ARG4$
}
除了传感器详细信息外,无需 RRD,只需指定最大和关键警告限制。在第二个示例中,$ARG4$中预定义的 RRD 文件保存了测量数据。以下服务使用/var/lib/rrd/temperatur-serverroom1.rrd文件进行此目的:
define service{
host_name linux01
service_description Room temperature
max_check_attempts 1
normal_check_interval 2
**check_command check_temp_max_rrd!com1.1!18.0:22.0!16.0:24.0!/var/lib**
**/rrd/temperatur-serverroom1.rrd**
...
}
当max_check_attempts设置为1时,如果发生错误,Nagios 不会在retry_check_interval间隔内重复查询。相反,温度会每两分钟持续测量一次。
由于室温通常变化非常缓慢,你可以使用normal_check_interval为五分钟的normal_check_interval。如果你选择更大的测量间隔,你可以将max_check_attempts设置为大于1的值,并在出现错误时在更短的间隔内重复测量(例如,retry_check_interval 1)。
^([263]) www.nagiosexchange.org/60;575
^([264]) www.rrdtool.org/
第二十二章:监控 SAP 系统
监控 SAP 系统有几种方法。最简单的是检查对应 SAP 服务运行的端口。通常这些是系统编号00的 TCP 端口 3200/3300,系统编号01的 3201/3301 等。这可以通过在第 6.7.1 节“测试 TCP 端口”中描述的通用插件来完成(第 132 页)。但是,即使端口可达,也可能没有用户能够登录,因为 SAP 内部服务失败,使得无法与系统一起工作。
要真正测试各种 SAP 组件之间的复杂交互,你需要一个与应用层上的 SAP 系统进行通信的程序。这里有两种选择:更简单的一种是使用程序sapinfo,它可以在不直接登录的情况下查询可用信息——就像 SAP-GUI 在启动时那样。不过,如果你愿意付出更多努力,你可以通过 SAP 标准接口与 SAP 系统进行通信。然而,除非你有相应的权限的 SAP 登录,否则这毫无用处。使用计算中心管理系统(CCMS),SAP 提供了自己的内部监控系统,该系统也可以通过 RFC^([265])接口进行查询,并且可以与正确的插件一起在 Nagios 中发挥出色的作用。
22.1 无登录检查:sapinfo
程序sapinfo是客户端 RFC 接口开发的可选软件包的一部分。你需要的 Linux 版本RFC_0PT_46C.SAR可以在 ftp://ftp.sap.com/pub/linuxlab/contrib/获得,或者你可以登录到SAP Service Marketplace(需要密码)并使用那里的搜索帮助查找关键字RFC-SDK。SAP 笔记 413708(目前是当前的 RFC 库)、27517(安装 RFC SDK)和 212876(新的存档工具 SAPCAR)也提供了信息。
22.1.1 安装
SAP 有自己的存档格式,其中预编译的软件被存储。要解包程序,你需要程序SAPCAR,它也可以通过提到的 FTP 链接或通过 SAP Service Marketplace 获得。它的操作方式类似于 tar:
linux:~ # **mkdir /usr/local/sap**
linux:~ # **cd /usr/local/sap**
linux:local/sap # ***/path/to/*SAPCAR -xvf RFC_OPT_46C.SAR**
SAPCAR: processing archive RFC_OPT_46C.SAR
x rfcsdk
x rfcsdk/bin
x rfcsdk/bin/sapinfo
...
存档中的数据位于其自己的子目录 rfcsdk 中。如果您不带任何参数运行 SAPCAR,将显示简短的操作手册。
22.1.2 第一次测试
程序 sapinfo 现在可以不进行进一步配置进行测试。为此,您需要所谓的 连接字符串;如果连接通过 SAP 网关运行,则这是一个类似于 /H/*`ip_of_the_sap-gate-way`*/S/3297/H/*****`ip_of_the_sap_system`* 的字符串;如果没有网关,您只需指定一个可以解析的 IP 地址或主机名,而不是这个复杂的表达式。如有疑问,负责 SAP 系统的管理员将揭示确切的连接字符串。此外,您还必须指定系统编号,^([266)) 在本例中,01:
nagios@linux:~$ **cd /usr/local/sap/rfcsdk/bin**
nagios@linux:rfcsdk/bin$ **./sapinfo ashost=10.128.254.13 sysnr=01**
SAP System Information
--------------------------------------------
Destination p10ap013_P10_01
Host p10ap013
System ID P10
Database P10
DB host P10DB012
DB system ORACLE
SAP release 620
SAP kernel release 640
RFC Protokoll 011
Characters 1100 (NON UNICODE PCS=1)
Integers LIT
Floating P. IE3
SAP machine id 560
Timezone 3600
输出提供了有关 SAP 安装的各种信息,包括 SAP 版本(620)、SAP 系统 ID(P10)、数据库所在的主机以及使用的数据库系统,在这种情况下是 Oracle。
使用 ashost 参数查询特定的应用程序服务器。对于消息服务器,sapinfo 需要以下详细信息:
nagios@linux:rfcsdk/bin$ **./sapinfo r3name=P10 mshost=10.128.254.12 \
group=ISH**
r3name 参数指定 SAP 系统 ID,mshost 定义服务器的 IP 地址,group 描述登录组。只要存在 PUBLIC 组,您就可以省略此参数,然后使用默认值 PUBLIC。
如果查询以错误消息结束,例如
ERROR service 'sapmsP10' unknown
那么 Nagios 服务器在 /etc/services 中的 sapmsP10 服务定义缺失^([267)):
sapmsP10 3600/tcp
对于端口,您定义消息服务器运行的 TCP 端口。这取决于特定的 SAP 安装;标准端口是 3600。
22.1.3 插件 check_sap.sh
插件 check_sap.sh,一个基于 sapinfo 的 shell 脚本,包含在标准的 Nagios 插件包中,但它位于 contrib 目录中,并且不会自动安装。您可以手动将其复制到插件目录:
linux:~ # **cp /usr/local/src/nagios-plugins-1.4/contrib/check_sap.sh \
/usr/local/nagios/libexec/**.
然后您在插件中查找变量 sapinfocmd 并调整 sapinfo 的路径:
sapinfocmd='/usr/local/sap/rfcsdk/bin/sapinfo'
如果在此处指定的位置找不到插件 sapinfo,check_sap.sh 将将错误消息写入 STDERR,但如果没有发生错误,您将在 STDOUT 上收到 OK 消息和返回值 0:
./check_sap.sh: line 79: /usr/sap/rfcsdk/bin/sapinfo: No such file or directory
OK - SAP server available.
与 sapinfo 类似,该插件可以通过两种方式运行:使用参数 as 查询应用程序服务器,使用 ms 消息服务器。每种情况下,第二个参数是连接字符串,如果没有使用 SAP 网关,则它是要查询的主机的 IP 地址或主机名:
check_sap.sh as *connect_string system_number*
check_sap.sh ms *connect_string SID logon_group*
第一种变化需要应用程序服务器的两位系统编号作为第三个参数,计数从 00 开始:
nagios@linux:nagios/libexec$ **./check_sap.sh as 10.128.254.13 01**
OK - SAP server p10ap013_P10_01 available.
这意味着在主机 10.128.254.13 上运行的应用程序服务器是可用的。
当查询消息服务器时,插件会显示属于指定登录组(作为第四个参数给出)的应用服务器。如果此信息缺失,它将确定 PUBLIC 组的应用服务器。
对于消息服务器,你指定 SAP 系统 ID (SID),例如 P10,而不是系统编号:
nagios@linux:nagios/libexec$ **./check_sap.sh ms 10.128.254.12 P10 ISH**
OK - SAP server p10ap014_P10_02 available.
在此示例中,运行在 10.128.254.12 的消息服务器检测到 p10ap014_P10_02 作为登录组 ISH 的应用服务器,并且还揭示了它是可到达的。
以下两个命令定义假设使用 IP 地址就足够了,并且不需要 SAP 连接字符串:
define command{
command_name **check_sap_as**
command_line $USER1$/**check_sap.sh** as $HOSTADDRESS$ $ARG1$
}
define command{
command_name **check_sap_ms**
command_line $USER1$/**check_sap.sh** ms $HOSTADDRESS$ $ARG1$ $ARG2$
}
如果不是这种情况,查询应用服务器的 command_line 可能如下所示:
$USER1$/**check_sap.sh** as /H/sapgw/S/3297/H/$HOSTADDRESS$ $ARG1$
以下服务定义可用于所有应用服务器:
define service{
service_description SAP_AS
host_name sap01
**check_command** **check_sap_as!00**
...
}
由于 SAP 系统中只有一个消息服务器,因此为每个登录组定义一个单独的服务更有意义。以下示例展示了对于 ISH 组:
define service{
service_description SAP_MS_ISH
host_name sap09
**check_command** **check_sap_ms!P10!ISH**
...
}
以这种方式,你可以测试用户是否可以登录,而实际上并不登录。如果在数据库和应用服务器之间存在中断,使得无法登录,sapinfo 在超时后会提供相应的错误信息。作者曾多次观察到在这种情况下,sapinfo 和 check_sap.sh 报告了错误,而应用服务器的仅 TCP 端口测试 check_tcp 返回了 OK,尽管用户已经无法登录。因此,check_sap.sh 即使没有登录,也提供了比仅端口检查更可靠的信息。
22.1.4 更新且用 Perl 编写:check_sap.pl
check_sap.sh 不仅年代久远,显然也不再维护,所以偶尔你只能忍受它返回 OK,即使存在错误。因此,本书的作者用 Perl 编写了自己的插件版本,并在 NagiosExchange 上提供。正如一个值得信赖的 Perl 插件一样,它使用 Perl 模块 Nagios::Plugin(更多内容请参阅 24.2 The Perl Module Nagios::Plugin,第 560 页),使用 Getopt::Long(25.1 使用 Getopt::Long 分割命令行,第 565 页)解析命令行,并包含集成在线帮助。
插件 check_sap.pl 也使用 sapinfo (22.1 不登录检查:sapinfo),并具有以下选项:
--ashost= 表示 connect_string
测试应用服务器。必须指定连接字符串(21.2 Nagios 插件 check_pcmeasure2.pl]) 远程功能调用。
^([266]) SAP 管理员也会知道这一点。
^([267]) 这里将始终显示适当的系统 ID,而不是P10。
^([268]) 这种情况的第一例系统编号为 00,第二例为 01,等等。
^([269]) www.nagiosexchange.org/21;744
22.2 使用 SAP 自己的监控系统 CCMS 进行监控
使用 SAP 自己的计算中心管理系统(CCMS)框架,不仅可以监控 SAP 系统,还可以监控外部应用程序。在这里,本地代理从每个主机收集数据,自 R/3 4.6C 版本发布以来,^([270]) 可以从中央组件中进行查询。检查的数据不仅包括 SAP 特定的功能,如 SAP 缓冲区或批处理作业,还包括操作系统数据,如内存和 CPU 使用情况,或磁盘 I/O 和交换。甚至可以查询使用的数据库或应用程序的平均响应时间。
CCMS 的数据也可以通过 RFC(远程功能调用,一个标准的 SAP 接口)在外部进行查询。SAP 提供了适用于 Unix 和 Windows 平台的相应库,例如,Linux 程序可以通过网络从 CCMS 查询信息。
22.2.1 警报监控器简要概述
在 SAP 世界中,您可以通过 CCMS 警报监控器(事务 RZ20)访问这些数据(图 22-1)。该图显示了所谓的监控连接,它们将各种信息分组。

图 22-1. SAP CCMS 警报监控器
SAP 在其分发中提供了几个预配置值的监控集合。经过培训的 SAP 管理员可以随时创建和操作监控器。在这里,我们将限制自己关注监控集合SAP CCMS 监控模板和对话概述监控器(图 22-2)。
那里指定的会话响应时间(通过监控属性会话响应时间访问)为用户感觉的“慢系统”对应性能问题提供了一个可测量的等效值。此值指定了事务的平均处理时间(不包括网络传输时间和在客户端 GUI 中渲染信息所需的时间)。

图 22-2. SAP CCMS 监控对话框概览
监控属性网络时间揭示了系统在会话阶段从客户端(SAP GUI)到 SAP 系统以及返回所需的时间。
对于每个属性,监控显示在 SAP 系统中定义的上下文(通常是哪个 SAP 实例)参与了指定的测量值。大多数测量参数都有一个警告和临界限制。如果值低于警告限制,监控器将以绿色显示该行;对于单色设备,颜色以文本形式列出。如果超过警告限制,显示黄色,如果超过临界限制,显示红色。如果部分树的条目超出绿色限制,监控器也将上层节点设置为黄色或红色,以便管理员即使在菜单未打开的情况下也能看到有问题。
通常情况下,您不需要担心阈值。SAP 配置的设置是合理的,只有在有充分的理由进行更改时才应该更改。
在 22.2.4 CCMS 插件(第 525 页)中描述的 CCMS 查询的 Nagios 插件返回 CCMS 中定义的状态:绿灯亮时为 OK,黄灯为 WARNING,红灯为 CRITICAL。因此,阈值是由 SAP 系统设置的,而不是由 Nagios 设置的。
如果您想了解更多关于 CCMS 的信息,请参阅service.sap.com/monitoring(需要密码)中的文档。在那里,SAP 提供了关于 CCMS 安装和操作的详细信息。SAP 在线帮助也提供了广泛的信息。如果您只想对主题有一个简短的总结,并且对 Nagios 插件的工作方式更感兴趣,您可以在关键字SAP CCMS下找到两个信息丰富的 PDF 文档,地址为www.nagiosexchange.org/Misc.54.0.html。
22.2.2 为 Nagios 获取必要的 SAP 使用权限^([271])
从 CCMS 检索信息是通过 RFC (远程功能调用)完成的,这需要在 SAP 端进行登录。幸运的是,用户只需要最小权限集。
在角色生成器(事务 PFCG)中设置了一个新角色,其名称符合公司内部规范。在菜单中没有分配任何事务。

图 22-3. 从 Nagios 访问需要这些 SAP 授权对象
在维护权限时,以下权限对象会手动添加:S_RFC、S_XMI_LOG和S_XMI_PROD(参见图 22-3)。
这些权限是否足够可以通过 22.2.4 CCMS 插件中描述的插件check_sap_cons进行测试,第 525 页check_sap_cons。如果权限对象S_RFC中缺少功能组(如SALG),则插件会在错误消息中以纯文本形式显示该名称。
登录数据存储在 Nagios 服务器上的文件/etc/sapmon/login.cfg中。在此过程中,可以同时配置多个目标主机(在 SAP 中称为RFC 目标)。这种针对目标系统的登录配置在 CCMS 插件的语言中称为RFC 模板(22.2.4 CCMS 插件,第 525 页)。它具有以下形式:
[LOGIN_*template*]
LOGIN=-d *target* -u *user* -p *password* -c *client-id* -h *address*
-s *system_number*
完整的LOGIN定义必须写在单行上,并且它必须包含以下详细信息:
-d *`target`*
这是 SAP 系统的名称,也称为SID或系统 ID。
-u *`user`* -p *`password`*
这些参数指定了 SAP 用户及其对应的密码。请记住,新创建的对话框用户在首次登录时必须更改其密码。
此外,某些系统存在大小写问题:在某些情况下,密码必须全部大写。
如果登录是为了以后使用,密码可能不能包含#符号。允许的特殊字符似乎取决于系统设置。这里你可能需要稍微试验一下,如果需要的话。如果你遇到问题,最好从一个非常简单的密码开始,这样就可以排除这类错误。
-c *`client-id`*
这是三位数的客户端 ID。
-h *`address`*
命名用户应该登录的主机名。这必须解析为 IP 地址。
-s *`system_number`*
SAP 系统编号。第一个 SAP 实例通常是00,然后增量增加。
下面,具有密码*`secret`*的用户应从 ID 为020的客户端登录到主机p10ap013,其 SAP 安装的系统编号为01:
[LOGIN_P10]
LOGIN=-d P10 -u *user* -p *secret* -c 020 -h p10ap013 -s 01
方括号中的 RFC 模板名称由文本LOGIN_和 SAP 系统 ID(SID)组成。这里定义的 RFC 模板属于 SAP 系统P10。
22.2.3 监视器和模板
SAP 提供的由插件使用的接口有简单和可扩展两种形式。只有额外的功能才能检索 CCMS 的所有信息,这就是为什么我们省略了简单接口的描述.^([272])
对于扩展接口,模板定义了要使用的监控数据。这些数据存储在 Nagios 服务器上的文件 /etc/sapmon/agent.cfg 中,并具有以下格式:
[TEMPLATE_*name*]
DESCRIPTION *description*
MONI_SET_NAME= *monitor collection*
MONI_NAME= *name_of_the_monitor*
PATTERN_0=SID\*context\monitor_object\attribute*
以斜体字写的占位符替换如下:
*`name`*
这是插件用来引用模板的名称。该名称可以由数字、字母以及字符 _ 和 - 组成。当插件调用时,名称必须小写,无论它被调用为 TEST、Test 或 test 等。如果您在字母数字名称上遇到问题,在开始时最好选择由两位数字组成的模板名称,例如 00、01 等。
*`description`*
一个自由选择的简单文本。
*`monitor collection`*
这是监控器的名称,设置方式与 CCMS 中完全相同(包括大小写和空格)。
*`name_of_the_monitor`*
监控器的名称也必须与 SAP 名称完全匹配。
*`context`*
此模式从监控器包含的值中筛选出所需值。在大多数情况下,您指定 SAP 实例的标识符,例如 p10ap013_P10_01(p10ap013 是主机名,P10 是 SAP 系统的 SID,01 是系统编号)。
*`monitor_object`*
这是所需监控对象的名称,例如 Dialog。不幸的是,这里要求的术语很少与 SAP GUI 中显示的术语相符。最好使用 PATTERN_0=* 来确定它,如下所述。
*`attribute`*
这是需要查询的变量。每个监控对象可能包含多个变量。例如,Dialog 除了 ResponseTime 变量外,还有 FrontendNetTime 变量,该变量揭示了事务的平均处理时间,限于网络传输时间和客户端的处理时间。
这里的挑战在于在 PATTERN_0 中指定过滤器。它必须与 SAP 内部名称完全匹配,而这些名称与在 CCMS 警报监控器(事务 RZ20)中显示的术语并不相同。
最好从 PATTERN_0=* 开始,这确保了整个树都出现。我们将简单地称这个模板为 00:
[TEMPLATE_00]
DESCRIPTION=Dialog response time
MONI_SET_NAME=SAP CCMS Monitor Templates
MONI_NAME=Dialog Overview
PATTERN_0=*
在 /etc/sapmon/agent.cfg 中的这个条目使用 check_sap_cons 插件查询所有监控条目的完整列表,在这种情况下是 ID 为 P10 的系统:
nagios@linux:nagios/libexec$ **./check_sap_cons 00 P10**
...
P10 p10ap013_P10_01 Dialog ResponseTime 262 msec
P10 p10ap014_P10_02 Dialog ResponseTime 61 msec
P10 p10db012_P10_00 Dialog ResponseTime 11 msec
...
条目包含以下信息——项目之间由空格分隔:
*SID context monitor_object attribute value*
查询上述P10系统信息首先给出 SAP 实例,例如p10ap013_P10_01,然后是监控对象(Dialog)和属性(ResponseTime)及其值。在 SAP GUI(图 22-2])转换为 tar 文件,或者您可以从 SuSE FTP 镜像^([274])获取源 RPM 并自行编译源代码。这将为您提供表 22-1 中列出的插件。
表 22-1. SAP-CCMS 插件
| 插件 | 描述 |
|---|---|
| ^([a]) | |
check_sap |
以 HTML 格式输出监控数据 |
check_sap_cons |
同上,但输出无 HTML 格式和无超链接 |
check_sap_instance |
特定应用服务器的对话框响应时间和登录用户数(需要 CCMS Ping^([a])) |
check_sap_instance_cons |
同上,作为无 HTML 标记的文本输出 |
check_sap_multiple |
监控模板数据的 HTML 格式输出,返回多个值 |
check_sap_mult_no_thr |
与check_sap_multiple不同,输出多个值,具有简单的 HTML 格式,无超链接 |
check_sap_system |
显示 SAP 系统的应用服务器及其状态(需要 CCMS Ping) |
check_sap_system_cons |
与check_sap_system类似,但无 HTML 格式 |
|
^([a]) 作为 CCMS 监控系统的一部分,CCMS Ping 监控属于 SAP 系统的应用服务器的可用性。
|
以 _cons 结尾的插件特别适合测试目的:它们只是简单地将数据传递到命令行,而不进行进一步格式化。其他插件的输出包含由 SAP 修改的 Nagios 版本的 HTML 格式;在 Nagios 2.0 中,它们通常会导致视图错误,因此无用。
最好使用check_sap_cons检索单个值。对于 Nagios 2.x,监控定义必须真正只返回一个单一值。其余的将返回在额外的行上,由 Nagios 2.x 忽略。
如果你从 3.0 版本开始使用 Nagios,你当然可以以这种方式制定监控定义,使得check_sap_cons返回多个值。尽管 Web 界面只会显示这些值的第一个,但通过extinfo.cgi扩展视图将显示其余的输出,长度可达 8 KB(见图 22-4)。

图 22-4. check_sap_cons 在 Nagios 3.0 中的多行输出。
如果 Nagios 2.x 要显示多个返回值,最好使用check_sap_mult_no_thr,它提供了这些值和一些 HTML 格式化元素,这些元素也适用于 Nagios 2.x。这导致所有结果都在 Web 界面中显示。
所有插件都要求两个参数:check_sap、check_sap_cons、check_sap_multiple和check_sap_mult_no_thr首先需要从文件/etc/sapmon/agent.cfg中获取监控模板的名称,例如00、00_sapl3、01或10(见 22.2.2 为 Nagios 获取必要的 SAP 使用权限),然后是 RFC 模板的名称,如/etc/sapmon/login.cfg中定义的(在这本书的例子中我们使用系统 ID P10)。
对于check_sap_system/check_sap_system_cons和check_sap_instance/check_sap_system_cons,第一个参数发生变化:check_sap_system要求系统 ID(在这里,P10),而check_sap_instance要求 SAP 实例,包括主机名、SID 和系统编号(例如,p10apl3_P10_01)。
使用check_sap_cons的初步步骤
插件check_sap_cons可能最适合你的初次尝试。只有在你正确地在命令行上使用它之后,你才应该继续进行实际的 Nagios 配置。在 22.2.3 监控和模板的例子中已经展示了如何使用监控模板00确定对话框响应时间,接下来的例子使用监控模板01查询 SAP GUI 需要的网络时间,直到事务的结果出现在 SAP GUI 中:
nagios@linux:nagios/libexec$ **./check_sap_cons 01 P10**
P10 p10ap013_P10_01 Dialog FrontEndNetTime 383 msec
P10 p10ap014_P10_02 Dialog FrontEndNetTime 673 msec
P10 p10db012_P10_00 Dialog FrontEndNetTime 1491 msec
两个模板中的定义可以在第 523 页的 22.2.3 监控器和模板中找到。在两个示例中,check_sap_cons 返回多个值,只有其中第一行会在 Web 界面和通知中被 Nagios 注意到。如果实例 p10ap014_P10_02 显示了关键状态,而 p10ap013_P10_01 没有显示,插件会返回 CRITICAL,但 Web 界面只会显示第一行(就像通知一样),这不会引起任何担忧。这意味着管理员不会看到触发关键状态的确切原因。
如果 check_sap_cons 只返回错误消息而不是您想要的数据,这可能有几个原因。在以下示例中,登录失败:
nagios@linux:nagios/libexec$ **./check_sap_cons 00 P10**
<== RfcLastError
FUNCTION: SXMI_LOGON
RFC operation/code SYSTEM_FAILURE
ERROR/EXCEPTION
key :
status :
message : User account not in validity date
internal:
<== RfcClose
原因在 message: 字段中给出:当前用户没有有效的账户。如果以下消息出现在那里
message : User 910WOB has no RFC authorization for function group SXMI.
这意味着用户 910W0B 在授权对象 S_RFC 中没有必要的权限。为了授予它,该用户应分配到功能组 SXMI。
插件将此类 RFC 错误消息记录在当前工作目录的 dev_rfc 文件中。如果 Nagios 运行插件,那么它将在 Nagios 主目录(/usr/local/nagios,如果您遵循了本书中的安装说明)中生成此文件。
在下一个案例中,登录工作得很好,但插件没有返回任何值:
nagios@linux:nagios/libexec$ **./check_sap_cons 01 P10**
No information gathered! System up?
错误在于监控定义:通常监控集或监控器的名称写错了,或者模式与使用的监控器不匹配。监控器和模式的交集为空,如果监控器或监控集不存在,SAP 也不会明确警告。
使用 check_sap_mult_no_thr 检查多个值
如果 Nagios 要在 Web 界面中代表多个查询值,您应使用 check_sap_mult_no_thr:
nagios@linux:nagios/libexec$ **./check_sap_mult_no_thr 00 P10**
<table>
<tr><td CLASS='statusOK'>P10 p10ap013_P10_01 <br>
Dialog ResponseTime 785 msec</td></tr>
<tr><td CLASS='statusOK'>P10 p10ap014_P10_02 <br>
Dialog ResponseTime 352 msec</td></tr>
<tr><td CLASS='statusOK'>P10 p10db012_P10_00 <br>
Dialog ResponseTime 22 msec</td></tr>
</table>
输出以单行给出,我们在此手动重新格式化,以便更容易阅读。使用 HTML 代码,插件确保每个值(多亏了 CLASS 规范)都在与其状态匹配的颜色上单独一行显示。如果至少有一个测量值是关键的,Nagios 服务的状态将变为 CRITICAL。这种情况在图 22-5 中显示。

图 22-5. Check_sap_mult_no_thr 使用 HTML。标记,Nagios 2.0 也理解
在这种情况下,你也应该记住,Nagios 2.x 总共处理的插件输出不超过 300 字节,并截断其余部分。对于 HTML 格式的输出,不仅信息会丢失,而且在 Web 界面的表格布局中也会有副作用。如果有疑问,你必须将测试分配给多个服务检查。从 Nagios 3.0 开始,这个问题通常不再发生,因为插件输出的 8 KB 限制通常也足够显示大量输出。
在 Nagios 命令对象的定义中,主机名对于 CCMS 插件来说例外,不起作用。这意味着不使用 $HOSTADDRESS$ 宏:
define command{
command_name **check_sap_ccms**
command_line $USER1$/**check_sap_mult_no_thr** $ARG1$ $ARG2$
}
如果你同时请求多个值,它们通常属于不同的主机。这意味着服务只能在一对一的单一值查询中分配给主机。尽管如此,Nagios 期望在服务定义中有一个特定的主机:
define service{
service_description SAP Dialog Response Time
host_name sap01
**check_command** **check_sap_ccms!00!P10**
...
}
22.2.5 性能优化
由于监控器总是通过 RFC 接口传输所有可用的数据,因此过滤总是在客户端通过插件进行。因此,不建议你依次查询大型监控器的单个值:这会消耗大量资源。
你应该让单个服务提供所有值,^([275]) 或者你自己定义一个包含你想要测试的精确值的单独监控器。SAP 推荐后者。
如果你想要检查多个监控器,或者依次检查监控器的单个值,你应该注意必要的网络带宽。在本地网络中这通常不是问题,但它可能会对窄带长距离连接(ISDN、简单的 VPN)造成相当大的负担。在这种情况下,你应该在启动操作时测量网络流量,以便在出现问题时相应地增加检查间隔。
^([270]) 在早期版本中无法进行集中评估。
^([271]) 本节旨在为 SAP 授权管理员提供信息。如果你不自己维护 SAP 授权,你可以跳过本节。
^([272]) 关于此的信息由 22.2.1 监控器概述 中提到的 PDF 文档提供。
^([273]) 可以在 www.rpmseek.com/ 找到,例如,如果你在那里搜索 nagios-plugins-sap-ccms。
^([275]) 使用专为输出多个值预定的插件。
第二十三章:处理事件数据库中的事件
事件在 Nagios 中与其他通常的主机和状态服务截然不同。在服务处于关键状态时,对服务的检查会返回 CRITICAL,直到服务状态改变,无论检查次数和重复间隔是多少。另一方面,事件只会发生一次,例如以 syslog 条目或 SNMP 陷阱的形式。
如果不间断电源(UPS)的事件通过 syslog 记录到日志文件中,那么 UPS 由于电压供应失败而切换到电池的消息将只出现一次。如果您现在定期测试是否在过去的半小时内发生了相应的条目,那么简单的日志文件检查在时间过期后不会宣布匹配,因此它们将返回 OK,因为没有关键事件。但是 UPS 仍然处于关键状态。只有当收到电压供应已恢复的消息时,关键状态才会真正结束。
通过 SNMP 陷阱进行监控接近期望的行为:一个警报陷阱宣布电压供应失败,服务状态设置为 CRITICAL,随后的 OK 陷阱宣布电压供应已恢复,状态变回 OK。
事件可以通过多种方式集成到 Nagios 中。简单的 syslog 集成在 14.5 应用示例 I:集成 syslog 和 Nagios 中有描述,从第 306 页开始,另一种处理 SNMP 陷阱的方法,也保持得很简单,在 14.6 应用示例 II:处理 SNMP 陷阱中有处理,从第 312 页开始。对于 Windows 事件,通常只需要测试在过去 12 到 24 小时内是否发生了特定事件。可以使用 NSClient++和模块CheckEventLog(20.4.4 内部 NSClient++函数,第 502 页)进行检查,例如。
本章中描述的程序更进一步。所有事件都收集在事件数据库中。管理员通过 Web 界面处理所有这些事件,并设置确认。Nagios 现在通过插件检查特定组是否超过了定义的事件数量,这样管理员就必须采取行动——设置确认并采取进一步行动,如果需要的话。
nagtrap^([276])(以前称为 SNMPTT Web 前端,不要与 SNMPTT GUI^([277])混淆)采用了类似的方法。nagtrap专门用于 SNMP 陷阱,并直接集成到 Nagios Web 界面中。由于篇幅原因,我们在此不进行详细描述。
23.1 事件数据库如何工作
NETWAYS 的 EventDB 基本上由四个组件组成:一个 syslog 连接,用于收集事件;一个 MySQL 数据库用于保存事件;一个用于交互式处理的 Web 界面;以及一个连接 EventDB 到 Nagios 的 Nagios 插件。图 23-1 显示了该设置的示意图。
由于其更灵活的配置,使用了一个中央 syslog 服务——syslog-ng来收集来自各种来源的事件。有各种软件包可用于集成 Windows 事件日志,其中之一在 23.6 将 Windows 事件发送到 Syslog(第 545 页)中进行了描述。安装在 syslog 服务器上的 SNMP 陷阱守护进程snmptrapd(14.6.1 使用 snmptrapd 接收陷阱, 第 312 页),能够将其接收到的陷阱传递给 syslog。为了从加密的 OID 中提供更有意义和可读的消息,SNMP 陷阱翻译器(SNMPTT)可以帮助snmptrapd,这简要地描述在 23.7 使用 SNMPTT 使难以理解的内容易于理解的第 546 页。
syslog-ng允许将现有事件按自定义格式排列并发送到命名管道。从这个管道中,一个守护进程读取传入的事件并将它们写入 MySQL 数据库。通过 Web 界面(图 23-2, 第 539 页),管理员可以通过确认来确认已处理的事件。Nagios 使用插件来测试是否存在一个或多个未确认的特定事件的条目,并相应地通知管理员有关通知功能。
还应提到,即使不使用 Nagios,EventDB 也非常适合处理 syslog 条目。EventDB 的 Web 界面提供了一个简单但有效的界面,可以快速轻松地搜索数据库以查找特定事件或类似事件,尤其是在从大量主机收集相同类型的事件时。

图 23-1. syslog-ng从各种来源收集数据并将其写入命名管道。一个单独的守护进程从该管道读取事件并将它们写入数据库。从这里可以通过 Web 界面或通过 Nagios 插件进行查询。
^([276]) www.nagtrap.org/
^([277]) snmptt-gui.sourceforge.net/
^([278]) www.netways.de/
23.2 安装
可以从 NagiosExchange 获取 EventDB 的当前版本,^([279])并将 tar 存档的内容解压到目录/usr/local/src:
linux:~ # **cd /usr/local/src**
linux:local/src # **tar xvzf** /pfad**/eventdb.tgz**
eventdb/
eventdb/plugin/
eventdb/plugin/check_eventdb.pl
eventdb/agenten/
eventdb/agenten/syslog-ng/
eventdb/agenten/syslog-ng/syslog-ng2mysql
eventdb/agenten/syslog-ng/syslog-ng.conf
eventdb/agenten/syslog-ng/syslog-ng2mysql.pl
...
eventdb/db/
eventdb/db/create_tables.sql
eventdb/webinterface/
eventdb/webinterface/index.php
...
eventdb/cleanup/
eventdb/cleanup/eventdb-clean_database.sh
eventdb/cleanup/rotate_eventdb.sh
...
Nagios 插件位于plugin子目录中。子目录agenten包含与syslog-ng的集成。在db中有一个 MySQL 脚本,用于在数据库中创建必要的表。webinterface目录包含 EventDB 的 Web 界面。
23.2.1 安装要求
EventDB 的一个先决条件是至少版本 1.9.1 的syslog-ng,因为所需的模板机制只从这个版本开始实现。对于数据库,您需要一个当前的 MySQL-5.0 服务器(例如,包含在 Debian 软件包mysql-server-5.0中),以及用 Perl 编写的syslog-ng2mysql.pl守护进程所需的模块DBD::MySQL(在 Debian 中,软件包libdbd-mysql-perl)。
网络界面是用 PHP 5 实现的。这需要 Apache 2,以及适用于此服务器版本的 PHP-5 模块(在 Debian 中为libapache2-mod-php5)和 PHP5-MySQL 软件包(在 Debian 中为php5-mysql)。
EventDB 中不包括检查所有必需软件包是否存在的自动安装程序。
如果要集成的 SNMPTT(将在 23.7 使用 SNMPTT 使难以理解的内容易于理解中稍后描述),则需要snmpd和snmptrapd守护进程,以及相应的客户端程序。Debian 将这些程序提供在snmpd和snmp软件包中。SNMP 陷阱翻译器需要 SNMP Perl(在 Debian 中,包含在libsnmp-perl软件包中),不要与Net::SNMP混淆。
23.2.2 准备 MySQL 数据库
在安装相应发行版的 MySQL-5 服务器软件包后,设置数据库eventdb和数据库用户eventdb:
linux:~ # **mysql -p**
mysql> **CREATE DATABASE eventdb;**
Query OK, 1 row affected (0.01 sec)
mysql> **GRANT SELECT,INSERT,UPDATE,DELETE ON eventdb.* TO** \
**'eventdb'@'localhost' IDENTIFIED by** 'mypassword';
Query OK, 0 rows affected (0.00 sec)
mysql> **quit**
Bye
GRANT命令给eventdb提供了与事件数据库一起工作的必要权限;而不是在这里设置的密码,您使用自己的安全密码。然后切换到源代码已解压的目录(在这种情况下,/usr/local/src/eventdb)并使用子目录db中的脚本create_tables.sql设置必要的表:
linux:~ # **cd /usr/local/src/eventdb**
linux:src/eventdb # **mysql -p eventdb < db/create_tables.sql**
如果在这个过程中没有发生错误,将出现提示,没有任何其他输出。然后可以使用show tables和describe tablename显示脚本创建的内容:
user@linux:~$ **mysql -u eventdb -p eventdb**
mysql> **show tables;**
+-------------------+
| Tables_in_eventdb |
+-------------------+
| comments |
| events |
+-------------------+
2 rows in set (0.00 sec)
mysql> **describe events;**
+-------------+---------------------+-----+-----+---------------+
| Field | Type | Null| Key | Default |
+-------------+---------------------+-----------+---------------+
| uid | int(11) | NO | PRI | NULL |
| type | varchar(50) | NO | MUL | |
| host | varchar(50) | NO | MUL | |
| facility | varchar(50) | NO | MUL | |
| priority | varchar(20) | NO | MUL | |
| level | varchar(10) | NO | | |
| tag | varchar(10) | NO | | |
| program | varchar(50) | NO | | |
| datetime | datetime | NO | | 0000-00-00 00:00:00 |
| message | blob | NO | MUL | |
| acknowledged| tinyint(1) unsigned | NO | | 0 |
+-------------+---------------------+-----+-----+---------------+
11 rows in set (0.00 sec)
MySQL 命令show tables显示创建的表。所有事件都保存在events中。comments表只是一个辅助表,用于管理员在设置确认时可能做出的评论。
23.2.3 使用syslog-ng将事件发送到数据库
syslog-ng的配置已在 14.5 应用示例 I:集成 syslog 和 Nagios 中描述,从第 306 页开始,因此在这里我们只处理 EventDB 的调整。为了使 syslog 守护进程能够将数据传递给 EventDB,我们需要合适的目标和一条使用这些目标的日志条目。为了使配置更清晰,我们将自己的模板写入文件syslog-ng.conf,该文件格式化输出,并在两个目标d_eventdb和df_eventdb的定义中引用:
template t_eventdb {
template("$HOST\t$FACILITY\t$PRIORITY\t$LEVEL\t$TAG\t$YEAR-$MONTH-$DAY
\t$HOUR:$MIN:$SEC\t$PROGRAM\t$MSG\n");
template_escape(no);
};
destination d_eventdb {
pipe("/var/run/syslog-ng.pipe" template(t_eventdb));
};
destination df_eventdb {
file("/var/log/eventdb" template(t_eventdb));
};
在TAG变量中有一个非文档化的组合,即$FACILITY和$PRIORITY,表示要记录的程序类型(守护进程、授权工具、内核、cron 守护进程、打印机等;也见man 3 syslog)和消息的重要性。$HOST是计算机的占位符,$YEAR-$MONTH-$DAY是日期,$HOUR:$MIN:$SEC是时间,$PROGRAM是消息适用的程序,$MSG是日志消息本身。
LEVEL变量实际上是不必要的,因为它包含与PRIORITY相同的值。然而,数据库布局要求这两个值,因此必须指定。整个模板定义必须在配置文件syslog-ng.conf中写在一行上;这里只是为了打印目的而换行。
目标d_eventdb是一个命名管道,其中包含模板的数据。目标df_eventdb用于调试目的,可以在查找错误时用作替代或并行使用。这里的数据最终会进入一个正常的日志文件。由于使用了相同的模板,它产生的文本与命名管道中的文本完全相同。
目前缺少的只有源、过滤器和日志条目:
source local {
unix-stream("/dev/log");
internal();
};
source remote {
udp( ip(0.0.0.0) port(514) );
};
filter f_warn {
level(warn .. alert);
};
log {
source(local); source(remote);
filter(f_warn);
destination(d_eventdb);
# destination(df_eventdb);
};
源local读取所有到达syslog-ng的本地和系统内部事件,但不包括内核事件。remote描述了通过 UDP 端口 514 接收远程 syslog 守护进程数据包的经典方法。过滤器f_warn覆盖所有优先级(或级别)至少为warn的事件。最后,log将过滤器匹配的两个源的事件写入目标d_eventdb。
所示的配置使用/var/run/syslog-ng.pipe作为命名管道。基于 Debian 的系统在系统启动时会删除/var/run/目录的内容。因此,命名管道必须在每次系统启动时重新创建。Event-DB 附带的自启动脚本,agenten/syslog-ng目录中的syslog-ng2mysql,自 2007-11-30 版本以来一直在做这件事;对于旧安装,你应该在脚本开头添加以下两行:
FIFO="/var/run/syslog-ng.pipe"
test -p $FIFO || mkfifo $FIFO
然后将脚本复制到/etc/init.d,并根据发行版确保它在系统启动时自动运行,并且在/etc/init.d/syslog-ng之前运行。
Perl 守护进程syslog-ng2mysql.pl也位于agenten/syslog-ng子目录中。在这个脚本中,你需要将变量$dbuser和$dbpass更改为与你的 MySQL 安装匹配:
my $db = "eventdb";
my $dbhost = "localhost";
my $dbuser = "eventdb";
my $dbpass = *"mypasswd";*
my $dbtable = "events";
然后将文件复制到/usr/local/sbin,其中 init 脚本期望它在那里。使用
linux:~ # **/etc/init.d/syslog-ng2mysql start**
linux:~ # **/etc/init.d/syslog-ng restart**
你重启 Perl 守护进程并重新启动 syslog 守护进程。
可以通过在events表上输入简单的select *命令来获得事件是否最终进入数据库的初步概述:
user@linux:~$ **mysql -u eventdb -p eventdb**
mysql> **select * from events;**
...
如果这里没有任何操作,你可以使用logger程序来测试 syslog 守护进程是否正在将条目写入日志文件(有关更多信息,请参阅man logger):
user@linux:~$ **logger -p daemon.warn "hallo wob"**
即使 syslog 工作正常,如果没有条目出现,你应该启用目标df_eventdb并检查模板的输出是否格式正确。
^([279]) www.nagiosexchange.org/36;1129
23.3 使用 Web 界面
EventDB 的 Web 界面由一个单一的 PHP 文件index.php组成,该文件包含在webinterface子目录中的 tar 文件中。它直接访问数据库,因此需要数据库的详细信息,例如用户名和密码。你应该相应地检查(并更改)文件中的以下四行:
// Database
cset('db.user', 'eventdb');
cset('db.pass', '*mypasswd')*;
cset('db.host', 'localhost');
cset('db.name', 'eventdb');
然后将index.php复制到(之前创建的)目录/usr/local/nagios/share/eventdb。如图图 23-2 所示,Web 界面可以通过 URL nagios-server/nagios/eventdb/index.php 访问。
Web 界面大致分为三个区域:顶部的选择窗口,允许选择性过滤数据,中间的事件显示,以及一个允许对确认进行注释的第三部分。

图 23-2. EventDB 的 Web 界面允许选择某些条目,管理员也可以通过 Web 界面为每个事件设置确认。
选择过滤器类型指的是事件源,通常是syslog。如果正在处理 SNMP 陷阱,则包括另一种类型,snmptrap。通过主机,您可以通过 syslog 条目中的主机详细信息指定事件的来源系统。设施和优先级的选择选项也对应于 syslog 中使用的命名约定(见 23.2.2 准备 MySQL 数据库)。
如果您勾选了显示已确认的项目,Web 界面将显示所有事件。通常您只会看到没有确认的事件。
更重要的是中间的文本框:在顶部,您可以输入简单的模式。例如,如果您正在寻找程序pluto的所有条目,您只需在这里输入pluto*。区分大小写。正则表达式提供了更多选项,可以在第二行指定:条目(smbd|nmbd|win/bind)搜索所有包含smbd、nmbd或winbind的条目。然而,正则表达式搜索要慢得多。字符串不存在的勾选标记将否定之前的选项。
选项消息为空只能单独使用。它忽略文本框中的所有其他设置,并显示所有不包含任何消息文本的事件。
显示框会影响展示效果。您可以选择不同的排序方法,并定义要显示的条目数量。默认的20条目对于许多用途来说太低。如果 Web 界面默认显示更多的条目,您应该相应地更改文件index.php中的以下行:
cset('page.maxrows', 20);
数据范围显示正常的 syslog 条目,以及数据库中数据集的编号在ID列中。对于确认,您可以在条目前面放置勾选标记,如果需要,在下方部分输入注释,并选择确认按钮。确认的条目在重新加载网页时消失。
如果您想同时确认所有显示的条目,请选择第一张表的第一列的rev标题,这将反转选择字段的当前状态。通过按钮进行的后续确认将同时确认所有条目。
负责确认的人员列在 作者 行中。一旦用户登录到 Web 服务器,他的用户名将自动显示在那里;否则,将显示 AnonymousGnome 作为作者。此条目可以按需覆盖。
23.3.1 使用 URL 参数预选择过滤器
可以通过 URL 将特定参数传递给 Web 界面,以便在调用时已预先选择:
http://*nagios-server*/nagios/eventdb/index.php?host[0]=swobspace
此示例调用分配给主机 swob-space 的所有未确认条目。多选条目在 Web 界面中以数组形式表示,因此必须在参数 host、type、facility 和 priority 中用方括号指定。多主机条目通过连续索引查询:index.php?host[0]=swobspace&host[1]=wobgate 或 index.php?host[0]=wobgate&host[1]=swobspace—Web 界面中菜单条目的顺序不必与索引顺序匹配。
可以指定以下 CGI 参数,彼此之间用 & 分隔:
type[*`index`*]=*****`type`*
对应于 类型 过滤器。
host[*`index`*]=*****`host`*
确保选择在 主机 字段中。
facility[*`index`*]=*****`facility`*
选择 设施 条目。
priority[*`index`*]=*****`priority`*
对应于 优先级 选择。
message=*****`pattern`*
占位符 *`pattern`* 被替换为你将在 消息 框中写入的表达式。特殊字符必须首先以 HTML 兼容的代码编译。因此,*Bad TCP* 转换为 %2Abad%20TCP%2A:^([280])
event.php?message=%2ABad%20TCP%2A
regexp=*****`regular_expression`*
允许给出正则搜索表达式。与 message 一样,特殊字符也必须以 HTML 兼容的形式给出。
displayack=*****`value`*
当设置为 true 时,也显示已确认的条目。默认值是相反的值,false。
message_notexists=*****`value`*
模拟在 字符串不存在 前设置勾选:值 true 取消 message 和 regexp 选择。相反的值,false,是默认值。
message_notext=*****`value`*
当设置为 true 时,仅显示消息为空的条目。这里默认值也是 false。
order=*****`sorting`*
允许定义排序顺序:ASC 为升序,DESC 为降序。
orderby=*****`criterion`*
定义通过哪个字段进行排序:datetime、priority、host、facility 或 uid(数据库索引)。
displayrows=*****`number`*
定义要显示的行数。
23.4 EventDB 的 Nagios 插件
使用 Nagios 中的插件 check_event-db.pl 从 Nagios 查询 EventDB,该插件位于子目录 plugin 中,并复制到目录 /usr/local/nagios/libexec/。它有以下选项:
--db=*****`数据库名称`*
EventDB 的名称。仅在它不同于默认的 eventdb 时指定。
--dbtable=*`数据库表`*
数据库中的事件表。默认的 events 很少更改。
--dbuser=*****`数据库用户`*
此参数必须始终提供,因为数据库用户默认设置为 none。
--dbpassword=*****`数据库密码`*
同样适用于此用户的密码。
--dbhost=*****`数据库主机`*
运行数据库的主机的详细信息。默认设置为 localhost。
-H *`主机名`* /--host=*****`主机名`*
系统日志中消息的实际来源主机。
-p *`优先级`* / --priority=*****`优先级`*
所需的系统日志优先级(或级别),例如 warning、err 或 crit。有关其他信息,请参阅 man 3 syslog。
-f *`设施`* / --facility=*****`设施`*
要查询的系统日志设施,例如 cron、daemon 或 auth(另请参阅 man 3 syslog)。
-m *`文本`* / --message=*****`文本`*
插件应查找的事件文本。它以消息来源程序的名称开头。如果您正在查找来自程序 snmpd 的条目,请输入 -m ' snmpd*'。可以使用等效的通配符 *(shell 语法)和 %(SQL 语法);插件将 * 替换为 %。
-t *`类型`* / --type=*****`类型`*
事件类型,通常是 syslog。
-l *`前缀`* / --label=*****`前缀`*
放在插件输出前面的文本,以便更好地识别特定的检查。
-w *`整数`* / --warning=*****`整数`*
如果插件找到至少 整数 个匹配项,它将发出警告。
-c *`整数`* / --critical=*****`整数`*
如果插件找到至少 整数 个匹配项,它将发出严重警告。
以下插件调用查找来自 daemon 设施的所有具有 err 优先级的错误消息,这些消息源自 snmpd 并包含任何类型的消息文本。如果插件找到一个条目,它应该发出警告;如果找到两个或更多,它应该发出严重警告:
nagios@linux:nagios/libexec$ **./check_eventdb.pl --dbuser=eventdb** \
**--dbpassword=secret --facility daemon --priority err -m "snmpd%" \**
**-w 1 -c 2 --label=syslog-snmpd**
CRITICAL: syslog-snmpd 6 matches found!|matches=6
--label 在 syslog-snmpd 文本前添加实际结果,以便更容易解释。
由于实际逻辑存储在服务定义中,因此命令定义保持非常简单。整个 command_line 必须像以前一样,写在一行中:
define command {
command_name check_eventdb
command_line $USER1$/check_eventdb.pl --dbuser=eventdb --dbpass=$USER
9$ $ARG1$
}
数据库用户名和密码在这里紧密相连。为了确保此时没有密码可见,我们使用资源文件中的宏$USER9$(请参阅 A.1 主配置文件 nagios.cfg)。所有其他参数都由$ARG1$的服务定义指定,例如如下所示:
define service {
host_name nagios
service_description syslog_snmpd
check_command check_eventdb!--facility daemon --priority err -m
"snmpd%" -w 1 -c 2 --label=syslog-snmpd
...
}
^([280]) 特殊字符将被转换为%后跟其十六进制值:空格对应 20,*对应 2A;请参阅man ascii。
23.5 维护
在某些情况下,MySQL 数据库可能会很快填满——这取决于连接的系统和通过 syslog 传递的事件数量。这时就需要进行清理。为此,您需要找到所有早于某个日期的条目,检查是否存在确认,然后删除它们。以下SELECT语句展示了这一原理:
user@linux:~$ **mysql -u eventdb -p eventdb**
mysql> **SELECT * FROM events WHERE datetime < '2007-11-16'**
-> **AND acknowledged;**
MySQL 以*`YYYY-mm-dd HH:MM:SS`*的格式存储日期,这就是为什么简单的字符串比较可以工作。如果管理员已确认条目,则acknowledged字段将包含值1。以下简单的清理脚本删除所有超过两周的确认条目:
#!/bin/bash
OLDDATE='date --date '-2 weeks' "+%Y-%m-%d %H:%M:%S"'
MYSQL="mysql --user=eventdb --password*mypassword* eventdb"
$MYSQL --execute="DELETE FROM events WHERE datetime < '$OLDDATE' AND acknowledged;"
$MYSQL --execute="optimize table events;"
该脚本通过 cron 每天运行,但在彻底测试之前不会运行。如果您在删除之前想要存档数据,您需要在DELETE语句之前导出它。为此,您需要将 SQL 语句INTO OUTFILE添加到上面引入的SELECT命令中,在SELECT *和FROM之间。这将数据保存到文本文件中,使用制表符作为分隔符,如下所示:
SELECT *
INTO OUTFILE '/var/backups/eventdb/$OLDDATE.txt'
FIELDS TERMINATED BY '\t'
FROM events WHERE datetime < '2007-11-16' AND acknowledged;
EventDB tar 文件包含两个示例脚本eventdb-clean_database.sh和rotate_eventdb.sh,位于cleanup子目录中,这些脚本本质上调用前面描述的函数。尽管如此,您仍然需要仔细考虑如何清理数据库,并相应地修改和测试脚本。
23.6 将 Windows 事件发送到 Syslog
为了将 Windows 系统集成到 syslog 环境中,您需要一个读取 Windows 事件日志并通过 syslog 协议将其发送到中央 Syslog 服务器的服务。这项任务由来自普渡大学工程计算机网络的免费且易于安装的evtsys工具(项目名称Eventlog to Syslog的缩写)执行,该工具可在其主页上下载。网页提供了两个二进制包,一个用于 32 位系统,一个用于 64 位系统(evtsys_exe_32.zip或evtsys_exe_64.zip),以及源代码。
包含在包中的文件evtsys.exe和evtsys.dll被复制到 Windows 服务器系统根目录下的system32子目录(通常是C:\Windows\system32)。然后使用命令安装并激活服务
C:\Windows\system32> **evtsys -i -h** syslogserver
C:\Windows\system32> **net start evtsys**
如果要在已运行该服务的系统上安装当前的 evtsys 版本,您必须首先完全卸载旧版本:
C:\Windows\system32> **net stop evtsys**
C:\Windows\system32> **evtsys -u**
evtsys 会将所有事件日志条目无例外地发送到中央系统日志服务器。消息发送到 daemon 功能,可能的优先级是 notice、warning 和 err。
在所有情况下,您都应利用系统日志服务器上 syslog-ng 的广泛过滤选项,因为单个域控制器本身的安全消息每小时可能就有 1,000 条或更多,即使在小型环境中也是如此!
如果您想在 Windows 端首先过滤事件日志条目,您将需要使用其他服务。一个免费但相对较旧的工具是 NTsyslog,它可能从 Windows 2003 R2 开始无法完美运行。您还可以在互联网上找到各种可以购买的商业解决方案。
Windows 另一个过滤选项是由 Steve Shipway 提供的 Nagios EventLog Agent for Windows,nagevtlog,它也可在 NagiosExchange 上找到。^([283]) 但由于数据通过 NSCA 发送到 Nagios 服务器,因此它与 EventDB 不兼容。
所有在 Windows 端提供过滤功能的服务都有一个缺点:在某些情况下,未知事件甚至可能不会出现在系统日志中,必须在配置中单独补充。如果中央系统日志服务器能够处理数据洪流,使用中央过滤器的方案更容易维护。
^([281]) engineering.purdue.edu/ECN/Resources/Documents/UNIX/evtsys/
^([282]) ntsyslog.sourceforge.net/
^([282]) www.steveshipway.org/software/f_nagios.html
^([283]) www.nagiosexchange.org/49;221
23.7 使用 SNMPTT 使难以理解的内容变得可读
SNMP Trap Translator (SNMPTT)^([285]) 通过伴随的 MIB 将难以理解的数值对象标识符转换为可读文本。要安装此软件,您需要将 SNMPTT 源代码从 Sourceforge^([287]) 解压到 /usr/local/src:
linux:local/src # **tar xvzf /**pfad*/snmptt_1.2.tgz*
linux:local/src # **cd snmptt_1.2**
linux:src/snmptt_1.2 # **cp snmptt snmptthandler snmpttconvertmib /usr/sbin/**.
linux:src/snmptt_1.2 # **chmod +x /usr/sbin/snmptt***
linux:src/snmptt_1.2 # **cp snmptt.ini /etc/snmp/**.
存档中包含的 snmptt、snmptthandler 和 snmpttconvertmib 文件被复制到 /usr/sbin 并通过 chmod 命令使其可执行。配置文件 snmptt.ini 被复制到 /etc/snmp 目录,该目录是在安装 snmpd 软件包时设置的。
snmptrapd 接受 SNMP 陷阱。为了将其转发到 snmptt,需要在 snmptrapd.conf 配置文件中输入以下内容:
# /etc/snmp/snmptrapd.conf
traphandle default /usr/sbin/snmptt
为了将所有陷阱转发到 snmptt,该文件可能只包含此默认规则。snmptt 接受以数值形式表示的对象标识符,因此需要使用带有 -On 选项启动 snmptrapd。根据发行版的不同,snmptrapd 启动脚本可能需要调整。对于 Debian,文件 /etc/default/snmpdis 需要相应修改:
# /etc/default/snmpd (Debian)
...
TRAPDRUN=**yes**
TRAPDOPTS='-Lsd **-On** -p /var/run/snmptrapd.pid'
-Lsd 选项通过 syslog 并行记录所有陷阱以进行调试。这应该在之后关闭,通过将 -Lsd 替换为 -t。
23.7.1 配置文件 snmptt.ini
要描述中央 SNMPTT 配置文件 /etc/snmp/snmptt.ini 的所有参数,将超出本书的范围。我们只需查看可以检查和可能需要调整的节和选项:
[General]
mode = standalone
net_snmp_perl_enable = **1**
mibs_environment = **ALL**
...
[Logging]
log_enable = 1
log_system_enable = 1
unknown_trap_log_enable = 1
syslog_enable = 1
syslog_level = warning
...
[TrapFiles]
snmptt_conf_files = <<END
**/etc/snmp/snmptt/snmptt.conf**
**/etc/snmp/snmptt/messbox.conf**
END
[General] 部分中的设置 mode=stardlone 表示 snmptrapd 直接调用 snmptt。使用 mode=daemon,SNMPTT 作为独立的守护进程运行。net_snmp_perl_enable=1 启用使用 Perl 模块 SNMP,该模块将 OIDs 转换为有意义的文本。由于默认值 0 禁用了模块,因此此参数肯定需要更改。mibs_environment=ALL 集成所有已安装的 MIB。然而,这些必须没有错误,这对于从发行版安装的 MIB(对于 Debian,在 libsnmp-base 软件包中)通常是正常的情况。
[TrapFiles] 部分中的 snmptt_conf_files 参数包含一个配置文件列表,这些文件翻译传入的 SNMP 陷阱并在必要时触发操作。这些文件来自设备的 MIB——如何执行此操作在 23.7.2 转换 MIB 中解释。
[Logging] 部分中的三个变量 log_enable=1、log_system_enable=1 和 unknown_trap_log_enable=1 确保将 SNMPTT 的活动记录到 /var/log/snmptt*,这在查找错误时非常有用。通过记录未知陷阱,使用 unknown_trap_log_enable=1,你可以看到为什么 SNMPTT 没有翻译它接收到的陷阱(例如,可能包含来自配置文件的 OIDs,这些 OIDs 与 MIB 中获取的配置文件中预期的不同)。
两个 syslog_* 参数将翻译后的陷阱转发到这里的 syslog 守护进程,使用 syslog 优先级 warning,这样数据就会随后出现在 EventDB 中。
在 snmptt.ini 和设备相关的配置文件中允许的参数在 SNMPTT 主页上有详细的文档说明.^([288])
23.7.2 转换 MIB
包含的程序 snmpttconvertmib 将现有的 MIB 转换为可以由 SNMPTT 使用的配置文件。翻译器只翻译配置文件中明确列出的文件,这些文件已经与 snmptt_conf_files 集成。
snmptt convertmib使用snmptranslate,因此在使用之前,您应该检查实际的转换程序是否正常工作。为此,运行snmptranslate -m ALL而不带任何其他参数。会出现一个在线帮助,以下是一些起始行:
USAGE: snmptranslate [OPTIONS] OID [OID]...
在此行之前不应出现其他错误消息;如果出现了,这意味着 MIB 没有正确安装。如果 MIB 是直接从发行版安装的,则不应出现错误。
转换过程——根据 MIB 的质量——从非常简单(对于正确构建的 MIB)到几乎不可能(对于存在许多错误的 MIB)不等。例如,Debian 在文件rfcl628-UPS.mib中提供了一个完美的 MIB。此发行版将 MIB 存储在目录/usr/share/snmp/mibs中。
在您开始从其他来源查找和安装 MIB 之前,您应该使用一个“干净的”MIB 进行转换测试。已经提到的 UPS-MIB 如下转换为 SNMPTT 配置文件:
user@linux:~$ **/usr/sbin/snmpttconvertmib** \
**--in=/usr/share/snmp/mibs/rfc1628-UPS.mib** \
**--out=rfc1628-UPS.conf**
....
Done
Total translations: 4
Successful translations: 4
Failed translations: 0
输出末尾的摘要中不应出现错误,就像这里的情况一样。新的配置文件的内容现在如下所示:
EVENT upsTrapOnBattery .1.3.6.1.2.1.33.2.1 "Status Events" CRITICAL
FORMAT UPS On Battery - Utility Power Failure: The UPS is operating on ba
ttery power (Minutes Remaining=%0 Seconds on Battery=$1)
...
这里的两个关键条目是EVENT和FORMAT。第一个包含状态(此处:CRITICAL)以及 OID,而FORMAT定义了在 syslog 和 EventDB 中描述相应事件的文本。更多信息可以在 SNMPTT 主页上的ConvertMIB文档中找到.^([289])
^([285]) www.snmptt.org/
^([286]) 对于 SNMP,请参阅第十一章(第十一章. 使用 SNMP 收集监控相关信息]) www.sourceforge.net/projects/snmptt
^([288]) www.snmptt.org/docs/snmptt.shtml
^([289]) www.snmptt.org/docs/snmpttconvertmib.shtml
第五部分:第五部分开发
第二十四章:编写您自己的插件
插件是独立的程序——由 Nagios 调用——执行检查并以标准化的形式返回结果。如果您想要执行的任务既没有标准的插件,也没有在 NagiosExchange 的类别 | 检查插件中找到合适的插件,那么最好的解决方案就是您自己编写一个插件。
插件只需要在命令行上可执行,并为管理员返回简短的文本输出以及标准化的返回值。如果您想将其也放在互联网上使用,您需要遵守各种指南,以便它能够被广泛使用和接受,而无需大量的支持。
在理论上,对所使用的编程语言没有限制。然而,一些奇特的编程语言会限制在其他系统和平台上的可移植性,脚本语言需要被解释,因此脚本插件比编译型插件执行时间更长。但这不应该阻止任何人使用他们选择的编程语言,尤其是在快速实现比可移植性和执行速度更重要的情况下。但如果您计划使用脚本语言每隔五分钟运行 2000 次或更多的检查,您将不得不解决性能问题。
下面我们将使用 Perl 编程语言。它几乎存在于每个 Unix 系统上,插件必须执行的大量小型任务,需要简单的文本输出,都在这种脚本语言的经典领域内。通过 CPAN^([291]), 也有许多现成的模块可供使用,您可以用模块化的方式处理新出现的任务。然而,脚本语言对性能的拖累仍然存在。然而,有了 ePN,Nagios 拥有自己的集成 Perl 解释器,这大大提高了性能。关于这一点,有一个专门的章节,从第 669 页开始。
在使用 Perl 开发 Nagios 插件时使用的核心中心是 Tom Voon 的 Perl 模块Nagios::Plugin,它在许多方面简化了具体的编程。还使用了Pod::Usage模块,它使得插件源代码中嵌入的 man 页面可以格式化为在线帮助。
24.1 插件编程指南
即使您只是想快速拼凑一些东西,如果您从一开始就遵循官方的开发者指南^([292]), 那么您最终会为自己省去很多麻烦,因为您很少会是唯一一个与最终插件相关的人。
开发者指南目前没有为 Nagios 3.0 提供处理多行输出的选项。Nagios 3 插件的新应用程序编程接口(API)在 Nagios 主页上有描述.^([293])
24.1.1 返回值
Nagios 期望插件提供一个从0到3的标准返回值,该值描述了执行的检查的当前状态。值0(OK)和2(CRITICAL)之间的区别几乎总是由管理员在定义单个检查时通过警告和临界阈值来定义——只有少数插件本身指定阈值。
返回值3(未知)保留用于操作插件时的错误(选项设置错误、不存在选项)或内部插件错误,这些错误可能阻止插件执行其工作。开发指南中引用的例子是一个插件想要打开的网络套接字,但调用失败。另一方面,正常的超时不应以未知响应。当然,有些插件在超时时返回 WARNING,只有当超过特定阈值时才返回 CRITICAL。在许多情况下,对于一般的超时,CRITICAL 更有意义,因为这通常可以解释为服务 xyz 无法工作。
表 24-1 总结了返回值及其含义,按服务和主机检查排列。对于主机检查,Nagios 有 OK、DOWN 和 UNREACHABLE 三种状态,DOWN 和 UNREACHABLE 之间的区别仅反映在空间排列上:失败的主机是否是自身,还是位于失败主机之后的主机?这就是为什么只有状态 ok(0)和错误状态(2)的返回值需要区分的原因。
表 24-1. Nagios 插件返回值
| 状态 | 服务检查 | 主机检查 |
|---|---|---|
| 0 | OK | UP |
| 1 | WARNING | UP 或 DOWN/UNREACHABLE^([a]) |
| 2 | CRITICAL | DOWN/UNREACHABLE |
| 3 | 未知 | DOWN/UNREACHABLE |
|
^([a]) see text
|
在 Nagios 3.0 中,返回值 1 的处理方式取决于参数use_aggressive_host_checking (A.1 主要配置文件 nagios.cfg):如果设置为1,则返回值1表示 DOWN/UNREACHABLE,否则 Nagios 将评估主机为 UP。
24.1.2 管理员在标准输出上的信息
Nagios 期望在标准输出上有文本,告知管理员(例如在网页界面中)当前状态。然而,此输出应保持特定格式:
*TYPE_OF_CHECK STATUS-text information*
实际上,这看起来就像以下三个示例中所示的内容:
SMTP OK - 0 second response time
CHECKSAP OK - system p10db012_P10_00 available
PROCS WARNING: 4 processes with command name 'pppoe'
网页界面仅通过颜色间接显示返回值本身,文本则以可读的形式包含当前状态。文本输出的内容应基于为管理员提供特定检查所需信息的部分。
在文本输出要求方面,Nagios 2.x 和 Nagios 3.0 之间存在相当大的差异。对于 Nagios 2.x,文本必须在单行中,如示例所示。它只会处理多行输出的第一行。整个文本,包括性能数据(我们将在 24.1.6 超时中讨论)的长度不得超过 300 字节。
Nagios 3.0 处理的最大长度为 8192 字节的输出,并且输出可能包含多行。多行格式在 8.5.1 多行插件输出中描述,第 193 页。
如果你正在编写一个利用 Nagios 3.0 优势(多行,文本长度超过 300 字节)的插件,你需要意识到这个插件在 Nagios 2.x 中只能有限制地使用。因此,你应该仔细考虑多行输出格式是否是解决特定问题的正确方法。记住,你可以使用check_multi插件(见 8.5 使用 check_multi 汇总检查,第 191 页)来总结几个单独检查的结果,并通过这种方式减少单个检查的数量——例如,为了优化性能,而不会遗漏详细文本信息。然而,单个检查总是只提供一个返回值,在这种情况下是一个汇总结果。另一种方法是通过脚本和 cron 启动测试,并将单个结果作为被动检查传递给 Nagios。
因此,建议对于通用插件不使用多行输出,并遵守 Nagios 2.x 的限制。
24.1.3 在线帮助?
经典的 Nagios 插件,包括核心插件,不包含单独的 man 页面,但它们是自文档化的:通过使用开关-h或--help来获取帮助。这并不意味着不能有任何其他文档,但集成帮助应该完整,并详细描述所有现有选项,以便插件可以在没有任何进一步文档的情况下使用。
一些插件仅提供-h的简短帮助文本和--help的完整帮助文本。在这种情况下,-h的输出应表明可以通过长格式获取更多信息。
帮助文本也应调整到正常终端的宽度,长度不超过 80 个字符。通常情况下,管理员在服务器房间试图解决问题时,会面对一个简单的控制台。
帮助信息应始终用英语编写。为了本地化目的,即输出不同语言,可以使用 gettext。这个工具使用简单的基于文件的数据库来翻译要显示的文本。如果目标语言没有文本,gettext 会显示未翻译的文本,因此它以容错的方式运行。更多信息可以在 gettext 的 man 页面或 info 页面中找到。
对于 Perl 脚本,man perllocale^([294]) 是一个很好的起点。对于具体应用,我们推荐使用 Perl 模块 Text::Domain,它可以大大简化本地化。
24.1.4 保留选项
编程指南提供了对所有插件具有相同意义的选项。其中最重要的列在 表 6-2 第 108 页中。
此外,还有一些保留选项,在简短形式中有时会被赋予两次。因此,-u 可以代表用户名(--user),也可以代表 URL(--url)。选项 -p 则允许指定 TCP 或 UDP 端口(--port),也可以指定密码(--password)。用户名也可以通过 −l 或 --logname 传递,而密码(更广义上,认证字符串,也可以是 Kerberos 域)可以通过 -a 或 --authentication 传递。
这些选项可能有两个不同的意义,这相当不幸,可能是出于历史原因。如果有疑问,应避免这种双重分配,并仅使用意义明确的选项的长形式。许多 GNU 和其他开源程序以类似的方式运行(例如,tar,rsync,...)。这里的主要是,保留选项不应用于其他目的。例如,保留选项 -C/--community 只与 SNMP 查询结合使用有意义。如果插件与 SNMP 没有关系,则不应将其用于其他目的。
24.1.5 指定阈值
阈值 决定插件返回 OK 还是错误值(警告、临界)。阈值始终根据 from:to 模式指定一个范围。
排除原则在这里需要一些习惯。形式为 -w 10:20 的警告阈值意味着指定范围内的值不会导致警告。警告状态包括从 -∞ 到包括 9 以及从 21 到 ∞ 的所有值。
通过示例最好地解释警告和临界阈值之间的交互。假设 Nagios 正在监控服务器室的温度。正常情况下,温度应在 18°C 和 22°C 之间。在此范围内,上下各两度被设置为容差范围,对于这个范围应显示警告。低于 16°C 和高于 24°C 时,Nagios 应报告临界状态。
将图 24-1 中描述的场景转换为阈值,应该看起来像这样:-w 18:22 -c 16:24。22°C 到 24°C 之间的温度不是关键的,但仅覆盖警告范围。高于 24°C 的温度范围覆盖了两个阈值区间,并且在那里更强的错误值(CRITICAL)占主导地位。

图 24-1. 阈值 -w 18:22 -c 16:24会发生什么?
要否定一个值范围,你只需在其前面放置一个@:-w @10:20现在确保如果确定的值大于或等于 10 且小于或等于 20,将显示警告。如果起始值等于 0,则可以省略:-w 20与-w 0:20具有相同的效果。不需要指定无限大的最终值,但起始值后面的冒号必须保留:-w 10:。波浪号(˜)代表负无穷大,没有为无穷大提供单独的符号(见表 24-2)。
表 24-2. 指定阈值的特殊语法
| 阈值 | 覆盖区域 |
|---|---|
*`end`* |
0: *`end`* |
*`start:`* |
*`start:`*∞ |
˜: *`end`* |
-∞:*****`end`* |
*`@start:end`* |
不是*`start:end`* |
24.1.6 超时
插件可能并不总是能在合理的时间内完成任务。例如,它可能使用df来访问通过 NFS 挂载的卷,而该卷的主机当前不可用。或者,防火墙可能拒绝来自网络插件的网络数据包,而插件并未设计为注意到这一点。然而,Nagios 希望在某个时间点从其插件那里收到合理的回复;如果任何类型的检查在某处悬而未决,这会消耗不必要的资源,并可能真正给 Nagios 调度器造成混乱。
因此,每个插件应在预设时间后取消其操作——通常是十秒钟——并返回给 Nagios 相应的错误结果。选项-t(--timeout)允许在调用插件时指定不同的超时值。
修改超时是有意义的,例如,如果一个插件通过 NRPE(见第十章"))间接运行(从第 213 页开始)。Nagios 直接运行的check_nrpe的超时应该合理地比插件本身的长一些,这样check_nrpe就不会在没有了解真实原因的情况下取消执行。
24.1.7 性能数据
性能数据以标准化的形式呈现结果值,从第 404 页开始描述,这使得这些值可以被外部程序自动处理。它们位于正常文本输出之后,由 | 符号分隔。
只要插件找到数值,它就应该始终将这些值显示为性能数据。如果外部程序可以自动处理这些数据,管理员就不需要做太多的配置工作。有些外部程序可以在必要时从正常文本输出中提取信息,但由于缺乏标准化,这总是伴随着额外的工作——并不是每个 Nagios 管理员都能完美地处理 Perl 兼容的正则表达式。因此,每个插件程序员都应该始终提供性能数据,前提是具体的应用程序允许这样做。
24.1.8 版权
插件应提供清晰的版权声明,注明许可证和作者。对于用编译语言(如 C)编写的插件,这两个项目存储在单独的文本文件中,以便在插件稍后以二进制形式分发时不会丢失这些信息。标准做法是有一个包含所涉及完整许可证(例如,GNU 公共许可证)的 COPYING 文件和一个包含作者名字的 AUTHORS 文件。
对于用脚本语言编写的插件,在源代码本身包含版权声明就足够了,因为插件通常以可读的形式分发。
在使用选项 --version 显示版本号时,提供版权的简要输出也是有用的。
如果插件基于现有的代码,或者个人以补丁或建议的形式参与其中,开发者指南要求提供文件 ACKNOWLEDGEMENTS 和 THANKS。前者用于代码原本有不同的作者(或代码的部分被回收),后者包括那些以补丁形式以及有时以重要思想形式做出贡献的人的名字。
^([290]) www.nagiosexchange.org/Check_Plugins.21.0.html
^([291]) www.cpan.org
^([292]) nagiosplug.sourceforge.net/developer-guidelines.html
^([293]) nagiosplug.sourceforge.net/developer-guidelines.html
^([294]) perldoc.perl.org/perllocale.html
24.2 Perl 模块 Nagios::Plugin
如果你想要以尽可能少的努力在 Perl 中创建插件,同时遵守编程指南,Perl 模块 Nagios::Plugin 可以提供给开发者支持。我们将在 2007 年 10 月的版本 0.21 中介绍它。在这个版本中,主要功能已经得到很好的发展,不应该进行任何重大更改,除了消息函数,这些函数仍然被标记为实验性的。
这个面向对象的模块包含表示状态的常量和变量;退出函数不仅使用与 Nagios 兼容的退出代码,而且格式相同;以及用于测试阈值和正确输出性能数据的函数。此外,它还提供了解析命令行以及集成帮助功能的函数。在这方面,该模块偏离了标准的 Perl 习惯:已经有一个广泛的命令行模块 Getopt::Long,以及在线帮助,Perl 提供了 Perl 在线文档 (POD)。
24.2.1 安装
Nagios::Plugin 是核心插件之一,但也可以通过 CPAN 代替安装。这样,模块以这种方式在系统中固定,Perl 可以自动找到它。但该模块也会导致安装其他模块,这在认证系统中并不总是希望的。
在安装了核心插件之后,Nagios::Plugin 可以在其自己的目录下找到,包括所有依赖的模块。现有的 Perl 安装不会受到影响,但 Perl 不会以这种方式自动找到该模块。任何基于此的插件都必须明确设置模块的基目录路径。
使用 CPAN 的方法
Nagios::Plugin 的 CPAN 安装命令会检查现有依赖关系,并同时安装所需的任何模块:
linux:~ # **perl -MCPAN -e 'install Nagios::Plugin'**
...
在某些情况下,你之前安装的模块将被更新。如果你第一次运行 perl -MCPAN,Perl 将会提出一系列问题,这些问题将交互式地回答——除了下载服务器的选择之外,建议的默认值可以使用。
与核心插件一起
从版本 1.4.10 开始,nagios-plugins* tar 存档也包含 Perl 模块。如果你在运行 configure 命令时使用 --enable-perl-modules 开关(参见 1.4 安装和测试插件,第 43 页),则将其包含在安装中。模块安装到 /usr/local/nagios/perl 目录,符合本书中使用的约定。
为了让插件能够找到模块,你必须通过 use lib 明确设置路径。在他的常见问题解答中^([295]),Ton Voon 推荐使用 Perl 模块 FindBin:
use FindBin;
use lib "$FindBin::Bin/../perl/lib";
use Nagios::Plugin;
FindBin是 Perl 分发的一部分,它找到从插件被调用的目录的路径。根据我们的约定,这是/usr/local/nagios/libexec目录。这个路径通过变量$FindBin::Bin进行查询,然后use lib将相对于此目录的 Nagios 特定 Perl 目录集成。Linux 发行版是否会设置一个具有相同相对路径的 Perl 目录还有待观察。只要你自己安装核心插件,三条命令就会按预期工作。
如果在指定的路径中找不到Nagios::Plugin,Perl 将搜索所有其他标准路径。这样,如果模块来自 CPAN 或(在未来)来自分发包,模块将被找到。
^([295]) www.nagiosplugins.org/faq/development/nagios-plugin-perl
第二十五章. 确定文件和目录大小
对于一个具体的 Perl 插件示例,我们将查看check_du.pl.^([296]) 它用于确定指定文件或目录的大小,并检查总大小是否在预设阈值内。为此,它调用系统程序du:
user@linux:~$ **du -cs /var/spool/var/log**
26524 /var/spool
745640 /var/log
772164 total
当与-s选项一起使用时,du不会列出所有单个子目录,而只显示总大小。-c将单独的值相加以达到总大小。
在开始时,插件使用new Nagios::Plugin构造函数生成一个新的对象,以便它可以利用模块的功能:
#!/usr/bin/perl -w
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../perl/lib";
use Nagios::Plugin;
my $np = Nagios::Plugin->new(shortname ⇒ "CHECK_DU");
这里可以使用各种参数。shortname包含要执行检查的简短名称,它将被后来添加到所有输出之前:^([297])
CHECK_DU OK - check size: 1128 kByte | size=1128kB;;
#!之后的第一个内容定义了要运行的解释器,它是 Perl。选项-w和随后的use warnings——这两个都确保在 Perl 对脚本中的某些内容表示反对时提供大量输出——在这里故意重复。在 Perl 5.6 之前的版本中,没有use warnings参数,所以你必须注释掉该语句并使用-w。为了确保没有人忘记这一点,-w从一开始就被包含在内。指令use strict强制进行严格的语法检查,并迫使程序员预先声明所有变量。当使用此功能时,可以避免许多简单错误。
插件的核心功能以相对简单的方式构建:
open ( OUT, "LANG=C /usr/bin/du -cs $what 2>&1 |" )
or $np->nagios_die( "can't start /usr/bin/du" );
while (<OUT>) {
print "$_" if ($verbose);
chomp $_;
$denied++ if ( /Permission denied/i );
if ( /^(\d+)\s+total$/i ) {
$size = $1;
last;
}
}
close (OUT);
open调用程序du,并处理输出就像它来自一个打开的文件一样。如果调用失败,来自模块Nagios::Plugin的nagios_die将终止插件的执行并发出错误信息。在调用du程序之前,LANG=C明确地将语言设置为英语默认值,这样du显示的文本就不依赖于特定环境。
while 循环逐行读取输出,并检查所有目录是否可评估。如果输出文本中出现 Permission denied,插件会在变量 $denied 中记录这一点,该变量最终包含不可读目录的数量。如果 $verbose 不等于零,插件会将 du 接收到的所有行发送到 STDOUT 以进行调试。chomp 从刚刚处理的行(在 $_ 中调用)中移除行尾。
从报告总大小的行(行尾有文本 total)中,插件使用括号中的正则表达式提取显示的数字。这个数字现在包含在 $1 中。如果有匹配项,last 将终止 while 循环,然后 close 函数正确地关闭文件句柄。
25.1 使用 Getopt::Long 分割命令行
模块 Getopt::Long 提供了一个函数 GetOptions,它简化了类似于许多 GNU 程序风格的命令行分割:
use Getopt::Long qw(:config no_ignore_case bundling);
GetOptions(
"P|path=s" ⇒ \$what,
"w|warning=s" ⇒ \$warn threshold,
"c|critical=s" ⇒ \$crit threshold,
"t|timeout=s" ⇒ \$timeout,
"h|help" ⇒ \$help,
"V|version" ⇒ \$printversion,
"v|verbose+" ⇒ \$verbose,
"d|debug:+" ⇒ \$debug,
) or *die_with_help;*
指令 qw(:conf ig no_ignore_case) 配置了 GetOptions 的行为,以便区分大小写。qw(:config bundling) 允许短选项组合,这与较老的 Unix 和 GNU 程序的正常做法一致;用户可以写 -abc 而不是 -a -b -c。
在 GetOptions 选项中,你列举了插件的所有选项,并为每个选项传递了一个变量的引用。由于 use strict 参数(例如,使用 my $what = ";),在调用 GetOptions 之前必须预先声明这些变量。这存储了通过命令行传递的带有相应选项的参数。左侧的字符串定义了选项可以在什么名称下调用。列出的选项
"P|path|directory=s"
可以通过 -P *`path`*、--path *`path`*、--path=*****`path`* 和 --directory=*****`path`* 等方式调用。所有长格式选项也可以缩写,只要缩写是唯一的。例如,可以是 --pf *`path`*、--pa *`path`* 或 --dir=*****`path`*。
结尾处的指令 =s 表示,在这个例子中类型为字符串(s)的参数必须跟在选项后面。可选的参数类型有 i(整数)、o(Perl 整数,即包括八进制和十六进制数字)和 f(浮点十进制)。如果使用冒号而不是等号,则参数是可选的。
选项名称后面跟着一个加号,例如 v |****verbose+,允许在命令行上多次指定选项。每次使用时,变量都会增加。如果用户选择选项 --verbose,$verbose 将包含值 1,但如果他选择 --verbose --verbose(或 --verbose -v),它将包含 2,依此类推。如果你将加号与冒号结合使用(例如,d|debug:+),用户可以在运行命令时将整数分配给变量:--debug=5 将变量 $debug 设置为 5。如果他只调用 --debug,$debug 将只有值 1。
当调用 GetOptions 时,你应该始终检查是否发生错误,例如通过错误条件。在 Perl 中,这可以这样写:
GetOptions(...) or *die_with_help;*
在出现错误的情况下,开发者指南要求必须指定终止的原因,以及简短的在线帮助。为此,我们需要使用 Perl 在线文档和模块 Pod::Usage。
^([296]) 插件可在作者的首页 linux.swobspace.net/projects/nagios/perl-nagios-plugins.html 获取。
^([297]) 模块在线帮助功能需要其他参数,这些参数我们在这里不会使用。我们将使用模块 Pod::Usage。
25.2 Perl 在线文档
Perl 在线文档 (POD) 是一种简单的标记语言,它基于传统的 man 页面。它允许你在脚本本身中包含 Perl 脚本的文档。命令 perldoc *`script`* 提供了这种预格式化的内容:^([298])
#!/usr/bin/perl -w
**=head1** NAME
check_du.pl - Nagios plugin for checking size of directories and files
**=head1** SYNOPSIS
check_du.pl -P path/pattern [-v] [-w warning_threshold] [-c critical_threshold]
check_du.pl [-h|-V]
**=head1** OPTIONS
**=over 4**
**=item** -P|--path=expression
Path expression for calculating size. May be a shell expression like /var/log/*****.log
**=item** -w|--warning=threshold
threshold can be max (warn if < 0 or > max), min:max (warn if < min or > max), min:
(warn if < min), or @min:max (warn if >= min and <= max). All values must be integer.
**=item** -c|--critical=threshold
see --warning for explanation of threshold format
...
**=cut**
... *perlcode* ...
`=head1` AUTHOR
...
`=cut`
每条指令都以等号作为行的第一个字符开始,如标题 =head1 到 =head4 所示。指令前后保留空白行。
指令 =over 4 以四个字符的缩进开始一个列表,其中只能使用 =item 作为 POD 指令。=cut 结束插入的文档,之后你可以继续使用正常的 Perl 代码。
一个 Perl 脚本可以包含你想要的任意数量的 POD 部分。通常,重要的部分被放置在脚本的开头,而较不重要的部分,如 man 页面的 SEE ALSO-、AUTHOR- 或 BUGS 的细节,则放置在末尾。
除了 perldoc 之外,还有如 pod2html、pod2latex、pod2man、pod2text 和 pod2usage 等程序,它们可以将内联文档显示为其他格式。然而,应该指出的是,POD 基本上显示的是内联 man 页面,而转换为 HTML 的 man 页面仍然具有 man 页面的外观。
man 页面的各个部分由 man man; 描述,重要的部分包括 NAME、SYNOPSIS、DESCRIPTION、OPTIONS、FILES、SEE ALSO、BUGS 和 AUTHOR。如果插件需要更详细的文档,您可以添加自己的部分。POD 格式的语法和结构在 man perlpod 中有详细描述,而 man perldoc 解释了如何提取嵌入的帮助。
25.2.1 Pod::Usage 模块
Pod::Usage 作为 Perl 核心分发的组件,显示内联文档的全部或摘录,并以预定义的退出代码结束脚本:
pod2usage(
-msg ⇒ *$message_text*,
-exitval ⇒ *$exit_status*,
-verbose ⇒ *$verbose*,
-output ⇒ *$filehandle*,
);
您可以使用 -msg 开关指定附加文本,例如关于插件使用不当的说明,该文本将在内联文档之前显示。
-exitval 确定了脚本结束时的返回代码。对于 Nagios 插件,应始终使用导入的常量 UNKNOWN。
-verbose 定义了显示的文档数量。当值为 0, pod2usage 时,生成一个简短的用法信息。对于 -verbose ⇒ 1,输出包括 SYNOPSIS、OPTIONS 和 ARGUMENTS 部分,而对于 -verbose ⇒ 2,则包括整个文档。值 99 扮演了一个特殊角色。这个值与 -sections 开关一起使用,以指定要显示哪些部分:
-verbose ⇒ 99,
-sections ⇒ "NAME|SYNOPSIS|OPTIONS|AUTHOR",
各个部分由 | 符号分隔。-output 开关最终定义信息应该结束的位置——对于 0 或 1 的详细值输出到 STDOUT,对于 2 及以上的值输出到 STDERR。因此,对于完整在线帮助的输出,您应该明确设置此值(否则用户必须首先将 STDERR 重定向到 STDOUT 才能查看帮助):
-output ⇒ \*STDOUT,
在插件中,您首先检查 GetOptions 是否失败,例如因为指定了无效的选项。如果发生错误,则执行 or 后面的指令——在这种情况下是 pod2usage。
GetOptions( ...
) or pod2usage(
-exitval ⇒ UNKNOWN,
-verbose ⇒ 0,
-msg ⇒ "******* unknown option or argument found *******",
);
由于插件使用不当,返回值是 UNKNOWN。-verbose 被设置为 0,因为在这种情况下简短的用法信息就足够了。-msg 更精确地向用户说明他做错了什么;这条信息放在用法信息之前。
如果用户请求在线帮助,插件中包含的整个帮助文本将被显示:
pod2usage(
-verbose ⇒ 2,
-exitval ⇒ UNKNOWN,
-output ⇒ \*STDOUT,
) if ( $help );
由于 pod2usage 通常在这里使用 STDERR,-output 明确确保输出到 STDOUT。
要显示版本号,pod2usage 也可以使用。许多 GNU 程序将版权信息与版本号一起包含。为此,您创建一个 POD 部分 =head1 LICENSE 并使用 verbose ⇒ 99: 输出此部分。
=head1 LICENSE
This program is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
...
You should have received a copy of the GNU General Public License along with this
program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
Fifth Floor, Boston, MA 02110-1301, USA.
=cut
...
pod2usage(
-msg ⇒ "\n$0 -- version: $version\n",
-verbose ⇒ 99,
-sections ⇒ "NAME|LICENSE",
-output ⇒ STDOUT,
-exitval ⇒ UNKNOWN,
) if ( $printversion );
由于此详细级别的输出会发送到 STDERR,因此您也在这里使用 -output 来确保输出发送到 STDOUT。NAME 和 LICENSE 部分可能位于插件文件中,在 pod.2-usage 调用之前或之后。
如果插件期望强制性的详细信息——在我们的例子中,是确定总大小的目录子树路径——则检查参数是否存在值:
pod2usage(
-msg ⇒ "******* no path/pattern specified *******",
-verbose ⇒ 0,
-exitval ⇒ UNKNOWN,
) unless $what;
如果用户没有使用 --path 选项调用插件,变量 $what 将保持为空,并且 pod2usage 将发出相应的消息。
^([298]) 完整文本包含在插件 check_du.pl 中,位于 linux.swobspace.net/projects/nagios/perl-nagios-plugins.html。
25.3 确定阈值
在 24.1.5 指定阈值 页 557 中讨论的阈值格式不易解析,这就是为什么来自模块 Nagios::Plugin 的函数是一个受欢迎的帮助:
$np->set_thresholds(
warning ⇒ $warn_threshold,
critical ⇒ $crit_threshold,
);
$result = $np->check_threshold($size);
$np->nagios_exit($result, "check size: $size kByte");
方法 set_thresholds 的任务是设置 Nagios::Plugin 实例的阈值 $np.$warn_threshold 和 $crit_threshold 包含用户通过命令行上的选项 --warning 和 --critical 传递的详细信息。
check_threshold 将阈值与目录的总大小进行比较,并将返回代码存储在变量 $result(可以是 OK、WARNING 或 CRITICAL)中。这可以直接在函数 nagios_exit.Nagios::Plugin 中使用,该函数负责解析和检查所有工作。
25.4 实现超时
要实现硬超时,C、Perl 和其他编程语言中的函数 alarm() 可用,它通常调用同名的系统函数(见 man 2 alarm)。对于 Perl 的 alarm() 函数,超时以秒为单位指定:
# ... GetOptions ...
alarm($timeout);
# ... core code ...
alarm(0);
# ... end
alarm($timeout) 调用启动警报功能,第二次调用时使用参数 0 停止它。第一次调用应在时间密集型处理步骤之前使用,在网络插件中在打开套接字之前,以及可能发生长时间延迟的类似情况下。一个好的位置是在通过 GetOptions 处理命令行之后。
在插件末尾,建议您重置警报。对于独立程序,这可能不是必需的,但如果 Perl 插件在嵌入式 Perl 解释器中运行,如果不采取此步骤,可能会产生一些不期望的副作用。通过显式停止警报,您可以确保安全。
如果警报被触发,这意味着超时已过期,会发生什么?Perl 会检查是否安装了伴随的信号处理器,如果是的话,就会执行它。建议您利用这个可能性并安装自己的信号处理器,以便插件的行为符合开发者指南:
$SIG{ALRM} = sub {
$np->nagios_die("Timeout reached");
}
信号处理器——一个匿名子程序——被分配给变量 $SIG{ALRM}。子程序调用来自 Na-gios::Plugin 模块的函数 nagios_die。在超时的情况下,插件将终止并返回带有适当错误信息的未知返回代码。
25.5 显示性能数据
使用 Nagios::Plugin 显示性能数据与处理阈值一样简单。您只需运行带有几个参数的函数 add_perfdata,其余的将由 nagios_exit 自动处理:
$np->add_perfdata(
label ⇒ "size",
value ⇒ $size,
uom ⇒ "kB",
threshold ⇒ $np->threshold(),
);
参数 label 定义了变量的名称。value 包含测量的值,uom 定义了测量单位,在此例中为 KB。threshold 期望一个阈值对象,该对象由函数 threshold() 生成。阈值必须已经通过 set_thresholds 设置。
当运行 nagios_exit 时,如果之前已定义了性能数据,则输出将自动显示。
Nagios::Plugin 包还包含模块 Nagios::Plugin::Performance,该模块提供了在 parse_perf string() 中的性能数据解析器,它将性能数据字符串拆分。如果您正在用 Perl 编程处理性能数据的插件,您可以使用此函数节省大量工作。
25.6 插件配置文件
一个简单的插件可以完全在命令行上配置。但是,如果您需要整合更复杂的默认值,或者如果参数不应出现在进程列表的参数中,则可能需要配置文件。模块 Nagios::Plugin 允许您以简单的方式访问配置文件——一个原因当然是为了鼓励插件程序员使用统一的格式,因为这将大大简化 Nagios 管理员的配置工作,管理员不再需要为每个插件适应不同的格式。
Nagios::Plugin 为模块 Config::Tiny 提供了一个接口。文件格式与 INI 文件格式相对应:
rootproperty=10.0
[math]
pi=3.1415
euler=2.78
一节从方括号内的条目开始,例如 [math]。在此之前的所有内容(在此示例中,变量 root-property) 被称为 root property。指令按照 *`parameter=value`* 的模式给出。以 # 和 ; 开头的行是注释;等于号前后允许有空格,这些空格将被简单地忽略。更多详细信息请参阅 man Config::Tiny 手册页。
通过模块Nagios::Plugin::Config中的Config对象访问配置文件,该对象使用read()方法生成:
$Config = Nagios::Plugin::Config->read('/etc/nagios/myplugin.ini');
my $rootproperty = $Config->{_}->{rootproperty};
my $pi = $Config->{math}->{pi};
my $euler = $Config->{math}->{euler};
同时,read()读取指定的配置文件。如果您省略路径细节并且不带参数调用read(),模块将搜索各种配置文件。搜索路径的详细列表包含在 man 页面man Nagios::Plugin::Config中。
虽然可以想象可能使用单个配置文件为所有插件配置,但由于维护原因,建议为每个插件设置一个单独的配置文件,每个文件都包含一个示例。
现在通过构造在[math]部分中的配置参数被访问
$Config->{math}->{pi};
对于 root 属性,_ 用作部分分隔符:
$Config->{_}->{rootproperty};
第二十六章. 使用即时客户端监控 Oracle
如果特定的任务需要您同时操作 STDIN 并读取外部程序的 STD-OUT,则需要另一个工具,即模块IPC::Open2。
以下章节不会介绍任何完成的插件,而是说明您如何使用示例构建自己的 Oracle 插件,该示例监控 Oracle。对于此 DBMS,已经存在一些插件,例如check_oracle,这是标准 Nagios 插件之一,或 Mathias Kettner 的check_oracle_writeaccess^([299)])。但它们都需要正常的 Oracle 客户端,大多数非 Oracle 管理员在尝试安装它时会感到力不从心。
幸运的是,有一个更简单的解决方案:Oracle 已经提供了一段时间的即时客户端,这大大减少了安装工作:解压 zip 文件,设置变量,安装就完成了——命令行工具sqlplus可以立即使用。后者可以用作插件——就像本章中引入的 Perl 脚本一样,它使用sqlplus向 Oracle 数据库发送请求并评估响应。
26.1 安装 Oracle 即时客户端
即便即时客户端自 Oracle 10g 版本以来才可用,但它同样可以与较旧的 Oracle 数据库(如 8i 或 9i)一起使用。软件以 zip 文件的形式提供,可在 Oracle 主页上找到,^([300)]),前提是您之前已在公司的网站上注册。下载时,您会被问及一些关于出口条件的问题。
尽管该软件免费,但您必须遵守 Oracle 的许可条款。如果您的 Oracle 数据库是基于 CPU 进行许可的,您无需担心其他用户(如 Nagios)的额外访问。
对于sqlplus,您需要两个 zip 文件,^([301)]),instantclient-basic-linux32-10.1.0.3.zip和instantclient-sqlplus-linux32-10.1.0.3.zip。
大约 31 MB 的 instantclient-basic 软件包包含所有必要的库,以及包含的 instantclient-sqlplus,其大小仅为 320 KB,包含简短的文档(READFR0M_IC.htm)以及客户端本身以及另一个库。安装时文件解压缩的位置无关紧要;在此情况下,我们将使用 /usr/local/oracle:
linux:~ # **mkdir /usr/local/oracle**
linux:~ # **cd /usr/local/oracle**
linux:local/oracle # **unzip instantclient-basic-linux32-10.1.0.3.zip**
Archive: instantclient-basic-linux32-10.1.0.3.zip
inflating: instantclient10_1/classes12.jar
...
linux:local/oracle # **unzip instantclient-sqlplus-linux32-10.1.0.3.zip**
Archive: instantclient-sqlplus-linux32-10.1.0.3.zip
inflating: instantclient10_1/READFROM_IC.htm
inflating: instantclient10_1/glogin.sql
inflating: instantclient10_1/libsqlplus.so
inflating: instantclient10_1/sqlplus
这将创建一个子目录 instantclient 10_1,其中包含所有必需的文件。设置两个环境变量后,即时客户端就准备好使用了:
LD_LIBRARY_PATH=/usr/local/oracle/instantclient10_1
SQLPATH=/usr/local/oracle/instantclient10_1
LD_LIBRARY_PATH 确保在运行程序时首先考虑即时客户端目录中的所有共享库,然后再加载系统范围内安装的库。SQLPATH 告诉 sqlplus 在哪里查找文件 glogin.sql。此文件为访问 Oracle 数据库设置了一些默认设置,并且对于我们的目的不需要进行调整。
^([299]) mathias-kettner.de/nagios_plugins.html.
^([300]) www.oracle.com/technology/software/tech/oci/instantclient
^([301]) 除了在此处介绍的基于 Intel x86-32 系统的 Linux 版本外,客户端还适用于 Linux x86-64、Linux Itanium、MAC OS-X、HP-UX(32 位和 64 位,适用于 PA-RISC 和 Itanium)、Solaris SPARC(32 位和 64 位)、Solaris x86-32、AIX 5L(32 位和 64 位)以及 HP Tru64 UNIX。
26.2 建立与 Oracle 数据库的连接
sqlplus 需要以下详细信息才能与数据库建立联系:
sqlplus *user/password@//host/database*
占位符 user 被替换为数据库中存在的用户,密码后面跟着一个正斜杠。在 @// 符号之后是主机名或 IP 地址,然后是 sqlplus 应连接到的数据库名称。在以下示例中,我们将使用数据库 DEMO:
user@linux:~$ **sqlplus wob/**password**@//192.168.1.9/DEMO**
SQL*Plus: Release 10.1.0.3.0 - Production on Sat Aug 13 14:12:52 2005
...
SQL> **quit**
Disconnected from Oracle8i Release 8.1.7.0.0 - Production
JServer Release 8.1.7.0.0 - Production
在连接过程中,您将看到所使用的即时客户端版本(此处为:10.1.0.3.0)以及所使用的 Oracle 数据库版本说明,在本例中为 8.1.7.0.0。quit 命令将终止连接。如果密码错误或用户不存在,Oracle 会明确要求用户再次输入。
26.3 为 sqlplus 的包装插件
要查询 Oracle 数据库,sqlplus 通过标准输入接收适当的 SQL 语句,并通过标准输出接收回复:
user@linux:~$ **echo "select trash from nothing"** |\
**sqlplus -i wob/**password**@//192.168.1.9/DEMO**
select trash from nothing
*****
ERROR at line 1:
ORA-00942: table or view does not exist
开关-s(静默)防止输出版本和版权等信息,并将回复限制在真正有趣的部分。如果查询失败,如上所述,文本仅指出发生的错误。sqlplus本身仅在客户端使用时发生错误时才返回错误状态作为返回值,否则它只返回 OK(命令已执行)。这就是为什么sqlplus不能直接由 Nagios 使用的原因。相反,必须编写一个包装器来围绕实际的查询,该查询评估数据库的回复,在上面的例子中,从ERROR回复生成适合 Nagios 的 CRITICAL 返回值,并添加一个简短的单行回复。
sqlplus原则上可以用任何能够解释文本响应的脚本语言运行。由于这是 Perl 的优势之一,我们将使用这种语言来编写包装器插件——但它也可以用像 Bash 这样的 shell 编写;基本原理始终相同。
26.3.1 包装器的工作原理
包装器插件按照以下步骤构建:
*sql-statement* | sqplus *arguments* | *output_processing*
sqlplus从标准输入接收 SQL 语句,插件从标准输出检索结果。包装器可以围绕(几乎)任何不提供合理返回值但“隐藏”结果的程序构建。
Perl 本身不提供同时检查标准输入和输出的直接方法。但如果没有为这个目的创建特定的模块,Perl 就不是 Perl 了。ICP:: Open2^([302])正好满足这个目的:
use IPC::Open2;
open2(*READFROM, *WRITETO, *program, list_of_arguments*);
print WRITETO "*instruction_via_standard_input*\n";
while (<READFROM>) {
*processed_standard_output*;
}
close(READFROM);
close(WRITETO);
open2例程需要两个文件句柄。它们的名字,WRITETO和READFROM,从包装器的角度来看描述了交互,从open2的角度看,其行为正好相反:open2从其标准输入(WRITETO)读取,并将其输出写入(READFROM),在这里不区分标准输出和错误输出。第三个参数是一个带有完整路径的程序,后面跟任何数量的程序参数,每个参数之间用逗号分隔。
使用WRITETO文件句柄,通过print发送所需的命令。对于sqlplus的每一行都应该在这里结束,并带有正确的行结束符(Perl:'\n'**')。使用**while (**结构,Perl 逐行从标准输出(或错误输出)读取,直到没有更多行。然后**close ()`
使用 IPC::Open2 可能会引发问题:可以想象,所使用的程序(在我们的情况下,sqlplus)可能会阻塞,因为它仅在写入一些内容之后才会继续处理输入的一部分。如果插件仅在所有输入完成后才处理输出,您就会遇到经典的死锁情况。因此,您必须确保在读取和写入时没有阻塞。幸运的是,在我们的简单应用程序中发生这种情况的危险性极小。
26.3.2 详细介绍 Perl 插件
一个好的 Perl 脚本以 use strict 和 use warnings 指令开始。然后必须声明所有变量,并且 Perl 在语法上非常讲究。^([303])
#!/usr/bin/perl -w
use strict;
use warnings;
use IPC::Open2;
my $ipath = "/usr/local/oracle/instantclient10_1";
my $sqlplus = "$ipath/sqlplus";
my $connectstring = "wob/*password*@//192.168.1.9/DEMO";
# -- Set environment variables
$ENV{'LD_LIBRARY_PATH'} = $ipath;
$ENV{'SQLPATH'} = $ipath;
$ipath 包含即时客户端所在的目录路径,而 $sqlplus 则包含程序 sqlplus 的绝对路径。连接字符串已在上方解释。通过哈希 %ENV,脚本设置了两个必需的环境变量。哈希条目通过 Perl 中的 $ENV{'variable name'} 进行引用。
对于此示例,数据库查询语句定义在一个变量中:
# -- SQL-Statement
my $select = "SELECT table_name FROM all_tables ";
$select .= " where table_name = 'VERSION';";
指令 .= 将以下文本追加到 $select 中已存在的文本。因此,SQL 语句从包含所有现有表名的 Oracle 系统表 all_tables 中选择列 table_name,在这种情况下,对表名 VERSION 有额外的限制。
在下一步中,插件使用 open2: 例程打开标准输入和输出。
# -- open2 with error processing
eval {
open2(*READFROM, *WRITETO, $sqlplus, "-s", $connectstring);
};
if ($@) {
die "Error in open2: $!\n$@\n";
}
sqlplus 的 -s 开关防止不必要的连接输出。为了进行适当的错误处理,我们将 open2 命令嵌入到 eval 环境中:由于 open2 如果发生错误会直接终止,否则程序员将没有机会显示一个合理的错误信息。如果需要,可以通过 $@ 在 eval 环境中获取错误输出。die 函数输出此信息并终止 Perl 脚本的执行。
现在剩下的只是发送 SQL 语句,通过 print WRITETO 发送到 sqlplus(之后我们关闭标准输入 WRITETO,以确保安全)并评估输出:
# -- Write instruction
print WRITETO $select;
close(WRITETO);
# -- Process reply
while (<READFR0M>) {
print $_;
}
while <READFR0M> 逐行读取输出。当前行的内容包含在 $_ 中。在您的第一次尝试中,我们建议您显示所有行的输出,使用 print $_;,这样您可以确定一切是否正常工作。
如果是这样,实际逻辑可以扩展:如果所查找的表名存在于数据库中,Oracle 首先显示列标题,然后(通过 hyphens 分隔)显示实际内容,即所查找的表名:
TABLE NAME
--------------------
VERSION
如果这样的表在数据库中不存在,响应是:
no rows selected
如果查询中发生错误,可能是因为缺少所需的列table_name或者表all_tables不存在,那么sqlplus将返回包含关键字ERROR的消息,就像在26.3 A Wrapper Plugin for sqlplus中的初始示例中那样。
现在的while循环看起来是这样的:
# -- Process response
while (<READFR0M>) {
if ( /^VERSION/i ) {
print "OK - Table VERSION found\n";
exit 0;
} elsif (/no rows selected/i) {
print "WARNING - Table VERSION not found\n";
exit 1;
} elsif (/ERROR/i) {
print "CRITICAL - SQL-Statement failed\n";
exit 2;
}
}
close(READFROM);
print "UNKNOWN - unknown response\n";
exit 3;
搜索指令/^VERSION/i包含两个特殊功能:末尾的i确保比较忽略大小写。开头的^确保文本VERSION必须位于行的开头。如果 Oracle 发送的 SQL 语句不正确,错误消息会重复这个开头——但是随后文本VERSION不再位于行的开头。
如果插件在响应中找到所需的表名VERSION,将显示一条 OK 文本消息,并以返回值0终止。
然而,如果数据库返回no rows selected或者甚至ERROR,脚本将向 Nagios 发送相应的回复,并以exit和相应的返回值终止。如果没有三个搜索模式中的任何一个匹配,也必须考虑返回值;否则,脚本将以状态0结束,Nagios 将宣布:“一切正常。”在这里,我们利用UNKNOWN状态,这实际上是为此插件保留的错误处理状态。
带着这些背景知识,编写自己的 Oracle 插件应该不会太难。这里的使用不仅限于读取访问:只要你对相关用户有写入权限,你也可以使用 UPDATE、INSERT 或 DELETE 等 SQL 语句,并评估结果。
^([302]) 该模块包含在 Perl 5.8 的标准包中。
^([303]) 一些程序员,尤其是在开始时,会非常烦恼,因为 Perl 对use strict反应非常小气。没有这条指令,变量不需要声明。有时一个变量名中的单个打字错误就足以让你花费数小时寻找原因,以了解为什么某个位置上的值总是0。
第六部分附录
附录 A. Nagios 配置参数概述
Nagios 包含两个独立的配置文件:nagios.cfg 控制 Nagios 守护进程的操作,cgi.cfg 配置 Web 界面。这两个文件应位于 Nagios 配置目录中,通常为 /etc/nagios。
nagios.cfg 指定了一系列进一步的配置数据库和日志文件,以及各自参数的功能将在以下参考中简要描述。符号 ⇒parameter 指的是当前正在讨论的配置文件中 parameter 的描述。
除非另有指定,否则参数可能具有 0 (禁用) 或 1 (启用) 的值。如果参数有默认值,则相应指定。对于某些路径细节,标准值是在编译时通过选项定义的。在这种情况下列出的值对应于书中使用的路径(见表 1-1,第 40 页)。
对于某些参数没有默认值。如果配置中缺少这些值,Nagios 不会提供相应的功能(例如,如果没有 cfg_dir 参数,Nagios 将忽略存储在单独目录中的对象定义)。
根据您使用的 Nagios 版本,并非所有参数始终都可用。(Nagios 2.x)表示仅限于 Nagios 2.x 的参数,而(Nagios 3.0)表示在 Nagios 3.0 中添加的参数。
A.1 主要配置文件 nagios.cfg
accept_passive_host_checks
被动主机检查的全局开关;值 0 会抑制它们。尽管根据 nagios.cfg 允许被动主机检查,但必须在定义主机对象时明确启用此功能。默认值:
accept_passive_host_checks=1
accept_passive_service_checks
被动服务检查的全局开关。尽管值 1 允许相应的测试,但此功能必须在定义服务对象时明确启用。默认值:
accept_passive_service_checks=1
additional_freshness_latency (Nagios 3.0)
将指定的秒数延迟添加到固定新鲜度间隔。在运行之前,即将到来的新鲜度检查(见 13.4 对被动检查过时信息的反应,第 295 页)将被延迟。示例:
additional_freshness_latency=15
默认值为 0 (无额外延迟)。
admin_email
负责 Nagios 服务器管理的管理员电子邮件地址,您可以通过宏 $ADMINEMAIL$ 访问。如果没有明确配置联系人对象,Nagios 不会向此地址发送电子邮件。示例(无默认值):
admin_email=nagios
admin_pager
传呼机号码、短信号码或用于通过管理员可以联系到的传呼机网关/短信网关的电子邮件地址。可以通过宏 $ADMINPAGER$ 访问。示例(无默认值):
admin_pager=pagenagios
aggregate_status_updates
指定 Nagios 是否将来自主机、服务和其自身程序的状态信息写入 ⇒status_update_interval 时间间隔的块中到 ⇒status_file。值 0 表示 Nagios 在每个事件之后立即更新此文件。默认值:
aggregate_status_updates=1
Nagios 3.0 基本上按照第一种方法工作,这就是为什么参数被省略的原因。
auto_reschedule_checks
使用这个实验性功能,Nagios 将测试均匀地分布在时间周期内,以避免峰值。这可能会显著降低性能,尤其是在 Nagios 已经因为性能不佳而难以保持时间表的情况下,这一点尤其没有用。通常应该关闭此选项。默认值:
auto_reschedule_checks=0
auto_rescheduling_interval
在这里指定的间隔内,Nagios 将在接下来的 auto_rescheduling_window 秒内执行的测试进行分配,以确保负载均衡。默认值:
auto_rescheduling_interval=30
auto_rescheduling_window
在这里指定的接下来几秒钟内将要进行的所有测试都将由 Nagios 重新安排,以便它们在这段时间内均匀分布。指定在未来时间但位于此间隔之外的时间进行的检查(目前)不考虑。这是一个实验性功能;仅在特殊情况下使用!默认值:
auto_rescheduling_window=180
broker_module (Nagios 3.0)
此参数在系统启动时集成指定的事件代理模块(见第 17.1 节“事件代理”,第 376 页)。除了完整路径外,还可以指定模块特定的参数。以下示例集成了 NDO 事件代理模块(另见第 17.4.4 节“在 Nagios 中加载事件代理模块”,第 386 页):
broker_module=/usr/local/nagios/bin/ndomod-3x.o config_file=/etc/nagios/ndomod.cfg
模块特定的参数 config_file 提供了其配置文件的路径。要集成多个模块,只需为每个模块分别指定参数 broker_module。
cached_host_check_horizon(Nagios 3.0)
指定 Nagios 回收主机检查结果的秒数。在此时间框架内,Nagios 不会重复测试,但认为最后一次检查的缓存结果仍然是最新的。这可以节省时间和资源。示例:
cached_host_check_liorizon=30
值 0 会关闭缓存;默认值为 15。此值的大小取决于具体情况。大值可以显著减轻 Nagios 的负担,但同时也存在这些值可能变得过时且不再有效的风险。
cached_service_check_horizon(Nagios 3.0)
与 ⇒cached_host_check_horizon 类似,但 Nagios 仅使用缓存的服务检查结果来处理依赖关系。因此,此参数只有在存在大量服务依赖关系检查时才会对性能产生影响。例如:
cached_service_check_horizon=30
值 0 会关闭缓存;默认值为 15。
`cfg_dir
存放包含对象定义的配置文件的目录。Nagios 会递归地搜索扩展名为 .cfg 的配置文件。其他名称的文件将被忽略,因此您可以将帮助文件放在此目录中,例如,一个 CSV 文件,该文件由脚本自动生成主机定义。要集成单个文件 ⇒cfg_file。此指令可以指定多次(也请参阅 2.1 主配置文件 nagios.cfg,第 55 页)。例如(未设置默认值):
cfg_dir=/etc/nagios/servers
cfg_file
集成一个包含对象定义的单个文件。更多关于这一点的内容请参阅 2.1 主配置文件 nagios.cfg,第 55 页。此指令可以指定多次。例如(未设置默认值):
cfg_file=/etc/nagios/checkcommands.cfg
Nagios 3.0 允许设置相对路径,从包含文件 nagios.cfg 的目录开始。
check_external_commands
启用外部命令的接口。对于被动检查或要通过 Web 界面执行命令时是必要的。更多关于这一点的内容请参阅 13.1 外部命令接口,第 292 页。默认值:
check_external_commands=0
check_for_orphaned_hosts (Nagios 3.0)
从 Nagios 3.0 开始,此参数将主机附加到已经在 Nagios 2.x 中存在的 ⇒ check_for_orphaned_services。
check_for_orphaned_services
如果在一段时间后没有收到服务检查的结果,这被称为 孤儿服务。由于 Nagios 只有在存在结果的情况下才会重新安排服务检查,因此可能存在服务永远不会再次被测试的情况。通常这种情况只会发生在运行中的服务检查被手动从外部终止的情况下。
如果怀疑出现了这样的孤儿服务,您应该将check_for_orphaned_services设置为1以进行调试。然后,如果 Nagios 将相应的错误条目写入日志文件,则可以确认这一点。是否合理很容易在 Web 界面中看到:您可以独立于其状态显示所有服务,并按最后测试时间升序排序。通常,主动检查的执行不应早于normal_check_interval中指定的日期。默认值:
check_for_orphaned_services=0
check_host_freshness
允许在长时间没有检查结果到达时,对被动主机检查进行主动测试。如果 Nagios 认为测试结果过旧,则 ⇒host_freshness_check_interval介入。更多关于新鲜度检查的信息,请参阅 13.4 对被动检查过时信息的反应,第 295 页。默认值:
check_host_freshness=1
check_result_path (Nagios 3.0)
从 Nagios 3.0 开始,检查结果以文件形式缓存的路径。此目录中不应有其他文件,因为 Nagios 会定期清空它。每个 Nagios 实例需要一个单独的目录。示例:
check_result_path=/var/nagios/checkresults
check_result_reaper_frequency (Nagios 3.0)
收割进程在检查结果中聚集,并为 Nagios 处理这些结果。check_result_reaper_frequency定义了这些进程启动的间隔(以秒为单位)。短间隔会增加系统负载;长间隔可能导致 Nagios 调度延迟。示例:
check_result_reaper_frequency=5
该参数替换了 Nagios 2.x 中的 ⇒service_reaper_frequency。
check_service_freslmess
等同于check_host_freshness的服务。Nagios 认为测试结果过旧的时间由参数 ⇒service_freshness_check_interval定义。默认值:
check_service_freslmess=1
child_process_fork_twice (Nagios 3.0)
当执行服务或主机检查时,Nagios 通常启动两个子进程。这不是必需的,但旨在使系统对插件调用崩溃具有更强的鲁棒性。默认:
child_process_fork_twice=1
参数use_large_installation_tweaks (A.1 主配置文件 nagios.cfg) 设置值为0(仅一个子进程);child_process_fork_twice=1激活此功能,尽管use_large_installation_tweaks已设置。
command_check_interval
定义 Nagios 测试外部命令文件(见 13.1 外部命令接口, 第 292 页)新条目的时间间隔。要使此操作发生,必须启用 ⇒check_external_coramands。
简单数字作为值表示由 ⇒interval_leiigth 指定的时间单位(通常为 60 秒,因此 1 代表一分钟)。值 −1 表示 Nagios 尽可能频繁地测试接口。如果数字后面补充(不带空格)单位 s,也可以显式指定秒。
依赖于被动检查的间隔可能不会太大,因为外部命令文件中的操作系统,一个命名管道,通常只能保存 4 KB。默认值:
command_check_interval=-1
command_file
作为外部命令文件的命名管道。它应该只对用户 nagios 和组 nagcmd 可写(另见 13.1 外部命令接口, 第 292 页)。默认值:
command_file=/var/nagios/rw/nagios.cmd
comment_file (Nagios 2.x)
通过 Web 界面指定的 Nagios 存储注释的文件。默认值:
comment_file=/var/nagios/comments.dat
此参数已在 Nagios 3.0 中删除;注释现在存储在文件 status.dat 中。
date_format
Nagios 在 Web 界面中显示或用于日期和时间宏的日期格式。可能的值有 us (*`mm/dd/yyyy hh:mm:ss`*),欧元(*`dd/mm/yyyy hh:mm:ss`*),iso8601 (*`yyyy-mm-dd hh:mm:ss`*),和 strict-iso8601 (*`yyyy-mm-ddThh:mm:ss`*)。默认值:
date_format=us
downtime_file (Nagios 2.x)
保存停机详情的文件,可以通过 Nagios Web 界面为主机和/或服务指定(见 16.3 规划停机时间, 第 359 页)。默认值:
downtime_file=/var/nagios/downtime.dat
此参数已在 Nagios 3.0 中删除;注释现在存储在文件 status.dat 中。
debug_file (Nagios 3.0)
对于 Nagios 2.x,在编译时仍需要激活调试(例如,使用 ./configure --enable-DEBUGALL;见 configure --help)。在 Nagios 3.0 中,这通常可以在 nagios.cfg 中配置。debug_file 定义了调试输出写入的文件。示例:
debug_file=/var/nagios/debug.log
debug_level (Nagios 3.0)
这定义了记录的信息。该参数有以下值,也可以组合使用:
−1 所有信息 |
|---|
0 关闭调试 |
1 函数调用开始/结束 |
2 配置信息 |
4 进程信息 |
8 调度细节 |
16 主机和服务的检查 |
32 消息 |
64 事件代理 |
示例:
debug_level=−1
debug_verbosity(Nagios 3.0)
定义了调试时的详细程度:值0仅提供基本信息,而1提供稍微详细的信息。值2提供更多详细的信息,通常只有开发人员才会感兴趣。默认:
debug_verbosity=1
enable_embedded_perl(Nagios 3.0)
如果已内置,则开启嵌入式 Perl 解释器(附录 G,第 669 页),Nagios 2.x 中内置的解释器始终处于活动状态,而 Nagios 3.0 允许通过此参数设置。示例:
enable_embedded_perl=1
开启解释器,值0关闭它。如果解释器已内置,则默认为1,否则为0。
enable_environment_macros(Nagios 3.0)
Nagios 标准宏,如$HOSTADDRESS$(参见使用环境标准宏,第 631 页)可以在 Nagios 2.x 中作为环境变量访问。在 Nagios 3.0 中,可用的宏数量急剧增加,因此在大型环境中处理它们可能会导致性能问题。默认:
enable_environment_macros=1
值0关闭此机制。
enable_event_handlers
全局切换选项以使用服务和主机检查的事件处理器。更多内容请参阅附录 C,第 619 页。默认值:
enable_event_handlers=l
enable_flap_detection
定义了 Nagios 是否通常能够检测持续变化的状态(状态波动检测,更多内容请参阅附录 B,第 611 页)。默认值:
enable_flap_detection=0
enable_notifications
定义了 Nagios 是否可以发送通知。关闭此功能通常只在分布式安装的中心主机上才有意义,这些主机本身无法生成通知,而是将测试结果转发到中心 Nagios 实例(参见第十五章分布式监控,第 317 页)。默认值:
enable_notifications=l
enable_predictive_host_dependency_checks(Nagios 3.0)
如果提供了相应的时间范围,Nagios 3.x 会缓存主机检查结果⇒cached_host_check_horizon。参数enable_predictive_host_dependency_checks不仅用于决定无法到达的主机的 DOWN 和 UNREACHABLE 状态,还用于主机依赖关系检查,前提是已经定义了一些(参见 12.6.2 特殊情况:主机依赖,第 289 页)。
enable_predictive_service_dependency_checks (Nagios 3.0)
如果此参数启用(值1),服务检查将使用缓存的结果来解决依赖关系,而不是再次执行检查。有关服务依赖关系检查的更多信息,请参见 12.6.1 标准情况:服务依赖,第 285 页。
event_broker_options
Nagios 2.0 中的事件代理作为新接口允许第三方以可加载模块的形式向 Nagios 添加一些功能,例如将测试结果保存到数据库而不是文件中。使用事件代理接口的一个应用程序是 NDOutils(第十七章,从第 375 页)。可能的值是0(关闭)和−1(接受所有代理模块)。默认值:
event_broker_options=0
event_handler_timeout
Nagios 终止尚未完成的事件处理器的超时时间。默认值:
event_handler_timeout=30
execute_host_checks
全局启用/禁用活动主机检查。仅在具有中央 Nagios 实例的分布式环境中才值得关闭,该实例仅接受来自其他 Nagios 服务器的被动结果(参见第十五章,第 317 页)。默认值:
execute_host_checks=1
execute_service_checks
与execute_host_checks类似,但用于服务检查。默认值:
execute_service_checks=1
external_command_buffer_slots (Nagios 3.0)
指定外部命令文件接口(13.1 外部命令接口,第 292 页)可以临时存储的外部命令的最大数量。如果缓冲区不够大,可能会丢失一些结果。默认:
external_command_buffer_slots=4096
free_child_process_memory (Nagios 3.0)
Nagios 通常从内存中清除子进程,但参数use_large_installation_tweaks=1(参见 A.1 主配置文件 nagios.cfg)默认关闭此行为。使用
free_child_process_memory=1
即使设置了use_large_installation_tweaks=1,也可以重新激活清理过程。
global_host_event_handler
定义一个全局主机事件处理器,除了使用event_handler定义的主机特定事件处理器外。为此,主机定义中的全局参数⇒enable_event_handlers以及参数event_handler_enabled都必须启用。Nagios 在执行主机特定事件处理器之前,先执行全局事件处理器,这是一个正常的命令对象。示例(未设置默认值):
global_host_event_handler=*****`name_of_the_command-object`*
global_service_event_handler
服务特定的等效于global_host_event_handler。除了⇒enable_event_handlers之外,服务定义中的参数event_handler_enabled也必须启用。示例(未设置默认值):
global_service_event_handler=*****`name_of_command_object`*
high_host_flap_threshold
主机检查中检测跳变的上限。详细信息请见附录 B, 第 611 页。默认值:
high_host_flap_threshold=30.0
high_service_flap_threshold
服务检查中检测跳变的上限(见附录 B). 默认值:
high_service_flap_threshold=30.0
host_check_timeout
Nagios 在未返回结果的情况下,在多少秒后终止主机检查。默认值:
host_check_timeout=30
host_freshness_check_interval
两次新鲜度检查之间的秒数间隔。默认值:
host_freshness_check_interval=60
host_inter_check_delay_method
控制 Nagios 在重启后如何处理主机检查。一个复杂的程序旨在防止 Nagios 在这种情况下同时执行所有测试,从而过载服务器。可能的值是:s(智能,智能,自动分配主机检查),n(无,所有检查同时开始),d(愚蠢,Nagios 以秒为间隔处理测试),以及以秒为单位的间隔,格式为*`x.xx`*。默认值:
host_inter_check_delay_method=s
host_perfdata_command
一个 Nagios 命令对象,应在每次主机检查后检查性能数据。需要设置⇒process_performance_data参数。
此参数仅在少数情况下有意义,因为 Nagios 仅在必要时执行主机检查,因此间隔非常不规则。如果要在没有模板的情况下处理性能数据(19.1 使用 Nagios 处理插件性能数据, 第 404 页),则使用此参数。示例(未设置默认值):
host_perfdata_command=process-host-perfdata
host_perfdata_file
指定一个文件或命名管道,通过该文件或管道 Nagios 将主机检查的性能数据通过模板机制转发到外部程序(参见 第十九章, 第 403 页)。⇒process_performance_data 必须设置。示例(未设置默认值):
host_perfdata_file=/tmp/host-perfdata
host_perfdata_file_mode
定义如何将数据传递到文件 ⇒host_perf data_file。可能的值是 a (追加 到一个普通文件) 或 w (写入到一个新文件),对于 Nagios 3.0,还有 p (非阻塞写入),这对于管道特别有用。示例(未设置默认值):
host_perfdata_file_mode=a
host_perfdata_file_processing_command
Nagios 命令对象在将主机性能数据传递到 ⇒host_perf data_file 接口之后被调用。该参数仅在模板机制中使用,是可选的。例如,perf2rrd (19.3 使用 Perf2rrd 准备性能数据以供评估, 第 415 页) 有自己的守护进程,它永久地从接口读取数据。示例(未设置默认值):
host_perfdata_file_processing_command=process-host-perfdata-file
host_perfdata_file_processing_interval
如果这个间隔——以秒为单位——大于 0,则属于它的命令(⇒host_perfdata_file_processing_command)将在这个间隔内定期运行。0 确保它不被使用。示例(未设置默认值):
host_perfdata_file_processing_interval=0
host_perfdata_file_template
描述性能数据的输出格式。Nagios 宏和其中包含的格式细节,如 \t (制表符) 或 \n (换行符),在输出中被替换。更多关于模板的使用,请参阅 19.1 使用 Nagios 处理插件性能数据, 第 404 页。示例(未设置默认值):
host_perfdata_file_template=\(TIMET\)\t\(HOSTNAME\)\t\(HOST-EXECUTIONTIME\)\t$HOSTOUTPUT\(\t\)HOSTPERFDATA$
illegal_macro_output_chars
列出在宏替换通知时被丢弃的字符,以避免诸如由 shell 解释等问题。该参数对主机或服务定义中宏的替换没有影响。示例(未设置默认值):
illegal_macro_output_chars=' ˜$&|'"<>
illegal_object_name_chars
指定 Nagios 对象名称中不允许的字符。建议至少指定以下示例中列出的字符(未设置默认值):
illegal_object_name_chars='˜ !$%^&*|'"<>?, () =
interval_length
定义对象定义(如normal_check_interval或retry_check_interval)中时间细节所参照的秒数时间单位。如果interval_length为60秒,则时间指定为5分钟。只有有充分的理由,您才应该更改默认的 60 秒。然而,interval_length对nagios.cfg中的时间参数没有影响。默认值:
interval_length=60
lock_file
指定包含 Nagios 守护进程进程 ID(PID)的 Nagios 守护进程锁定文件。启动/停止操作需要此文件。默认值:
lock_file=/var/nagios/nagios.lock
log_archive_path
Nagios 日志文件的归档目录。评估基于复制到该目录的归档文件。如果删除其中一个文件,则其中包含的信息将丢失。Nagios 仅在启用⇒log_rotation_method参数进行日志轮转时使用该目录。默认值:
log_archive_path=/var/nagios/archives
log_event_handlers
事件处理器操作是否应出现在日志文件中?此参数主要用于查找错误。默认值:
log_event_handlers=1
log_external_commands
Nagios 是否应在日志文件中记录外部命令(见 13.1 外部命令接口, 第 292 页)?默认值:
log_external_commands=1
log_file
中心日志文件。除了错误和问题外,它还保留所有事件。所有历史评估都使用此文件。对于日志轮转,Nagios 提供了一个单独的机制,即⇒log_rotation_method,您不应在此处使用外部程序。默认值:
log_file=/var/nagios/nagios.log
log_host_retries
指定 Nagios 是否应记录由于错误状态而导致的主机检查重复。如果使用的事件处理器(见附录 C, 第 619 页)需要响应软状态,则此选项绝对必要。默认值:
log_host_retries=0
log_initial_states
指定在 Nagios 系统启动时,服务主机启动状态是否应出现在日志文件中。默认值:
log_initial_states=0
log_notifications
定义 Nagios 是否也应将通知记录到日志文件中。默认值:
log_notifications=1
log_passive_checks
指定 Nagios 是否应在日志文件中记录被动检查。默认值:
log_passive_checks=1
log_rotation_method
定义是否应该定期将日志文件⇒log_file保存到存档⇒log_archive_path。日志轮转应始终由 Nagios 本身处理,而不是任何外部程序,否则软件在评估历史数据时将遇到困难。可能的值是n(无存档,不存档)、h(每小时,每个小时的开始)、d(每天,每天 00:00 小时)、w(每周,周六午夜至周日午夜)和m(每月,每月的第一天 00:00 小时)。默认:
log_rotation_method=n
log_service_retries
Nagios 是否应该记录由于软状态错误而重复的服务检查?这在开发事件处理器时进行调试很有用,但否则最好省略。默认值:
log_service_retries=0
low_host_flap_threshold
主机检查的翻转检测的下限。详细信息请参阅附录 B,第 611 页。默认值:
low_host_flap_threshold=20.0
low_service_flap_threshold
与low_host_flap_threshold类似,但用于服务检查。默认值:
low_service_flap_threshold=20.0
max_check_result_file_age (Nagios 3.0)
定义检查结果文件的最大年龄(以秒为单位),Reaper 进程从目录check_result_path中仍然处理这些文件。较旧的文件将被丢弃。例如:
max_check_result_file_age=1800
只有当伴随文件不超过 30 分钟时,这里的检查结果才会被处理。0的值忽略结果文件的年龄。
max_check_result_reaper_time (Nagios 3.0)
限制单个 Reaper 进程的运行时间为指定的秒数。例如:
max_check_result_reaper_time=10
在这里,Reaper 进程在 10 秒后被取消。检查结果中剩余的将由下一个 Reaper 进程处理。
max_concurrent_checks
指定 Nagios 可以同时执行多少个检查。值0允许无限数量。在不利的条件下,通过大于零的值进行限制可能会导致测试未能及时执行。默认值:
max_concurrent_cnecks=0
max_debug_file_size (Nagios 3.0)
将调试文件的大小限制为指定的字节数。例如:
max_debug_file_size=2048000
如果大小超过给定值,Nagios 将添加结尾的.old到文件。如果已存在同名文件,它将被删除。因此,您必须为此指定的大小提供两倍的空间,因为可能同时存在两个文件(带有和没有后缀.old)的最大大小。
max_host_check_spread
重启后,Nagios 应在多长时间间隔(以分钟为单位)内启动所有主机检查?这可以防止所有测试同时执行,从而避免过载 Nagios 服务器。默认值:
max_host_check_spread=30
max_service_check_spread
与max_host_check_spread类似,但用于服务检查。默认值:
max_service_check_spread=30
nagios_group
Nagios 守护进程运行的权限所属的组。默认值(在编译时定义):
nagios_group=nagios
nagios_user
Nagios 守护进程运行的权限所属的用户。默认值(在编译时定义):
nagios_user=nagios
notification_timeout
Nagios 在多少秒后应该放弃发送通知的尝试?一些操作,例如发送短信,需要一定的时间,因为系统首先等待接收者的确认。因此,这个值不应太低。默认值:
notification_timeout=30
object_cache_file
Nagios 启动后存储所有对象的文件。由于 Web 界面使用此文件,因此可以在 Nagios 运行时编辑带有对象定义的正常配置文件,而不会危及 Web 界面的功能。默认值:
object_cache_file=/var/nagios/objects.cache
obsess_over_hosts
在一般情况下,定义是否将主机检查结果转发到中央 Nagios 实例。如果启用此参数,则运行在⇒ocsp_commandis中定义的命令。这在分布式环境中使用;描述可参见第十五章,第 317 页。默认值:
obsess_over_hosts=0
obsess_over_services
在一般情况下,定义是否应将服务检查结果转发到中央 Nagios 实例。如果启用此参数,则使用在⇒ohcp_command中定义的命令。此功能用于分布式环境(见第十五章,第 317 页)。默认值:
obsess_over_services=0
ochp_command
定义强迫症主机处理器,这是一个 Nagios 命令对象,将分布式环境中的所有主机检查结果转发到中央实例(见第十五章,第 317 页)。示例(未设置默认值):
ochp_command=*****`name_of_the_command_object`*
ochp_timeout
定义⇒ochp_command的超时时间。在此指定的时间过后,Nagios 将中止命令的执行。默认值:
ochp_timeout=15
ocsp_command
指定命令对象,作为强迫症服务处理器,应将分布式环境中的所有服务检查结果转发到中央实例(见第十五章,第 317 页)。示例(未设置默认值):
ochp_command=*****`name_of_the_command_object`*
ocsp_timeout
对于⇒ocsp_command的超时时间。在此指定的时间过后,Nagios 将中止命令的执行。默认值:
ocsp_timeout=15
passive_host_checks_are_soft(Nagios 3.0)
通常,被动主机检查的结果总是被视为硬状态。使用
passive_host_checks_are_soft=1
同样的行为也可以应用于主动主机检查。现在可以通过主机定义中的参数max_check_attempts来调节分配软或硬状态。
perfdata_timeout
定义了性能命令(⇒host_perfdata_command,⇒service_perfdata_command,⇒host_perf-data_file_processing_command,或⇒service_perfdata_file_processing_command)应该在多少秒后终止。默认值:
perfdata_timeout=5
precached_object_file(Nagios 3.0)
从 Nagios 3.0 开始,可以在 Nagios 重启之前执行读取和检查配置,并将结果缓存到precached_object_file指定的文件中(参见第 690 页的 H.8 重启)。示例:
precached_object_file=/var/nagios/objects.precache
process_performance_data
开启性能数据的处理。此参数只有在性能数据确实被评估时才应启用。否则,它只会占用 Nagios 服务器的资源。默认值:
process_performance_data=0
resource_file
包含(最多 32 个)$USERχ$ 宏定义的配置文件。$USER1$ 通常指定 Nagios 插件的路径。否则,您可以将密码保存在这里,例如,这些密码不应在正常的 Nagios 配置文件中读取。然后,该文件必须受到所有外部访问的保护,并且只有用户nagios能够读取它。示例(未设置默认值):
resource_file=/etc/nagios/resource.cfg
retain_state_information
确定 Nagios 在关闭时是否将当前状态保存到文件中(⇒state_retention_file),并在启动时再次读取这些状态。默认值:
retain_state_information=0
retention_update_interval
Nagios 应每隔多少分钟将当前状态信息存储在⇒state_retention_file中?如果值为0,则系统仅在 Nagios 关闭时保存信息。必须启用参数⇒retain_state_information。默认值:
retention_update_interval=60
service_check_timeout
Nagios 在多少秒后如果服务检查尚未返回结果,则终止服务检查。默认值:
service_check_timeout=60
service_freshness_check_interval
两次新鲜度检查之间的秒数间隔。默认值:
service_freshness_check_interval=60
service_inter_check_delay_method
控制 Nagios 在重启后如何处理服务检查。一个“智能”的过程应该防止它们同时开始,以避免对服务器造成不必要的负载。可能的值是 s (smart,自动分配),n (no,同时启动所有测试!),d (dumb,检查之间间隔一秒),以及以秒为单位的显式指定间隔,形式为 x. xx。默认值:
service_inter_check_delay_method=s
service_interleave_factor
通过 Nagios 在一段时间内“智能”地分配所有主机的计划检查,防止针对特定主机的检查同时执行(⇒max_concurrent_checks, 598),可能的值是 s (smart,自动分配) 或大于 0 的整数。值为 1 时,Nagios 不执行任何分配;值为 4 时,Nagios 首先计划每第四个服务检查(即从预期检查的数量中,第 1 个、第 5 个、第 9 个等),然后是下一个数字(即第 2 个、第 6 个、第 10 个等),依此类推。测试序列通过 Web 界面中的 服务详情 项显示。如有疑问,默认值可以保持不变:
service_interleave_factor=s
service_perfdata_command
在每次服务检查后运行的 Nagios 命令对象,用于处理性能数据。此要求是必须设置 ⇒process_performance_data。
当性能数据需要在不使用模板的情况下进行处理时使用此参数 (19.1 使用 Nagios 处理插件性能数据, 第 404 页)。示例(未设置默认值):
service_perfdata_command=process-service-perfdata
service_perfdata_file
Nagios 通过模板机制将服务检查的性能数据转发到外部程序的文件或命名管道的路径。这仅在 ⇒process_performance_data 设置的情况下有效。关于处理性能数据的更多信息请参阅 第十九章, 第 403 页。示例(未设置默认值):
service_perfdata_file=/tmp/service-perfdata
service_perfdata_file_mode
定义了数据传递到 ⇒service_perfdata_file 的模式。可能的值有 a (append 向正常文件追加),w (write 写入新文件) 以及在 Nagios 3.0 中 p 也有效 (非阻塞写入),这对于管道很有用。示例(无默认值):
service_perfdata_file_mode=a
service_perfdata_file_processing_command
Nagios 在将服务性能数据传递给⇒service_perfdata_file之后执行的一个命令对象。该参数是可选的,并且仅与模板机制一起使用。只要进一步处理数据的程序,如perf2rrd (19.3 使用 Perf2rrd 准备性能数据以供评估,第 415 页),包含它们自己的永久读取service_perfdata_file的服务,您就可以不定义读取命令来管理。另见第十九章,第 403 页。示例(未设置默认值):
service_perfdata_file_processing_command=process-service-perfdata-file
service_perfdata_file_processing_interval
在多长时间间隔内,定义在⇒service_perfdata_file_processing_command中的命令会定期运行。将值设置为0确保它永远不会被使用。示例(未设置默认值):
service_perfdata_file_processing_interval=0
service_perfdata_file_template
性能数据的输出格式;Nagios 宏和格式细节,如\t(制表符)或\n(换行符),在输出中替换。另见 19.1 使用 Nagios 处理插件性能数据,第 404 页。示例(未设置默认值):
service_perfdata_file_template=$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$
service_reaper_frequency (Nagios 2.x)
Nagios 每隔多少秒处理累积的服务测试结果?默认值:
service_reaper_frequency=10
在 Nagios 3.0 中,相应的参数被称为⇒check_result_reaper_frequency,它不仅影响服务检查,还影响主机检查。
sleep_time
Nagios 在再次在调度队列中搜索要执行的检查之前等待的秒数。默认值:
sleep_time=0.5
state_retention_file
Nagios 在关闭时存储状态信息的文件,以及 Nagios 启动时再次从中读取信息的位置。这仅在⇒retain_state_information参数设置时使用。默认值:
state_retention_file=/var/nagios/retention.dat
status_file
Nagios 保存所有当前状态值的文件路径,以及 Web 界面从中检索它们的位置。默认值:
status_file=/var/nagios/status.dat
status_update_interval
Nagios 应该在什么间隔内将状态值存储在文件⇒status_file中?如果⇒aggregate_status_updates未设置,系统将忽略此参数,并立即将状态值写入此文件(不推荐)。默认值:
status_update_interval=60
temp_file
Nagios 在必要时使用的临时文件路径,并在不再需要时删除。默认值:
temp_file=/var/nagios/tempfile
temp_path (Nagios 3.0)
Nagios 可能存储临时文件的目录。该目录应定期清空。示例:
temp_path=/tmp
translate_passive_host_checks(Nagios 3.0)
确定 Nagios 是否应从拓扑角度将被动主机检查的结果转换为 DOWN 或 UNREACHABLE。默认为“否”:
translate_passive_host_checks=0
被动主机检查通常用于分布式环境,而 Nagios 没有关于这些环境拓扑结构的所有信息。在这种情况下,默认值是合理的。值 1 将转换设置为 DOWN 或 UNREACHABLE。
use_aggressive_host_checking
Nagios 在决定不可达的主机是 DOWN 还是 UNREACHABLE 时做出了一些假设。如果此参数设置为值1,Nagios 在主机检查上非常严格,在某些情况下可能会执行相当多的单独检查。虽然结果将更精确,但这会给系统带来相当大的压力。此参数仅在检测失败的主机存在问题时应设置。默认:
use_aggressive_host_checking=0
use_embedded_perl_implicitly (Nagios 3.0)
自动运行嵌入式 Perl 解释器中的所有 Perl 脚本,前提是脚本本身不包含避免解释器的显式指令。更多关于此内容请参阅 G.2 使用 ePN,第 672 页。
use_large_installation_tweaks(Nagios 3.0)
此参数包含多个设置,旨在提高 Nagios 在大环境中的性能。以下条目将其启用:
use_large_installation_tweaks=1
更多关于此内容请参阅 F.2.7 优化大型 Nagios 环境,第 667 页。
use_regexp_matching
定义是否允许在对象定义中使用通配符*(任意字符)和?(单个字符)。如果您想使用正则表达式,则必须使用use_true_regexp_matching。默认值:
use_regexp_matching=0
use_retained_program_state
Web 界面上参数的更改(enable_notifications、enable_flap_detection、enable_event_handlers、execute_service_checks 和 accept_passive_service_checks)在 Nagios 重启后是否仍然有效?只有当retain_status_informationis启用时才有效。默认值:
use_retained_program_state=1
use_retained_scheduling_info
Nagios 在关闭时是否应保存当前调度信息,以便在重启时再次读取?如果您正在添加大量测试,则可以暂时禁用此参数;否则,保持启用是明智的。默认值:
use_retained_scheduling_info=1
use_syslog
确保所有 Nagios 活动都记录在 syslog 中。默认值:
use_syslog=1
use_timezone (Nagios 3.0)
明确为 Nagios 设置时区。通常,Nagios 使用其运行系统的时区。如果在一个主机上运行多个不同时区的实例,则需要此参数。示例:
use_timezone=Europe/Berlin
指定所需区域信息文件的相对路径,通常在/usr/lib/zoneinfo或/usr/share/zoneinfo。
use_true_regexp_matching
与⇒use_regexp_matching相比,允许根据 POSIX 标准使用真正的正则表达式.^([304]) 默认值:
use_true_regexp_matching=0
^([304]) 请参阅 man 7 regex。
A.2 cgi.cfg中的 CGI 配置
A.2.1 认证参数
通过联系人和联系组,Nagios 将责任分配给用户,从而可以推断出 Web 界面的权限:每个联系人通常只能看到他负责的主机和服务的那些。这就是为什么 Web 登录名必须与联系人名称匹配。
下列参数在一定程度上解决了这一概念。然而,它们并不旨在解决由联系人和 Web 用户名不匹配引起的问题。
cmduse_authentication
确定是否通常需要登录到 Web 界面。与用户名一样,联系名称始终使用;密码的存储方式请参阅 1.5 Web 界面配置,第 47 页。
通常你不应该允许这种认证,但如果确实需要,你应该确保外部命令接口(13.1 外部命令接口,第 292 页)完全关闭。默认:
use_authentication=1
authorized_for_all_host_commands
允许指定的用户通过 Web 界面为所有主机运行命令,而无需属于适当的联系组。示例(未设置默认值):
authorized_for_all_host_commands=nagiosadmin
authorized_for_all_hosts
允许指定的用户查看所有主机信息,无论他们的实际责任如何。示例(未设置默认值):
authorized_for_all_hosts=nagiosadmin.guest
authorized_for_all_service_commands
允许在此定义的用户通过 Web 界面运行所有服务的命令,而不管他们是否属于联系组。示例(未设置默认值):
authorized_for_all_service_commands=nagiosadmin
authorized_for_all_services
允许指定的用户查看所有服务信息,无论他们的权限如何。示例(未设置默认值):
authorized_for_all_services=nagiosadmin,guest
authorized_for_configuration_information
启用指定的用户通过 Web 界面查看所有配置数据。这应该仅限于 Nagios 管理员。示例(未设置默认值):
authorized_for_configuration_information=nagiosadmin,jdoe
authorized_for_system_commands
允许指定的用户通过 Web 界面关闭或重启 Nagios。通常情况下,没有人拥有这种授权。示例(未设置默认值):
authorized_for_system_information=nagiosadmin,theboss,jdoe
authorized_for_system_information
允许指定的用户通过 Web 界面查看 Nagios 进程信息。通常情况下,没有人可以这样做。示例(未设置默认值):
authorized_for_system_information=nagiosadmin,theboss,jdoe
A.2.2 其他参数
action_url_target (Nagios 3.0)
设置操作 URL 的 HTML 标签 target(见 16.4.1 扩展主机信息)。默认值为 blank,将在新窗口中打开:
action_url_target=blank
default_statusmap_layout
定义状态图的布局。可能的值是 0(通过 hostextinfo 对象定义坐标),1(用户必须通过鼠标点击从一个层移动到下一个层),2(压缩树——在图片中分支交错,有些令人困惑),3(平衡树,分支显示得没有交错——更清晰,但需要更多空间),4(圆形表示,Nagios 位于中心:可以直接到达的主机显示在内圈,而其他圈中则位于可以从图形中已进入的主机到达的主机),5(与 4 类似的圆形;主机周围用颜色标记——正常为灰色,DOWN 或 UNREACHABLE 为红色;16.2.4 一目了然的最重要事项:tac.cgi 中的图 A.27 展示了一个示例),以及 6(圆形;主机显示为气球)。这些设置也可以在 Web 界面中更改,无需每次都调整配置文件,这使得尝试新事物变得更加容易。示例:
default_statusmap_layout=5
default_statuswrl_layout
通过 statuswrl.cgi 确定状态页面的 VRML 表示布局。可能的值是 0、2、3 和 4;相应的外观基于同名参数 default_statusmap_layout 的值。示例:
default_statuswrl_layout=4
default_user_name
可能使用网页而不进行身份验证的访客用户名。您应该只在 Web 服务器受到未经授权的访问保护时使用此参数,并且应仔细查看此用户通过联系组分配的权限。示例(未设置默认值):
default_user_name=guest
enable_splunk_integration (Nagios 3.0)
激活 Splunk 工具的集成,Splunk 是日志文件的搜索引擎.^([306])
escape_html_tags (Nagios 3.0)
值 1 禁用插件输出中的 HTML 格式:
escape_html_tags=1
因此,相应的格式化没有效果。默认是 0,这会导致 HTML 格式传递。
lock_author_name (Nagios 3.0)
对于各种 CGI 动作,例如设置确认,指定作者名称。使用设置
lock_author_names=1
这不能再更改(默认是登录用户)。
main_config_file
Nagios 主配置文件。默认值:
main_config_file=/etc/nagios/nagios.cfg
notes_url_target (Nagios 3.0)
设置 Notes URLs 的 HTML 标签 target(见 16.4.1 扩展主机信息)。默认是 blank,它将在新窗口中打开:
notes_url_target=blank
physical_html_path
文件系统中指向 Nagios 文档和图像目录的路径。另见 ⇒url_html_path。默认值:
physical_html_path=/usr/local/nagios/share
refresh_rate
指定网页自动更新的间隔。默认值:
refresh_rate=60
splunk_url (Nagios 3.0)
定义 Splunk 搜索引擎的 URL。示例:
splunk_url=http://127.0.0.1:8000/
参数 ⇒enable_splunk_integration (A.2.2 其他参数) 也必须启用。
statusmap_background_image
状态图显示的背景图像。示例(未设置默认值):
statusmap_background_image=smbackground.gd2
statuswrl_include
用于 VRML 表示的具有自己的 VRML 对象的文件。路径相对于 ⇒html_physical_path 指定。示例(未设置默认值):
statuswrl_include=myworld.wrl
url_html_path
从浏览器的角度来看,Nagios 文档和图像的逻辑路径,从 Web 服务器文档根开始。如果您在此路径中使用 URL,您将被带到 Nagios 启动页面。默认值:
url_html_path=/nagios
**`use_pending_states`** (Nagios 3.0)
如果尚未对此进行检查,主机和服务应在 Web 界面中如何显示?
use_pending_states=1
显示未检查的主机和服务的状态 PENDING;值 0 可以保持不变。
^([305]) 即,不通过父级进行“转移”。
^([306]) www.splunk.com/
附录 B. 快速交替状态:翼尖
如果主机或服务的状态不断变化,Nagios 会向管理员发送大量的问题和恢复消息,这不仅会非常令人烦恼,还会分散管理员对其他可能更紧急问题的注意力。
通过一种特殊机制,Nagios 可以快速识别交替状态,并可以选择性地通知管理员。Nagios 文档将此类交替状态称为状态翼尖,并将它们的检测称为翼尖检测。
这些交替状态涉及主机或服务本身对检测机制没有影响。差异更多地体现在主机和服务检查的性质上:Nagios 定期执行服务检查,因此定期。这样,系统可以持续接收有关当前状态的新信息。从 Nagios 3.0 开始,定期主机检查才有意义(参见第 689 页的 H.7 主机检查的新逻辑)。在 Nagios 2.x 中,主机检查通常仅在需要时进行,因此 Nagios 必须通过其他方式获取适当的信息。
B.1 使用服务进行翼尖检测
要检测交替状态,你需要一个包含上次服务检查期间发生的所有状态的完整列表。为此,Nagios 为每个服务存储最后 21 个测试结果,然后在内存中覆盖每个情况下的最老值。在这 21 个状态中,最多可以发生 20 次变化。
图 B-1 展示了示例。x 轴为每个情况中可能的交替状态编号,从 1 到 20,箭头的头部指示实际发生的交替状态。

图 B-1. Nagios 保存最后 21 个状态以检测频繁交替状态。此服务状态变化了十二次
在指定期间,系统状态的变化次数为 20 次中的 12 次,百分比是 60%。0%表示没有发生任何交替状态,而 100%则意味着服务每次记录时都处于不同的状态。
在确定百分比值时,Nagios 将较旧的状态变化赋予的权重低于较新的变化。因此,在图 B-1 中,它将最旧的状态变化权重设置为1,而最近的权重设置为20,权重每次增加约 0.02,^([307])从而实现线性增长。
在这种情况下,这种加权对最终结果没有太大影响:对于图 B-1,这导致 62.21%(而不是 60%),略有变化,因为第二半部分的状态变化更频繁。如果只有一次状态变化在20,加权将产生最大影响:5%(即可能的 20 次变化中的一次)将变为 5 * 1.2 = 6%。
使用可以定义的阈值值——两个用于服务,两个用于主机——Nagios 定义了服务或主机是否处于“折叠”状态。上下限都指定为百分比。如果检测到的状态变化超过上限,Nagios 将该服务分类为折叠。这会产生一些后果:Nagios 将事件记录在日志文件中,添加一个非永久性注释,^([308])并停止发送与此相关的任何通知。
如果百分比值低于下限,系统将撤销此步骤;也就是说,注释将消失,将再次发送通知,结果也将出现在日志文件中。
B.1.1 Nagios 配置
折叠检测配置在两个位置:在中央配置文件中以及服务对象定义中。在nagios.cfg中,该功能通常通过参数enable_flap_detection来开启,并且在这里也定义了全局限制值,如果没有为该服务定义其他内容,这些值将始终适用:
# /etc/nagios/nagios.cfg
...
enable_flap_detection=1
low_service_flap_threshold=5.0
high_service_flap_threshold=20.0
...
这里为enable_flap_detection设置的值1启用了折叠检测,而0将其关闭。
在这种情况下,下限low_service_flap_threshold位于 5%,上限high_service_flap_threshold限制在 20%。这意味着如果保存的历史记录检测到至少五个状态变化(超过可能的 20 个中的四个),Nagios 将服务分类为折叠。下限的五个百分比相当于一个状态变化。要低于这个值,所有 21 个状态都必须相同.^([309])要低于这个下限,所有 21 个状态都必须相同.^([310])
在服务对象的定义中,您还有机会决定在这种情况下是否需要启用翻动检测。您还可以选择为此服务指定与全局设置不同的阈值值:
define service{
host_name linux01
service_description NTP
...
flap_detection_enabled 1
low_flap_threshold 5.0
high_flap_threshold 20.0
...
}
flap_detection_enabled中的值1启用此服务的功能,而0(默认值)则关闭它。两个限制值low_flap_threshold和high_flap_threshold定义了覆盖全局定义值的限制值。如果它们设置为0或被省略,则应用全局阈值。
从 Nagios 3.0 版本开始,参数flap_detection_options允许在检测状态变化时仅考虑指定的状态。可能的值有o(OK)、w(WARNING)、c(CRITICAL)和u(UNKNOWN)。默认值为
flap_detection_options u,w,c,u
如果值限制为w、c,则只有 WARNING 和 CRITICAL 在检测中起作用;其他状态被忽略。Nagios 3.0 在全局关闭翻动检测时也保存状态,并引入了相应的新消息类型。更多内容请参阅第 687 页的 H.4 快速变化状态。
B.1.2 历史内存和状态变化的时序进展
由于历史记录只保存硬状态和软恢复,x 轴上的部分不能如此容易地按时间顺序分配,因为可能的状态变化之间的间隔并不相等。假设服务对象具有以下定义:
max_check_attempts 3
normal_check_interval 5
retry_check_interval 1
Nagios 在服务从 OK 状态变为 WARNING 状态后,在服务变为硬状态 WARNING(图 B-1 中的状态 1)之前再次检查服务两次。从最后一次返回 OK 的检查以来,总共过去了七分钟^([311]),因为五分钟和六分钟后的两个软状态不包括在历史记录中。
如果下一个服务检查,如图 B-1 所示,再次检测到 WARNING(即这次状态没有变化),那么状态 1 和 2 之间这次只间隔了五分钟。因此,x 轴因此只在特殊情况下以线性形式表示时间——例如,如果没有状态变化发生。
B.1.3 Web 界面中的表示
Nagios 将其归类为摆动状态的服务在 Web 界面中有三个可见点:由 tac.cgi 生成的摘要(16.2.4 一目了然的最重要事项:tac.cgi,第 345 页)和 status.cgi(16.2.1 状态显示的变体:status.cgi,第 334 页),以及由 extinfo.cgi 创建的信息页面(16.2.2 附加信息和控制中心:extinfo.cgi,第 339 页)。
最快到达那里的方式是通过 tac.cgi (图 B-2):在 监控功能 部分标记为 x Services Flapping 的链接会将你带到不断改变状态的服务状态概述。图 B-3 中显示的状态概述也可以直接通过 status.cgi?host=all&style=detail&serviceprops=1024 打开。
serviceprops=1024 描述了 Nagios 将其归类为摆动状态的所有服务。style=detail 提供详细视图(与 overview 相比,如图 B.10 所示 16.2 个体 CGI 程序概述),而 host=all 包含所有主机。

图 B-2. tac.cgi 在 监控功能 部分记录状态变化
在 图 B-3 的状态视图中,一个带有几个水平灰色条移动来去的白色区域揭示了一个摆动服务正在涉及。同时,一个白色话泡表示对此(由 Nagios 自动生成)的评论存在。

图 B-3. 动画水平条表示摆动状态
如果你在状态视图中点击问题服务旁边的摆动图标,extinfo.cgi 会生成关于该服务的附加信息(图 B-4),显示在摆动类别旁边的状态变化百分比,由标记为 YES 的红色条表示。

图 B-4. 百分比状态变化:揭示了硬状态变化的频率,以百分比表示
页面还包含由 Nagios 生成的非永久性注释(图 B-5),指出消息发送已停止,直到服务状态再次稳定。因此,当 Nagios 重启时,它就会消失。

图 B-5. 带有此注释,Nagios 将服务分类为翻页
^([307]) (1.2–0.8)/19=0.0211
^([308]) 在监控系统重启后,非永久性注释会消失,但永久性注释会保留。
^([309]) 如果状态变化最近发生,加权将确保四个状态变化就已经足够超过 20%的限制。
^([310]) 如果在第一半部分发生单个状态变化,加权结果将小于 5%。
^([311]) 5 5+2*1=7
B.2 主机的翻页检测
Nagios 试图以两种方式检测主机的状态变化:在主机检查本身(无论是 Nagios 3.0 的主动检查还是按需检查)以及如果为主机执行了服务检查,并且最近进行了翻页检测。Nagios 下一次执行服务检查以检测状态变化是由所有服务检查间隔的平均值确定的。
从 Nagios 3.0 开始,常规主机检查也不再是必要的,Nagios 的最新版本完全可以不使用它们。出于性能考虑,在 Nagios 2.x 中应尽量避免它们(4.2 需求主机检查与周期性可达性测试, 第 95 页)。通过使用一种技巧仅在需要时执行服务检查,Nagios 弥补了常规主机检查结果缺失的事实。如果至少有一个服务检查返回 OK,Nagios 就会据此得出主机也是可达的并且处于 OK 状态的结论。翻页检测的结果由 Nagios 存储在历史记录中。
同样的翻页检测机制在主机和服务中都使用。所以区别仅在于 Nagios 如何确定对应的数据基础。
是否需要为主机启用翻页检测由中央配置文件nagios.cfg和主机对象定义揭示。全局参数enable_flap_detection,适用于主机和服务,必须设置为1:
# /etc/nagios/nagios.cfg
enable_flap_detection=1
low_host_flap_threshold=5.0
high_host_flap_threshold=20.0
主机阈值参数的名称中包含host,但它们与它们的service等效参数具有相同的效果.^([312])
对于主机对象本身,检测通过flap_detection_enabled 1开启,通过0关闭:
define host{
host_name linux01
...
flap_detection_enabled 1
low_flap_threshold 5.0
high_flap_threshold 20.0
}
可选参数low_flap_threshold和high_flap_threshold允许为主机设置特定的阈值。如果省略这些参数,则使用全局阈值值。
对于服务检查,从 3.0 版本开始,Nagios 在这里还增加了额外的flap_detection_options参数。在主机定义中可能的值有o(正常),d(已关闭)和u(不可达)。只有为参数指定的状态用于翻页检测,如果没有提供此参数,则使用所有可能的状态。
^([312])参见 B.1 使用服务进行翻页检测。
附录 C. 事件处理器
如果主机或服务的状态在正常和错误状态之间交替,你可以使用事件处理器运行任何你想要的程序。例如,如果服务失败,你可以利用这个功能让 Nagios 尝试重新启动它。这为解决小问题提供了机会,而不需要管理员干预。
事件处理器的使用不仅限于自我修复:使用适当的脚本,你同样可以轻松地将当前值或事件本身记录到数据库中。但在 19.1 使用 Nagios 处理插件性能数据中描述了更合适的方法,第 404 页。这里以失败的打印机服务为例,说明了使用事件处理器进行自我修复。在这个例子中使用了打印机服务lpd,但这种方法可以普遍应用于任何有启动停止脚本的服务的场景。
C.1 事件处理器的执行时间
在服务定义中以下参数确保 Nagios 每五分钟在正常情况下测试一次服务,但在出错情况下,每两分钟测试一次:
normal_check_interval 5
retry_check_interval 2
max_check_attempts 4
经过四次测试后,如果结果相同,错误状态会变得难以处理。

图 C-1. Nagios 何时运行事件处理器?
图 C-1 展示了lpd服务从 OK 状态变为 CRITICAL,然后再变回 OK 状态的示例。10 分钟后,测试编号 2 检测到服务不再可用。由此产生的软状态导致 Nagios 以两分钟的间隔更仔细地检查lpd(检查编号 3、4 和 5)。测试编号 5 第四次返回 CRITICAL,导致 Nagios 将其分类为硬状态,并回到正常的五分钟测试间隔。在检查编号 7 中,服务再次运行,状态从 CRITICAL 变为 OK(关于主机的状态,见 4.3 主机和服务的状态,第 96 页)。
Nagios 对软错误状态(在检查编号 2、3、4 中)执行事件处理器,首次出现硬错误状态(在检查编号 5 中),以及在错误后的 OK 状态重置(无论这是硬恢复还是软恢复)。
由于硬错误状态会导致管理员被通知,因此建议将修复尝试移至软错误状态的时间。如果在此时刻成功,管理员就可以避免这些细节。理想情况下,在用户甚至注意到服务失败之前,服务应该已经重新启动。
Nagios 仅在首次出现硬错误状态时才执行事件处理器,这防止了进行修复尝试,但这些尝试最终并没有达到预期的结果(如果尝试成功,则不会发生进一步的硬错误状态)。
C.2 在服务定义中定义事件处理器
虽然 Nagios 为每个事件执行事件处理器,但它不必每次都执行操作。在我们的例子中,处理器应该在第三次软错误状态(检查编号 4)和第一次硬错误状态(检查编号 5)时尝试重置打印机服务,在其他执行时间则什么都不做。
为了这个目的,服务定义被修改如下:
define service{
host_name printserver
service_description LPD
...
**event_handler** **restart-lpd**
...
}
event_handler参数期望一个 Nagios 命令对象,该对象将运行处理器脚本:
define command{
command_name **restart-lpd**
command_line $USER1$/eventhandler/restart-lpd.sh $SERVICESTATE$ $SER
VICESTATETYPE$ $SERVICEATTEMPT$
}
在这个例子中,它被称为restart-lpd.sh,并且并不直接位于 Nagios 插件目录/usr/local/nagios/libexec中,而是在一个名为/usr/local/nagios/libexec/eventhandler的子目录中,正如 Nagios 文档中所建议的。该脚本接收三个宏作为参数:当前状态$SERVICESTATE$(OK、WARNING、CRITICAL 或 UNKNOWN),状态类型$SERVICESTATETYPE$(SOFT或HARD),以及当前(可能重复的)尝试次数$SERVICE ATTEMPT$(例如,如果测试正在进行第三次,则为3)。如果事件处理器用于主机检查,则使用宏$HOSTSTATE$、$HOSTSTATE-TYPE$和$HOSTATTEMPT$。
C.3 处理器脚本
实际处理错误(根据当前事件)由命令定义中定义的脚本处理。因此,为了在这个上下文中集中精力关注本质方面,我们假设lpd安装在 Nagios 服务器本身上。这使得服务可以在本地重启,而无需远程 shell(如 Secure Shell)。
restart-lpd.sh脚本检查确切涉及的事件,使用传递给它的宏,要么什么也不做,要么尝试重启lpd:
#!/bin/bash
# /usr/local/nagios/libexec/eventhandlers/restart-lpd.sh
# $1 = Status, $2 = status type, $3 = attempt
case $1 in
OK)
;;
WARNING)
;;
CRITICAL)
if [ $2 == "HARD" ] || [[ $2 == "SOFT" && $3 -eq 3 ]]; then
echo "Restarting lpd service"
/usr/bin/sudo /etc/init.d/lpd restart
fi
;;
UNKNOWN)
;;
esac
exit 0
case 语句首先检查存在什么状态。只有当它是 CRITICAL 时,脚本才会执行任何操作;对于其他状态,它不会执行任何操作。如果服务处于临界状态,则状态类型必须是HARD或者(||)相应的软状态必须连续发生三次,这样restart-lpd.sh才能使用restart参数执行lpd初始化脚本。^[[313]
脚本以nagios用户的权限执行,该用户既不能停止也不能重启系统服务。这就是为什么使用sudo的原因,它只为启动脚本/etc/init.d/lpd提供临时的root权限,仅限该用户。相应的配置可以在文件/etc/sudoers中找到,但如果编辑它,则必须使用程序visudo而不是标准编辑器(这会在保存时检查配置文件的语法错误):
linux:~ # **visudo**
然后你需要在配置文件中添加以下行:
nagios nagsrv=(root) NOPASSWD: /etc/init.d/lpd
用简单的话说就是:用户nagios可以在nagsrv主机上运行/etc/init.d/lpd命令。命令以root用户身份运行,但不需要密码。
^([313]) 如果你想更深入地了解 Bash 编程,我们可以推荐 Mendel Cooper 的杰出作品高级 Bash 脚本指南 (www.tldp.org/LDP/abs/html)。
C.4 使用事件处理器时需要注意的事项
如果你重新启动一个已经处于软错误状态的服务,只要操作成功,管理员将不会收到任何通知。尽管日志文件记录了重启,但除非你明确搜索日志文件以查找此类事件,否则几乎不会被注意到。这意味着管理员很少会调查服务失败的原因。
因此,你应该记住,消除问题是最好的解决方案,而重启只是次优选择。就像汽车中的安全气囊一样,事件处理器应仅被视为一种额外的安全措施,绝对不能代表处理错误的初级方法。如果你仅在发生硬错误状态时执行重启,管理员将通过通知机制面对问题。
此外,并非每个服务都适合自动重启。在 2.1.17 版本之前的 OpenLDAP 中,通过 slurpd 复制时偶尔会出现问题,留下了损坏的复制文件。尽管复制服务可以重启,但它在短时间内又死了。要真正让复制再次运行,您就必须手动修复复制文件。
您应该始终记住这个例子,并且永远不要完全相信自我修复。在最坏的情况下,反复无思考地重启服务可能会导致数据丢失,这可能只能通过从备份中检索数据来纠正。
附录 D. 宏
宏是 Nagios 汤中的盐,因为没有它们,每个服务都必须为每个主机单独定义,每个命令都必须为每个主机和每个服务单独定义。它们通过围绕它们的美元符号来识别:$macro$。我们将查看使用插件 check_http 的命令定义(见 6.4.2 通过 HTTP 控制 Web 服务器,第 119 页):
define command{
command_name check_http
command_line $USER1$/check_http -H $HOSTADDRESS$ $ARG1$
}
定义包含三个不同的宏:用户宏 $USER1$,在文件 resource.cfg 中定义(见 2.14 资源文件 resource.cfg,第 79 页),以及 $HOSTADDRESS$ 和 $ARG1$。32 个可能的用户宏 $USER1$ 到 $USER32$ 类似于常量,您可以使用它们来记录信息,例如插件目录的路径(通常在 $USER1$ 中)或甚至不应出现在正常配置中的密码。然后,文件 resource.cfg 可能只能由用户 nagios 读取。
第二个宏 $HOSTADDRESS$ 是所谓的 标准宏,在命令运行之前,它被替换为主机定义中的主机地址:
define host{
host_name linux01
address 192.0.2.1
...
}
define service{
host_name linux01
service_description HTTP
check_command check_http!-u test.html
...
}
如果服务 linux0l;HTTP 调用命令 check_http,该命令将从参数 address 中获取主机地址。然而,标准宏不仅可以提供对象定义中参数的内容,如本例所示,还可以提供可以变化的动态值。例如,主机的状态(例如,$HOSTSTATE$)、插件的输出(例如,$SERVICEOUTPUT$)以及系统信息,例如 Nagios 的启动时间或当前时间,或者有关配置或静态值的信息。
$ARGx$ 宏按顺序包含命令行参数。这些参数出现在命令 check_http 后面的感叹号之后。感叹号还用作各个参数之间的分隔符。这样,可以在参数内部使用空格,如本例所示(-u test.html),而不会出现任何问题。
Nagios 可以处理两组其他宏:按需宏和自定义宏。按需宏(见第 632 页的 D.2 按需宏]
并非所有宏都可以在任何地方使用。因此,表格提供了关于每个宏适用上下文的信息。通常,这可以通过一点常识推断出来。服务宏不属于主机检查或主机通知,同样,通知宏在主机或服务检查中也没有位置。当然,必须首先找到的值(例如主机状态)在识别过程中(即主机检查期间)尚未可用。
宏基本上可以在以下操作中使用:用于主机和服务检查、用于主机和服务通知、在运行事件处理器 (附录 C,第 619 页) 或 OCSP/OHCP 命令 (第十五章,第 317 页),以及使用伴随命令处理性能数据时 (19.1.1 模板机制,第 405 页和 19.1.2 使用外部命令处理性能数据,第 407 页)。
D.1.1 主机宏
表 D-1. 选择的宿主机宏
| 宏 | 描述 |
|---|---|
$HOSTNAME$ |
主机定义中来自 host_name 参数的主机名 |
$HOSTALIAS$ |
主机定义中来自 alias 参数的别名 |
$HOSTADDRESS$ |
主机定义参数中的 IP 地址或 FQDN |
$HOSTSTATE$ |
文本形式的状态:UP,DOWN,UNREACHABLE |
$HOSTSTATEID$ |
数值形式的状态:0(UP),1(DOWN),2(UNREACHABLE) |
$HOSTSTATETYPE$ |
HARD,SOFT |
$HOSTOUTPUT$ |
主机检查文本输出的第一行 |
$HOSTLONGOUTPUT$(Nagios 3.0) |
主机检查的长文本,如果提供多行信息 |
$HOSTPERFDATA$ |
主机检查的性能数据 |
表 D-1 记录了与主机相关联的最重要宏。宏 $HOSTNAME$、$HOSTALIAS$ 和 $HOSTADDRESS$ 提供来自主机定义本身的信息,因此它们是静态的。$HOSTSTATEID$ 和 $HOSTSTATE$ 并不给出插件返回值——1(OK)或 2(CRITICAL),而是 Nagios 进行拓扑评估后的结果。$HOSTSTATETYPE$ 定义 Nagios 是否真正完成了检查(硬状态)或检查是否需要重复(软状态)。
D.1.2 服务宏
表 D-2 展示了选定的服务宏。
表 D-2. 选定的服务宏
| 宏 | 描述 |
|---|---|
$SERVICEDESC$ |
服务的名称,从服务定义中的参数 service_description 中获取 |
$SERVICESTATE$ |
文本形式的状态:OK,WARNING,CRITICAL,UNKNOWN |
$SERVICESTATEID$ |
状态的数值:0(OK),1(WARNING),2(CRITICAL),3(UNKNOWN) |
$SERVICESTATETYPE$ |
HARD,SOFT |
$SERVICEOUTPUT$ |
服务检查期间插件文本输出的第一行 |
$SERVICELONGOUTPUT$ (Nagios 3.0) |
服务检查的长文本,如果提供多行输出 |
$SERVICEPERFDATA$ |
服务检查的性能数据 |
D.1.3 组宏
表 D-3 中描述的主机组宏也由 Nagios 为服务和联系人组提供。宏名称中的字符串 HOST 根据相应地替换为 SERVICE 或 CONTACT。
宏 $HOSTGROUPNAME$ 和 $HOSTGROUPNAMES$ 总是与主机相关联。对于等效的 SERVICEGROUP(与服务相关联)和 CONTACTGROUP 宏(与联系人相关联)也是如此。其中 $HOSTGROUPNAME$ 总是返回关联主机的第一个主机组,而 $HOSTGROUPNAMES$ 显示一个完整的、以逗号分隔的列表,列出主机所属的所有主机组。
表 D-3. 选定的组宏
| 宏 | 描述 |
|---|---|
$HOSTGROUPNAME$ |
第一个主组名称 |
$HOSTGROUPNAMES$ |
与关联主机相关的所有主机组的一个以逗号分隔的列表 |
$HOSTGROUPALIAS$ |
主组别名 |
$HOSTGROUPMEMBERS$ |
主机组成员 |
相比之下,宏 $HOSTGROUPALIAS$ 和 $HOSTGROUPMEMBERS$ 指的是主机组。然而,现在没有活动使用主机组作为参考点.^([315]) 因此,这些宏的目的是什么?它们可以作为按需宏实现(参见第 632 页的 D.2 按需宏)。例如,$HOSTGROUPMEMBERS:Linux$ 显示了 Linux 主机组所有成员的列表。
另一方面,如果宏在“正常”环境中运行,Nagios 会识别主机定义中指定的第一个主机组并评估其伴随的值。对于服务和联系组也是如此。
D.1.4 联系宏
列在 表 D-4 中的宏引用了相应联系定义中的所有参数。
表 D-4. 通知所选联系宏
| 宏 | 要读取的参数 |
|---|---|
$CONTACTNAME$ |
contact_name |
$CONTACTALIAS$ |
alias |
$CONTACTEMAIL$ |
email |
$CONTACTPAGER$ |
联系的 pager 参数 |
$CONTACTADDRESSn$ |
六个可能的联系地址之一,其中 n 是介于 1 和 6 之间的数字^([a]) |
|
^([a]) $CONTACTADDRESSn$ 的确切内容由 Nagios 管理员指定。任何内容都可以:其他电话号码、电子邮件地址,甚至是奶奶的电话号码。
|
D.1.5 通知宏
表 D-5 展示了通知所选宏的示例。
表 D-5. 通知所选宏
| 宏 | 描述 |
|---|---|
$NOTIFICATIONTYPE$ |
通知类型(有关值,请参阅文本) |
$NOTIFICATIONRECIPIENTS$ (Nagios 3.0) |
所有收件人的逗号分隔列表 |
$HOSTNOTIFICATIONNUMBER$ |
通知计数器 |
$SERVICENOTIFICATIONNUMBER$ (Nagios 3.0) |
通知计数器 |
$NOTIFICATIONTYPE$ 描述了通知的类型。对于 Nagios 2.x,通知类型是 PROBLEM、RECOVERY、ACKNOWLEDGEMENT、FLAPPING-START 和 FLAPPINGSTOP。Nagios 3.0 还包括 FLAPPINGDISABLED、DOWNTIMESTART、DOWNTIMEEND 和 DOWNTIMECANCELLED。
宏 $NOTIFICATIONRECIPIENTS$ 仅从 Nagios 3.0 版本开始可用;它包含刚刚发送的通知的所有收件人的逗号分隔列表。此版本中还包括两个新宏 $HOSTNOTIFICATIONNUMBER$ 和 $SERVICENOTIFICATIONNUMBER$。这些宏包含最后发送消息的递增编号,这对于升级管理非常重要。在这种情况下,忽略确认消息,以及摆动消息或计划维护期间的消息。一旦主机或服务的状态再次变为正常,此计数器将重置为 0,并且在发生错误时,计数将从开始处重新开始。
D.1.6 用于指定时间和日期的宏
日期宏的输出(表 D-6)。
表 D-6. 用于日期详细信息的选定宏
| 宏 | 示例 |
|---|---|
$LONGDATETIME$ |
Sa 29 Dec 17:23:22 CET 2007 |
$SHORTDATETIME$ |
2007-12-29 17:23:22 |
$DATE$ |
2007-12-29 |
$TIME$ |
17:23:22 |
$TIMET$ |
1198945589 |
$LONGDATETIME$ 输出与 date 程序提供的无参数格式相同的格式。$SHORTDATETIME$ 和 $DATE$ 的示例对应于 date_format=iso8601 设置。使用 date_format=us 值时,日期将写为 12/29/2007。$TIME$ 仅包含时间,而 $TIMET$ 显示纪元时间(自 1970 年 01 月 01 日起经过的秒数)。
D.1.7 统计宏
如果在通知中使用表 D-7,以及enable_environment_macros,A.1 主配置文件 nagios.cfg)。在 Nagios 2.x 中,环境变量无法关闭。
以下示例中,不是直接从外部脚本中访问 Nagios 环境变量,
#!/bin/bash
# badscript
HOST=$NAGIOS_HOSTADDRESS
...
它可以通过以下方式调用,
define command{
command_line $USER1$/badscript
...
}
作为替代,你可以明确地将宏的内容作为参数传递给脚本:
define command{
command_line $USER1$/goodscript $HOSTADDRESS$
...
}
然后你可以在脚本本身中不使用 Nagios 环境变量来管理:
#!/bin/bash
# goodscript
HOST=$1
...
goodscript使用$1从命令行检索相关值。
^([314]) Nagios 2.x: nagios.sourceforge.net/docs/2_0/macros.html;
Nagios 3.0: nagios.sourceforge.net/docs/3_0/macrolist.html
^([315]) 从 Web 界面运行主机组的命令是可能的,但 Nagios 总是将这些解析为每个主机的单个操作。
D.2 按需宏
按需宏——自 Nagios 2.0 以来就存在——引用的内容与标准宏相同。它们之间的细微差别在于它们引用的上下文。而标准宏仅引用当前正在使用的宿主、服务或联系对象,按需宏则允许访问任何外部对象中的值:
$HOSTADDRESS:linux01$
$HOSTSTATE:switch05$
宏与标准宏相同,但它们的名称包括引用的宿主名称。冒号用作分隔符。对于服务,还需要指定服务名称,再次用另一个冒号分隔:
$SERVICESTATE:switch05:PING$
$SERVICESTATE::NRPE$
如果主机字段留空,则宏引用调用宏的主机。例如,如果你通过 NRPE 在主机linux01上检查磁盘使用情况,使用服务Disks NRPE,那么标准宏$SERVICESTATE$将返回服务linux01;Disks的状态,而按需宏$SERVICESTATE::NRPE$将显示服务linux01;NRPE的状态。适当的脚本可以考虑到服务NRPE和基于 NRPE 的检查(如Disks)之间的依赖关系。
对于联系对象,外部参考点是每个情况下的一个联系点:
$CONTACTNAME:gregor$
$CONTACTEMAIL:smith$
此外,还有针对主机、服务和联系组的按需宏,并且在每个情况下,参考点是相关的组。
D.3 用户定义变量的宏
从 Nagios 3.0 开始,你可以在主机、服务和联系定义中指定自己的宏。这些宏在 Nagios 术语中被称为自定义宏,它们被像正常的标准宏一样处理,并且它们的名称以下划线开头,以便更容易识别:
define host {
host_name linux01
...
_NSCLIENT_PORT 12489
_ASSETID 734287
}
define service {
host_name linux01
service_description HTTP
...
_HTTP_PORT 8080
}
define contact {
contact_name wob
...
_DEPARTMENT 41ZBV
}
它们使用前缀对象类型来表示:
$_HOSTNSCLIENT_PORT$
$_HOSTASSETID$
$_SERVICEHTTP_PORT$
$_CONTACTDEPARTMENT$
该宏再次以下划线开头,但在定义中提供的下划线被省略。这很难阅读。如果你想在HOST和NSCLIENT_PORT之间使用下划线作为分隔符,例如,自定义宏必须以两个下划线开头。因此,
define host {
host_name linux01
...
__NSCLIENT_PORT 12489
__ASSETID 734287
}
转换为
$_HOST_NSCLIENT_PORT$
$_HOST_ASSETID$
在自定义宏的定义中,大小写不区分,但在调用宏时,它总是以大写形式书写。除了为主要用于文档目的的内容提供缩写,如ASSETID或DEPARTMENT,此类用户定义宏还可以用来整洁地定义命令。
例如,如果你使用 NS-Client 机制监控 Windows 环境,则在被监控的主机上安装了一个服务,该服务监听特定的端口(20.2.1 NSClient, 第 464 页)。在特定情况下,你将被迫更改标准端口。如果你现在有多个服务器,它们使用不同的端口,你必须告诉插件它在哪个端口上运行查询。
一种方法是将端口也作为每个服务定义的参数包含在内,或者定义一个带有永久存储的备用端口的第二个命令。然而,如果目标系统上的端口现在已更改,则必须修改目标系统的整个服务定义。
一个更优雅的解决方案是将端口,如上所述,存储为主机定义中的自定义宏,并在命令中评估该自定义宏。
这种解决方案遗憾的是只能在 Nagios 3.0 中工作,它在 20.2.5 端口 1248 问题的修正的第 471 页中进行了描述,NRPE 的等效示例可以在 H.2 变量和宏的第 685 页找到。
D.4 宏内容:并非所有内容都允许
许多宏包含的值既不是在 Nagios 配置中定义的,也不是由 Nagios 本身定义的,而是来自外部程序。这些包括记录插件输出的宏($HOSTOUTPUT$、$LONGHOSTOUTPUT$、$HOSTPERFDATA$),以及对应服务的宏。通过 Web 界面,管理员可以通过确认来将值传递给 Nagios,这些值可以从宏$HOSTACKAUTHOR$、$HOSTACKCOMMENT$和等效的服务宏中读取。
为了防止这些宏可能包含的破坏性代码,这些代码可能会触发缓冲区溢出或启用其他恶意行为,Nagios 会移除“危险”的行。这些“危险”的行由参数illegal_object_name_chars定义(A.1 主配置文件 nagios.cfg):
illegal_object_name_chars='~$^&'<>
Nagios 管理员可以更改这些设置,但他必须意识到字符越少,潜在的风险越高。
附录 E. Nagios Web 界面的单点登录
对于 Web 界面的登录,Nagios 使用已经对 Web 服务器进行身份验证的用户,通常是 Apache。原则上,这种身份验证是如何发生的没有区别,但联系人的名称必须与从 Web 服务器传递给 CGI 程序的用户名相匹配。Nagios 在这里对名称约定相当宽容。即使是wob@EXAMPLE.NET或EXAMPLE/wob这样的用户名也是可能的。这是通过单点登录(SSO)实现的,这意味着用户只需要登录一次。理想情况下,所有应用程序都应接受已经完成的身份验证,用户不需要每次都输入密码。
安全专家们一直在忙于讨论单点登录的利弊^([316)),但它在用户中非常受欢迎。因此,我们不会深入讨论安全问题。
单点登录与 Nagios Web 界面的结合意味着,当调用 Nagios CGI 程序时,用户会自动从浏览器进行身份验证,不再需要密码。当然,这里所描述的也可以用于其他 Web 页面——这可能是 NagVis、PNP 或 Wiki。单点登录的使用机会几乎没有限制。
本章描述了 Apache 2 中两个替代模块的使用,这些模块可以启用单点登录场景。作为认证服务器,需要 Windows 2003 上运行的活动目录.^([317]) 在客户端,使用的浏览器必须支持所选的 HTTP 认证程序。微软 Internet Explorer 和 Firefox 都适合这个用途。
Apache 模块 mod_auth_kerb 直接使用 Kerberos,因此可以在仅限 Linux 环境中使用(没有 Active Directory)。由于作者自己没有可用的生产 Kerberos 环境,包括 Linux 客户端,所以我们在这里不会讨论这个话题。如果你在 Linux/Unix 上运行一个完全功能的 Kerberos 环境,你应该很容易修改 mod_auth_kerb 部分以适应你的环境。
Apache 模块 mod_auth_ntlm_winbind 利用 ntlm_auth,这是一个 Samba 3.0 的组件。因此,它需要一个完整的 Samba 安装,服务器必须是 Active Directory 域的成员。
E.1 单点登录的 HTTP 认证
微软已经支持通过 Web 浏览器进行单点登录一段时间了。原始程序基于 (NT 网络管理器 (NTLM),这是一种在网络中使用的协议,例如在登录域或访问网络驱动器时。在这里,客户端发送一个包含客户端主机和域名所谓的 类型 1 消息。服务器回复一个 NTLM 挑战(一个 NTLM 类型 2 消息),客户端通过一个 类型 3 消息完成认证,这个消息反过来发送回服务器,不仅包括客户端名称和域名,还包括用客户端密码加密的挑战。这个程序是微软特有的,从未作为标准发布。尽管如此,
Firefox 能够使用它。NTLM 协议与 HTTP 认证相关的描述也可以在互联网上找到.^([318])
微软将很快用基于 Kerberos 的新认证替换基于 NTLM 的认证。在 Windows Server 2008 中,NTLM 将不再可用于 HTTP 认证,至少在服务器端。
这种技术的继任者已经实际应用了一段时间。它使用了一个名为 通用安全服务应用程序接口 (GSSAPI) 的通用接口。对于 HTTP 认证,以及 GSSAPI,使用了一个名为 SPNEGO (简单保护协商) 的机制,通过该机制进行具体的认证协商。微软在非正式的请求评论 (RFC 4559) 中描述了 HTTP 认证.^([319]) 这也讨论了 NTLM 程序。用于较新变体的 SPNEGO 在 RFC 4178 中描述.^([320])
SPNEGO 流程比 NTLM 认证要短一些,并且更接近 HTTP 认证方法 Basic 和 Digest。首先,客户端使用 GET 命令请求受保护的页面。服务器回复状态码 401 (Unauthorized) 并包含可能的认证流程:
HTTP/1.1 401 Authorization Required
...
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
WWW-Authenticate: Basic realm="Nagios Monitoring"
...
在这个示例中,服务器提供了三种流程的选择:Negotiate 代表基于 Kerberos 的 SPNEGO 流程,NTLM 代表较旧的 NTLM 认证,而 Basic 指的是经典的用户密码方法,其中认证数据以明文形式传输。现在客户端需要决定使用这三种流程中的哪一种。客户端——这里是一个 Microsoft Internet Explorer 6.0 的实例——选择了基于安全的 Kerberos 流程:
**GET /nagios/index.html HTTP/1.1**
...
**Authorization: Negotiate YIIIlwYGKwYBBQUCoIIIizCCCIegJDA..**.
在 HTTP 头部字段 Authorization 之后是关键字 Negotiate,后面跟着 Base64 编码的认证数据。如果成功,
服务器依次回复 HTTP 状态码 200 (OK),并且 HTTP 头部也包含认证数据,^([321]) 客户端会处理这些数据:
HTTP/1.1 200 OK
...
WWW-Authenticate: Negotiate oYGeMIGbo...
如果成功,浏览器将显示它接收到的 HTTP 页面。这里以某种简化的形式展示了协商过程,服务器在接收到客户端的 Authorization 数据包后,可能会发送回 401 状态码 (Unauthorized) 和 WWW-Authenticate 字段,因为需要进一步的身份验证数据。客户端随后发送另一个 Authorization 头部条目,如请求所示。这个过程会重复,直到服务器回复 200 OK。
^([316]) en.wikipedia.org/wiki/Single_sign_on
^([317]) 所描述的场景也可能适用于 Windows 2000,但作者未能进行测试。尽管如此,Windows 2000 和 Windows 2003 在 Kerberos 实现上肯定存在差异,这可能导致需要对这里描述的流程进行调整。
^([318]) www.innovation.ch/personal/ronald/ntlm.html,更详细的信息请见 davenport.sourceforge.net/ntlm.html
^([319]) rfc.sunsite.dk/rfc/rfc4559.html
^([320]) rfc.sunsite.dk/rfc/rfc4178.html
^([321]) 通常,Kerberos 在双方都提供认证,因此服务器也必须向客户端进行自我认证。
E.2 使用 mod_auth_kerb 进行 Kerberos 认证
模块 mod_auth_kerb 将 Apache 集成到现有的 Kerberos 环境中,并允许通过两种方式进行认证:使用 Basic 方法的简单认证或 RFC 4559 中描述的协商过程 SP-NEGO。
两个程序都在 图 E-1 中展示。对于通过协商认证(仅 Kerberos v5),客户端从 Kerberos 服务器获取票据(1),并将其转发给 Web 服务器(2)。Web 服务器随后通过 Kerberos 协议将票据发送给 Kerberos 服务器进行验证(3)。未展示的是,如果认证成功(或失败),Web 服务器对客户端的响应。

图 E-1. mod_auth_kerb 允许通过 Kerberos 和 SPNEGO 进行完全认证。使用 Basic 程序,Web 服务器和 Kerberos 服务器之间的通信也通过 Kerberos 协议进行。
使用 Basic 认证,客户端将用户/密码对以明文形式发送到 Web 服务器(4)。然而,服务器部分通过 Kerberos 协议将认证数据传输到 Kerberos 服务器(5)——这并不改变 Web 服务器和客户端之间的认证没有保护的事实。在这里使用 SSL 加密是至关重要的。Web 服务器本身有一个用于 HTTP 服务的永久票据,以便它首先可以与 Kerberos 服务器通信。
E.2.1 安装
该模块可在 SourceForge 上找到,^([322]) 其中也提供了一些关于安装和少量文档的说明。现代发行版将该模块作为包提供,这有一个优点,即您无需担心其他包的依赖关系——安装程序会自动安装所需的软件。在 Debian "Etch" 中,该模块称为 libapache2-mod-auth-kerb。您应该至少拥有版本 5.3,因为早期版本有一些小错误,尤其是在与 Microsoft Internet Explorer 6.0 一起工作时.^([323])
执行配置需要程序 klist 和 kinit,在 Debian "Etch" 中,这些程序可以在包 krb5-user(而不是 krb5-clients)中找到!关于 Kerberos 本身的一个额外说明:本书中的描述基于麻省理工学院(MIT)的 Kerberos 实现,该实现也用于 Microsoft Windows。
E.2.2 为 Apache 创建服务票据
要参与 Kerberos 流程,Apache 需要一个具有相当特定领域的服务票据:
HTTP/*fqdn*@EXAMPLE.NET
这包括协议,在本例中为HTTP,完全限定域名(FQDN)和域的域。协议和域域必须大写,FQDN 必须与 Web 服务器稍后使用的名称完全匹配。否则,客户端将在协商过程中拒绝工作。下面,将使用nagios.example.net作为 FQDN,域控制器名称为dc01.example.net。
Windows 2003 中的 Kerberos 实现要求服务票据绑定到一个用户。为此,需要设置一个用户(在示例中为webnagios),该用户不需要任何特殊权限。要手动创建票据,需要 Active Directory 环境中的支持工具,最好安装在域控制器上。安装后,切换到支持工具所在的目录,并使用程序ktpass创建服务票据:
C:\> **cd \Programs\Support Tools**
C:\Programs\Support Tools> **ktpass -princ HTTP/nagios.example.net@EXAMP**
**LE.NET -mapuser webnagios@example.net -pass ***** -out c:\temp\webnagios**
**http.keytab**
Targeting domain controller: dc01.example.net
Successfully mapped HTTP/nagios.example.net
to webnagios. Key created. Output keytab to
c:\temp\webnagioshttp.keytab: Keytab version:
0x502 keysize 81 HTTP/nagios.example.net@EXAMPLE.NET
ptype 1 (KRB5_NT_PRINCIPAL) vno 3 etype 0x3 (DES-CBC-MD5)
keylength 8 (0x7fc42302a7342952) Account webnagios has
been set for DES-only encryption.
然后,票据将被复制到一个目录中,最好是 Apache 安装目录中,例如到/etc/apache2/keytabs。
E.2.3 Kerberos 配置
/etc/krb5.conf用作 Kerberos 的配置文件:
# /etc/krb5.conf
[libdefaults]
default_realm = EXAMPLE.NET
[realms]
EXAMPLE.NET = {
kdc = dc01.example.net:88
kdc = dc02.example.net:88
admin_server = dc01.example.net
}
[libdefaults]部分基本上定义了默认值。在这里,重要的是域域必须大写。在[realms]部分,定义了各自的域和相应的服务器。参数kdc描述了充当密钥服务的 Kerberos 服务器(Active Directory 中的所有域控制器),而admin_server是 Kerberos 主服务器(通常是 Active Directory 中的第一个域控制器)。必须能够将这里指定的名称解析为 IP 地址,这可以通过对给定的 FQDN 进行ping测试来验证。
要检查 Kerberos 是否工作,最好使用程序kinit,如果成功,它将从 Kerberos 服务器获取一个有效的票据:
linux:~ # **kinit administrator@EXAMPLE.NET**
Password for administrator@EXAMPLE.NET: ******
kinit需要一个有效的账户作为参数,并且用户名后的域名必须大写。如果密码正确且一切正常,kinit将没有输出。现在可以使用klist显示获取的票据:
linux:~ # **klist**
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: administrator@EXAMPLE.NET
Valid starting Expires Service principal
08/26/07 14:31:47 08/27/07 00:31:49 krbtgt/EXAMPLE.NET@EXAMPLE.NET
renew until 08/27/07 14:31:47
Kerberos 4 ticket cache: /tmp/tkt0
klist: You have no tickets cached
E.2.4 Apache 配置
确保 Apache 在启动时确实加载了模块mod_auth_kerb。通过发行版安装时,模块已经预先配置。在 Debian "Etch"中,可以在文件/etc/apache2/mods-available/auth_kerb.load:中找到相应的LoadModule指令。
LoadModule auth_kerb_module /usr/lib/apache2/modules/mod_auth_kerb.so
对于激活,Debian 使用命令a2enmod,该命令基本上只是在一个目录中放置一个指向配置文件的符号链接/etc/apache2/mods-enabled/。
linux:~ # **a2enmod auth_kerb**
Module auth_kerb installed; run /etc/init.d/apache2 force-reload to enable.
要使用 Kerberos 进行身份验证,您需要修改 Apache 配置文件 /etc/apache2/conf.d/nagios.conf,该文件在 1.5.3 用户身份验证 (1.5.2 SELinux) 中有描述:
<Directory "/usr/local/nagios">
AllowOverride None
Order allow,deny
Allow from all
# -- Authentification
AuthType Kerberos
AuthName "Nagios Monitoring"
KrbAuthRealms EXAMPLE.NET
Krb5Keytab /etc/apache2/keytabs/webnagioshttp.keytab
KrbMethodK5Passwd on
KrbMethodNegotiate on
KrbSaveCredentials off
require valid-user
</Directory>
AuthType 指定应使用 Kerberos。通过 AuthName 为身份验证赋予一个名称,该名称将在 Basic 身份验证中显示。KrbAuthRealms 描述一个或多个域领域,如果有多个,则由空格分隔。
在域控制器上生成的服务票据在 Krb5Keytab 下指定。KrbMethodK5Passwd on 除了协商过程外,还允许使用密码进行简单身份验证,其中浏览器通过 Basic 身份验证将密码发送到 Web 服务器。通过 KrbMethodNegotiate on 开启协商过程,并建立一个完全封闭的 Kerberos 电路。然后 KrbSaveCredentials 决定是否缓存接收到的身份验证数据,以防其他 CGI 应用程序应自动使用这些数据。对于我们来说,这并不是必要的,因此我们使用 off 选项将其关闭。最后,require valid-user 确保只有有效用户才能访问。不需要更详细的配置,例如指定组或单个用户,因为 Nagios 自己管理其用户,只需要认证用户的名称。
E.2.5 Nagios 联系人定义
要在 Nagios 中使用单点登录,现在您只需将联系人的名称修改为新认证的 Web 用户 user@REALM:
define contact{
use template-contact-webuser
contact_name wob@EXAMPLE.NET
alias wob@EXAMPLE
contactgroups admins
email w.barth@example.net
}
联系人定义(见第 70 页的 2.7 定义错误消息接收者:联系人)假设存在一个名为 template-contact-webuser 的模板(见第 75 页的 2.11 模板)。
当修改身份验证及其相关的名称更改时,您还必须修改 CGI 配置文件 cgi.cfg(见第 606 页的 A.2 cgi.cfg 中的 CGI 配置),如果需要明确包含在 authorized_* 参数中的用户。
^([322]) modauthkerb.sourceforge.net/
^([323]) 即使在浏览器启动时使用了协商过程,一段时间后仍会弹出密码窗口,IE 浏览器会切换回基本身份验证。
E.3 使用 mod_auth_ntlm_winbind 进行单点登录
Apache 模块mod_auth_ntlm_winbind使用最初为 Squid 开发的程序ntlm_auth进行身份验证,因此其要求之一是在其中服务器本身是 Active Directory 域成员的 Samba 服务器安装。ntlm_auth使用winbind,因此可以平滑地集成到现有的 Active Directory 中。
该模块提供了三种身份验证方法:NTLM、Negotiate(SPNEGO)和Basic身份验证。在 2007 年夏季,Negotiate 仍然存在问题。该方法最初是为代理开发的,并不完全符合 Web 服务器的需求,因此没有被使用。在撰写本文时,NTLM 和Basic身份验证仍然存在,但在此书出版后可能会发生变化。NTLM 工作得非常好,其中ntlm_auth还允许选择特定的组。但你也应该记住,Microsoft 正在停止在 Windows Server 2008 中使用 NTLM 进行 HTTP 身份验证。
E.3.1 安装
该模块仍然非常新。它的版本号是 0.0.0,只能从 Subversion 源代码或相应的unpacked目录中获取。除了包含的README之外,你还可以在 SourceForge 上找到一些文档。[[324]][[325]][2]
对于安装,你切换到源代码解压的目录:
linux:~ # **cd /usr/local/src/mod_auth_ntlm_winbind**
linux:src/mod_auth_ntlm_winbind # **autoconf**
...
linux:src/mod_auth_ntlm_winbind # **./configure**
...
linux:src/mod_auth_ntlm_winbind # **apxs2 -DAPACHE2 -c -i mod_auth_ntlm_ \**
**winbind.c**
...
autoconf生成一个configure文件,然后运行以查询特定的系统参数。经典的make ; make install通常不起作用;幸运的是,运行 Apache 扩展工具apxs2时不再需要更多的工作,它知道已安装 Apache 环境的精确设置。选项-c编译指定的 C 文件,而-i将结果安装到其他可动态加载的模块所在的目录。
对于 Debian,Apache 配置文件以auth_ntlm_winbind.load文件的形式存在于debian子目录中,当 Apache 启动时会自动加载该模块:
LoadModule auth_ntlm_winbind_module /usr/lib/apache2/modules/mod_auth_nt
lm_winbind.so
此文件被复制到目录/etc/apache2/mods-available,并通过a2enmod auth_ntlm_winbind激活。
对于其他发行版,显示的条目被输入到动态模块加载的文件中,并相应地调整模块目录的路径。然后重新启动 Apache:
linux: # **/etc/init.d/apache2 stop; /etc/init.d/apache2 start**
在大多数情况下,简单的重启是不够的。
E.3.2 准备 Samba
为了使mod_auth_ntlm_winbind能够执行其服务,运行 Apache 的服务器必须作为 Samba 服务器包含在 Active Directory 域中。为此,你需要一个当前的 Samba-3 服务器软件包。最好使用发行版的内置资源进行安装。
对于域成员资格,Kerberos(如第 642 页的 E.2.3 Kerberos 配置 中所述)必须完全配置,并且您还需要使用 kinit 获得的有效的管理员票据来访问域。如果仅使用 Samba 的 Apache 模块,则足够简单的 Samba 配置即可:
# /etc/samba/smb.conf (Minimalkonfiguration)
[global]
workgroup =EXAMPLE
realm =EXAMPLE.NET
security =ads
password server =dc01.example.net dc02.example.net
encrypt passwords =yes
idmap uid =10000-20000
idmap gid = 10000-20000
winbind enum users =yes
winbind enum groups =yes
winbind separator = /
# winbind use default domain = yes
hosts allow =127.0.0.1
workgroup 和 realm 分别对应 NetBIOS 域名和 Active Directory 域的完整域名。对于 realm,再次强调,您必须将名称大写。security=ads 描述了 Active Directory 域的成员资格。对于密码服务器,您至少需要提供一个,最好提供两个域控制器;encrypt passwords = yes 是强制性的。
参数 idmap* 和 winbind enum* 将 Windows 用户和组映射到 Unix 用户和组。对于 winbind separator,您应该选择一个与 Unix 兼容的字符,通常是 /,以分隔域名和用户名,例如 EXAMPLE/wob。如果这导致应用程序出现问题,则可以替换此字符为另一个字符,前提是 Nagios 可以处理它。在这里 hosts allow 只允许来自本地主机的访问。
参数 winbind use default domain 定义了是否应该自动用 workgroup 的默认域替换缺失的域。然后可以在 Basic 认证中省略域。同时,mod_auth_ntlm_winbind 从 HTTP 用户中移除域名。用户根据域成员资格被不同对待:来自外部域的用户被分配到 HTTP 用户 FOREIGN/*****`user`*,而来自同一域的用户只分配到 *`user`*(前面没有域)。如果您只使用单个域,可以将参数设置为 yes,这样您就不再需要担心可能的前缀域。
使用 Samba 命令 net ads join 来实现域访问:
linux:~ # **net ads join -U administrator@EXAMPLE.NET**
administrator's password: ******
Using short domain name - EXAMPLE
Joined 'NAGIOS' to realm 'EXAMPLE.NET'
在成功加入后,您必须重新启动 Samba 和 Winbind:
linux:~ **# /etc/init.d/samba restart**
linux:~ **# /etc/init.d/winbind restart**
您可以使用 wbinfo -t 测试是否一切正常。该命令运行加密的 RPC 调用,只有当服务器确实是域成员时才可能:
linux:~ **# wbinfo -t**
checking the trust secret via RPC calls succeeded
如果您还想稍微玩一下 Winbind,可以使用 wbinfo -u 显示所有用户,使用 wbinfo -g 显示所有组。在启动后首次运行时,需要一段时间两个程序才会显示任何内容。
对于认证,Apache 使用 Web 服务器运行的权限调用程序 ntlm_auth。在 Debian 中,这是来自 www-data 组的 www-data 用户。在他的权限下,ntlm_auth 尝试访问目录 /var/lib/samba/winbindd_privileged/。这必须属于用户 root,并且对于 Apache 运行的用户来说是可读的,否则其他人无法访问该目录:
user@linux:~$ **chgrp www-data /var/lib/samba/winbindd_privileged**
user@linux:~$ **chmod 750 /var/lib/samba/winbindd_privileged**
user@linux:~$ **ls -ld /var/lib/samba/winbindd_privileged**
drwxr-x— 2 root www-data 4096 Aug 26 17:51 /var/lib/samba/winbindd_pri
vileged/
如果访问权限设置不正确,ntlm_auth 将拒绝提供服务。
E.3.3 Apache 配置
模块 mod_auth_ntlm_winbind 只需要在 Apache 配置文件 /etc/apache2/conf.d/nagios.conf 中进行少量条目,因为配置的大部分工作都在 Kerberos 和 Samba 中完成。在 1.5.3 用户认证(第 49 页)中描述的文件 nagios.conf 的更改如下:
<Directory "/usr/local/nagios">
AllowOverride None
Order allow,deny
Allow from all
AuthName "Nagios Monitoring"
# -- NTLM
AuthType NTLM
NTLMAuth on
NTLMAuthHelper "/usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp"
# -- Basic
NTLMBasicAuth on
NTLMBasicAuthoritative on
PlaintextAuthHelper "/usr/bin/ntlm_auth --helper-protocol=squid-2.5-bas
ic"
NTLMBasicRealm "Nagios Monitoring (Basic)"
# -- Negotiate
# AuthType Negotiate
# NegotiateAuth on
# NegotiateAuthHelper "/usr/bin/ntlm_auth --helper-protocol=gss-spnego"
require valid-user
</Directory>
NTLM 认证只需要三个参数:AuthType 选择认证模块,NTLMAuth 激活 NTLM 流程,NTLMAuthHelper 定义 ntlm_auth 的具体调用。这里使用的是协议 squid-2.5-ntlmssp,它最初是为 Squid 设计的。
Basic 认证,其中浏览器以明文形式将用户名和密码发送到 Web 服务器,还需要指定一个 Basic Realm,形式为参数 NTLMBasicRealm。参数 NTLMBasic Authoritative 的值控制是否可以回答失败尝试(用户未找到),或者是否应该查询其他认证模块(如果存在)(off)。
如果它确实无法正常工作,则无论如何都不应配置协商过程。如果 Web 服务器提供与其他过程一起协商,则浏览器将始终选择协商。然后认证将注定失败。
顺便说一下,使用 ntlm_auth 参数 --require-membership-of 可以强制特定组的成员资格。/usr/bin/ntlm_auth--require-membership-of =EXAMPLE/admins 只有当正在认证自己的用户是 admins 组的成员时才返回 OK。分隔符对应于在 smb.conf 中给出的 winbind separator 的值。
E.3.4 定义 Nagios 联系人
在联系人定义中,必须考虑 Samba 配置文件 smb.conf 中的设置 winbind use default domain。如果那里给出 no 值(或者参数根本未给出),则联系人名称将始终由域名(大写)、winbind separator 和用户名组成:
define contact{
use template-contact-webuser
contact_name EXAMPLE/wob
...
}
另一方面,如果 winbind use default domain 设置为 yes,则对于属于 Nagios 服务器所属域的用户,将省略域名。对于外部域的用户,则保留带有前缀域的命名约定。
^([324]) svn co svn://svnanon.samba.org/lorikeet/trunk/mod_auth_ntlm_winbind_mod_auth_ntlm_winbind
^([325]) samba.org/ftp/unpacked/lorikeet/mod_auth_ntlm_winbind/
^([326]) adldap.sourceforge.net/mod_auth_ntlm_winbind.php
E.4 Mozilla Firefox 作为 Web 客户端
在 Windows XP 中配置 Mozilla 网络浏览器非常简单,前提是工作站是 Active Directory 域的成员。使用地址 about:config 您可以在 Firefox 中调用当前配置,并将 negotiate 作为过滤器输入(见图 E-2)。在 network.negotiate-auth.trusted-uris 参数中,您输入所有应自动登录的主机或域名。多个条目由空格或逗号分隔。如果目标主机或其域名不在列表中,Firefox 将肯定会要求用户名和密码。然而,这些信息是以明文形式传输的,因此您应始终优先选择自动登录。

图 E-2. 在 Firefox 的 network.negotiate 设置下启用了通过 SPNEGO/Kerberos 的单点登录。
在 Linux 中,您也可以通过协商过程自动使用 Firefox 进行身份验证。您只需要一个有效的用户票据即可完成此操作。
只要 Linux 工作站登录尚未通过 Kerberos 活跃处理,只需使用 kinit 手动获取票据即可。此外,文件 /etc/krb5.conf 必须按照第 E.2.3 节 Kerberos 配置中从第 642 页所述进行配置。作为普通用户,您可以使用对应 Windows 用户的领域获取票据:
user@linux:~$ **kinit myuser@EXAMPLE.NET**
Password for myuser@EXAMPLE.NET: ******
之后,您可以使用 klist 检查是否真的收到了票据。这通常只有效八小时。时间过期后,您必须获取新的票据,因为没有有效的票据,Firefox 将再次通过用户/密码查询宣布自己。
E.4.1 Firefox 和 NTLM
除了 SPNEGO/Kerberos 过程外,Firefox 也能够通过 NTLM 进行身份验证。为此,你需要在参数network.automatic-ntlm-auth.trusted-uris中输入所需的域或主机。在 Windows XP 中,其他所有操作都会自动进行。
在 Linux 中,通常不可用 NTLM 身份验证,因为 Linux 客户端无法通过 NTLM 在 Active Directory 中验证自身到 Windows 域。但这里也有解决方案:NTLM 授权代理服务器 ntlmaps^([327]) 允许 Linux 客户端参与基于 NTLM 的 Web 身份验证。然而,对此的描述将超出本书的范围。
^([327]) ntlmaps.sourceforge.net/
E.5 微软 Internet Explorer 作为 Web 客户端
微软 Internet Explorer 可以处理 SPNEGO/Kerberos 和 NTLM 身份验证过程。然而,出于安全考虑,Internet Explorer 并不总是立即提供账户数据信息。因此,你应该在安全设置下的受信任站点中输入 Nagios 主机,使用与之后调用时完全相同的 URL(图 E-3)。

图 E-3. 如何在 Internet Explorer 中添加受信任站点的主机
此外,你还应该在自定义级别中检查,是否真的需要为所选级别传输用户名和密码(图 E-4))。更改后,重启 Internet Explorer 并不会造成任何伤害。

图 E-4. 在更新受信任站点时,必须勾选“自动使用当前用户名和密码登录”
附录 F. 优化性能的技巧
用一般术语描述一个性能良好的 Nagios 安装是非常困难的。Nagios 应该立即执行检查,也就是说,它应该对主机和服务检查有很小的延迟时间。这是检查的计划执行时间和实际执行时间之间的差异。如果这是一个小时或更长时间,你当然可以谈论灾难性的性能。另一方面,小于一秒的延迟代表非常好的性能。在这两个极端之间,可接受和不可接受之间的界限有些模糊。
主机和服务的延迟时间可以客观地测量。其他更为主观的印象更难评估。在主机命令行上坚持不懈地工作,系统负载极高,或者当调用 Nagios Web 界面时页面显示时间过长:这些是否被视为性能问题或可以容忍,取决于您的具体要求。如果 Web 界面显示即使是少量服务也需要超过十秒钟,这当然不适合交互式使用。在强大的 4-CPU 机器上,负载为 40 可能不是问题,而在较不强大的系统上,负载为 10 可能已经灾难性。
当然,Nagios 安装的主机系统的容量也会严重影响整体性能。例如,一个非常慢的 RAID 系统,如果 Nagios 需要在短时间内将大量检查结果写入 RAID,并且 NDOUtils 同时想要将所有事件保存到数据库中,那么它可能会显著减慢 Nagios 的速度。如果 Nagios 的延迟值在容许范围内,从 Nagios 的角度来看,就没有理由更改 RAID 系统的配置。
为了更好地区分个体品质,我们在这里引入两个概念。一个性能指标是衡量 Nagios 客观性能的度量。服务主机检查的延迟时间到目前为止是最佳的性能指标。一旦任何问题开始影响 Nagios,这几乎总是直接体现在延迟上。
另一方面,问题指标是可能指向潜在问题的参数,但仅凭其绝对值本身并不能对实际性能做出判断。这些可能是系统测量,例如高 CPU 负载或 Nagios 运行的主机上的永久性交换,或者它们可能是 Nagios 的内部测量,例如外部命令结果的永久性满队列(参见第 666 页的 F.2.6 优先使用被动检查)。
F.1 Nagios 的内部统计
Nagios 在 Web 界面的所谓战术概览中显示性能指标的简短版本,位于右上角(参见 16.2.4 一目了然的最重要事项:tac.cgi 中的图),并通过extinfo.cgi显示一个稍微详细一点的版本(参见 16.2.2 额外信息和控制中心:extinfo.cgi 中的图)。此外,命令行程序nagiostats显示个别性能值或所有数据的摘要。
F.1.1 Nagios 的命令行工具 nagiostats
nagiostats 在安装 Nagios 时自动安装,并且位于主 nagios 程序相同的目录中(在我们的案例中:/usr/local/nagios/bin)。它需要一个参数,即主配置文件 nagios.cfg 的路径,以便在 Nagios 2.x 中显示所有值。(对于 Nagios 3.0,这并非必需。)
user@linux:~$ /usr/local/nagios/bin/nagiostats -c /etc/nagios/nagios.cfg
Nagios Stats 3.0b3
Copyright (c) 2003-2007 Ethan Galstad (www.nagios.org)
Last Modified: 08-30-2007
License: GPL
CURRENT STATUS DATA
-----------------------------------------------------
Status File: /var/nagios/status.dat
Status File Age: 0d 0h 0m 5s
Status File Version: 3.0b3
Program Running Time: 1d 23h 26m 57s
Nagios PID: 8184
**Used/High/Total Command Buffers: 0 / 1 / 4096**
Total Services: 1997
Services Checked: 1997
Services Scheduled: 1995
Services Actively Checked: 1995
Services Passively Checked: 2
Total Service State Change: 0.000 / 30.260 / 0.040 %
**Active Service Latency: 0.000 / 2.233 / 0.361 sec**
Active Service Execution Time: 0.063 / 20.081 / 0.518 sec
Active Service State Change: 0.000 / 7.630 / 0.011 %
Active Services Last 1/5/15/60 min: 308 / 1417 / 1922 / 1944
Passive Service State Change: 26.250 / 30.260 / 28.255 %
Passive Services Last 1/5/15/60 min: 0 / 0 / 0 / 0
Services Ok/Warn/Unk/Crit: 1904 / 61 / 5 / 27
Services Flapping: 2
Services In Downtime: 0
Total Hosts: 166
Hosts Checked: 166
Hosts Scheduled: 166
Hosts Actively Checked: 166
Host Passively Checked: 0
Total Host State Change: 0.000 / 0.000 / 0.000 %
**Active Host Latency: 0.000 / 1.527 / 0.638 sec**
**Active Host Execution Time: 0.066 / 0.537 / 0.155 sec**
Active Host State Change: 0.000 / 0.000 / 0.000 %
Active Hosts Last 1/5/15/60 min: 52 / 148 / 166 / 166
Passive Host State Change: 0.000 / 0.000 / 0.000 %
Passive Hosts Last 1/5/15/60 min: 0 / 0 / 0 / 0
Hosts Up/Down/Unreach: 166 / 0 / 0
Hosts Flapping: 0
Hosts In Downtime: 0
Active Host Checks Last 1/5/15 min: 59 / 209 / 622
Scheduled: 54 / 154 / 475
On-demand: 5 / 43 / 108
Parallel: 59 / 198 / 584
**Serial: 0 / 0 / 0**
Cached: 0 / 12 / 39
Passive Host Checks Last 1/5/15 min: 0 / 0 / 0
**Active Service Checks Last 1/5/15 min: 345 / 2148 / 6342**
Scheduled: 345 / 2148 / 6342
On-demand: 0 / 0 / 0
Cached: 0 / 0 / 0
Passive Service Checks Last 1/5/15 min: 0 / 0 / 0
External Commands Last 1/5/15 min: 0 / 0 / 0
程序首先提供关于评估状态文件和 Nagios 版本的信息。第二段中 Command Buffers 的详细信息更有趣。如果命令缓冲区满了,Nagios 将无法通过外部命令的接口处理命令。所有被动检查都会受到影响(参见 F.2.6 优先选择被动检查)。
接下来的两个块提供了主机和服务检查的值。其中许多纯粹是信息性的。如果右侧包含多个值,例如两个性能指标 Active Service Latency 和 Active Host Latency(此处以粗体显示),而左侧页面没有提供任何解释,那么这些是最小值、最大值和平均值。
您应该关注两个问题指示器 Active Host Execution Time 和 Active Service Execution Time。由于失败的主机导致的检查执行时间过长,无疑会对 Nagios 的性能产生负面影响。假设没有明确配置长超时,插件的标准超时时间为 10 秒,超过 30 秒的平均值相当不祥。尽管服务检查的长时间执行通常对性能没有显著影响,但它们仍然表明某些事情不正常。
最终信息块中关于 Active/Passive Host/Service Checks Last 1/5/15 min 的详细信息提供了描述当前检查结果是如何确定的统计数据。Scheduled 下的详细信息处理 Nagios 定期计划执行的检查,而 On-demand 行处理在考虑当前情况时执行的测试。对于主机,这包括由于主机失败而进行的检查,对于服务,则是由于依赖关系触发的测试。如果可以避免测试,因为已经存在一个相对较新的值,这将在 Cached 行中列出。
对于主机检查,Serial 行中的统计也揭示了根据效率低下的旧主机检查逻辑,串联执行了多少次测试。Parallel 行处理并行执行的主机检查,并显示定期计划和执行的主机检查的值。在 Nagios 3.0 中,主动主机检查可以改善性能。在 Nagios 2.x 中,如果可能的话,你应该尽量不使用它们。主机检查逻辑的改进在第 H.7 节 新的主机检查逻辑中描述,见第 689 页。
Active Service Checks Last 的 5 分钟平均资源提供了 Nagios 活动信息,而不是服务检查的绝对数量:20 分钟检查间隔的 10,000 次服务检查在 5 分钟平均中只产生 2,500 次检查,但 1 分钟检查间隔的 1,000 次检查在 5 分钟平均中则达到 5,000 次。
因此,所有检查的绝对数量并不代表太多。关键问题是 Nagios 每单位时间执行了多少次检查:5 分钟内的 2,500 次服务检查导致平均每秒 8.33 次检查。这意味着 Nagios 每秒启动 8.33 次检查,同时还需要收集和处理 8.33 次其他检查的结果,将任何性能数据转发到外部程序,然后可能还需要等待每个检查完成。如果还使用了 NDOUtils(见第十七章,第 375 页),系统还会将结果传递给事件代理。
确定单个值
nagiostats 还显示选定的值,使用--mrtg 和 --data=*****`variables`* 选项。这里可用的值可以通过运行nagiostats -h: 来查看。
user@linux:~$ **/usr/local/nagios/bin/nagiostats -h**
...
NUMACTSVCCHECKSxM number of total active service checks
occuring in last 1/5/15 minute
...
xxxACTSVCLAT MIN/MAX/AVG active service check latency (ms).
...
在这里,NUMACTSVCCHECKSxM 中的x被替换为所需的分钟数:1、5、15 或 60:
user@linux:~$ **/usr/local/nagios/bin/nagiostats -c /etc/nagios/nagios.cfg\**
**--mrtg --data=NUMACTSVCCHECKS5M**
2195
xxxACTSVCLAT,nagiostats 的行为与此类似;现在xxx被替换为MIN(最小值)、MAX(最大值)或AVG(平均值)。多个目标值由逗号分隔:
user@linux:~$ **/usr/local/nagios/bin/nagiostats -c /etc/nagios/nagios.cfg\**
**--mrtg --data=MINACTSVCLAT,MAXACTSVCLAT,AVGCTSVCLAT**
0
934
203
此处的输出以毫秒为单位,每个值占一行。因此,服务检查的平均延迟时间为 0.203 秒,最大值为 0.934 秒。--mrtg 开关表示此输出主要用于由 MRTG 处理,如下一节所示。当你在编写自己的插件时,性能指标的单个输出也非常有用。我们将在第 F.1.3 节 监控延迟的插件中查看,见第 660 页。
F.1.2 以图形方式显示 Nagios 性能
多路由器流量图(MRTG)^([328])最初是为了以图形形式表示活动网络组件的带宽而开发的。MRTG 始终在图形中显示两个测量值,一个作为绿色区域,另一个作为蓝色线条。在表示网络带宽时,这些通常是入站和出站流量。Nagios 使用 MRTG 来显示nagiostats提供的值。
通常,安装 MRTG 的最佳方式是从您使用的发行版提供的同名软件包中安装。源代码可以在主页上找到.^([329])
MRTG 每五分钟由 cron 运行一次。Debian 包含了现成的 cron 表/etc/cron.d/mrtg;该工具期望其配置在/etc/mrtg.cfg。Debian 提供的文件仅包含两个全局设置:
# Global configuration
WorkDir: /var/www/mrtg
WriteExpires: Yes
WorkDir 指定 MRTG 保存当前图形的目录,WriteExpires 为 Apache 创建额外的 Expire 文件。然而,此参数可以省略。
您只需将这些两行追加到 Nagios 在源代码的./sample-config目录中包含的配置文件mrtg.cfg。
最后,您使用 MRTG 包中包含的程序indexmaker来生成如图 图 F-1 所示的概览页。
linux:~ # **indexmaker /etc/mrtg.cfg > /var/www/mrtg/index.html**

图 F-1. Nagios 性能指标概览页
如果您点击此页上的任何图形,将出现一个详细视图,显示不同时间分辨率的图形,如图 图 F-2(每日、每周、每月和每年)所示。

图 F-2. 服务检查延迟的详细视图
随时间推移检查延迟的图形显示让您可以一眼看出高延迟是孤立事件、趋势的一部分还是永久性问题。如图 图 F-2 所示,周六下午采取的措施已经产生了积极效果(见周度图形)。服务检查的延迟现在低于一秒,不再是 20-80 秒。
伴随的在线文档^([331]) 包含每个图形的更详细链接,以及链接到可用于影响每个图形显示的指标的各个参数的文档。
F.1.3 监控延迟的插件
有什么比让 Nagios 监控其自身性能,并在必要时使用通知系统更合适呢?为此,您可以使用nagiostats查询延迟值,或者使用插件check_mrtg查询通过 MRTG 已收集的性能数据。
我们将在这里选择第一种方法,并将服务检查的延迟时间作为被动检查结果提供给 Nagios。为此目的的 shell 脚本通过 cron 独立于 Nagios 调度运行。在某些情况下,如果 Nagios 调度因为性能问题而完全混乱,Nagios 主动运行的插件可能不会返回任何结果,或者只返回不规律的结果。脚本看起来是这样的:
#!/bin/bash
# Attention: thresholds in milliseconds
WARN=20000
CRIT=60000
TIMESTAMP='date +%s'
CMDFILE='/var/nagios/rw/nagios.cmd'
LATENCY='/usr/local/nagios/bin/nagiostats \
--config=/etc/nagios/nagios.cfg \
--mrtg --data=AVGACTSVCLAT'
if [$LATENCY < $WARN ]; then
STATUS=0; INFO="OK"
elif [$LATENCY < $CRIT ]; then
STATUS=1; INFO="WARNING"
else
STATUS=2; INFO="CRITICAL"
fi
CMD="PROCESS_SERVICE_CHECK_RESULT"
OUTCMD="[%lu] $CMD;*nagios-server*;Service Latency;$STATUS;"
OUTINFO="$INFO Service Latency = ${LATENCY}ms "
OUTPERF="svclat=$LATENCY;$WARN;$CRIT;\n"
printf "${OUTCMD}${OUTINFO}|${OUTPERF}" $TIMESTAMP > $CMDFILE
首先nagiostats确定平均服务延迟的当前值(AVGACTSVCLAT)。脚本将结果保存到变量LATENCY中,并使用WARN和CRIT中的阈值决定是否返回 OK、WARNING 或 CRITICAL。
OUTCMD、OUTINFO和OUTPERF组成了传递给外部命令接口的命令(参见 13.1 外部命令接口,第 292 页)。它以方括号中的时间戳开始。命令PROCESS_SERVICE_CHECK_RESULT后面跟着主机名、服务名Service Latency、状态和实际输出,包括性能数据。在 Nagios 3.0 中,最好省略配置文件的详细内容,使用--config,因为否则nagiostats将开始输出额外的信息行,这只会干扰脚本:
NEW VALUE: /etc/nagios/nagios.cfg
在 Nagios 2.x 版本中,然而,您需要指定配置文件。这样 cron 守护进程才能定期运行脚本,在目录/etc/cron.d中创建一个名为nagios的文件,包含以下行:
*/3 * * * * nagios /usr/local/nagios/libexec/passive/check_svc_latency.sh
> /dev/null
现在所缺少的只是一个定义得当的服务:
# -- service latency check
define service{
host_name *nagios-server*
service_description Service-Latenz
active_checks_enabled 0
passive_checks_enabled 1
check_freshness 0
check_command check_dummy!3!active check, should not happen!
max_check_attempts 3
flap_detection_enabled 0
use template-service
}
host_name和service_description必须与脚本中的对应细节匹配。主动检查被关闭,被动检查被启用。为了确保 Nagios 在某个时刻不会自行执行检查,check_freshness必须设置为0(参见 13.4 对被动检查过时信息的响应,第 295 页)。这里的定义使用在别处定义的服务模板(参见 2.11 模板,第 75 页)。
在重新加载后,Nagios 接受来自脚本的信息并处理它。如果你使用 PNP 来处理性能数据(19.6 使用 PNP 进行平滑绘图,第 446 页),你应该确保 Nagios 包括检查命令的名称(在这种情况下,check_dummy)。如果你想使用不同的名称,你需要在脚本中指定性能标签svclat:
OUTPERF=**"check_svc_latency::check_svc_latency::svclat**=$LATENCY;$WARN; $CRIT;"
PNP 接受以下形式的标签 *`wrapper :: check_command :: label`*,工具从中提取双冒号之间的名称(在这种情况下,check_svc_latency),以便它可以将其用作插件名称。这个技巧通常适用于所有被动检查。
^([328]) www.mrtg.org/
^([329]) www.mrtg.org/
^([330]) 也就是说,扩大 Linux 用于文件系统缓存的空闲内存,以提高 NDOUtils 使用的 MySQL 数据库的 I/O 性能以及整体文件系统访问性能。
^([331]) nagios.sourceforge.net/docs/3_0/mrtggraphs.html
F.2 提高性能的措施
如果性能主观上较差,并且服务检查的延迟始终处于红色区域,那么你需要采取行动。但你应该从哪里开始?尝试解决问题比研究问题更好,而且没有专利配方。通常,如果你在这里和那里进行小的调整,你很快就会失去对整体图景的把握。因此,你应该一次只更改一个参数,并给 Nagios 时间来适应新的状态。根据系统、五分钟平均要执行的检查数量以及其他指标,有时几分钟就足够用nagiostats或 MRTG 注意到变化,但有时即使过了半小时,如果延迟已经积累了一段时间,可能也不够。
以下章节讨论了 Nagios 中可能成为性能问题原因的各种问题区域。
F.2.1 服务检查:尽可能少,尽可能必要
你会用大炮去打麻雀吗?当然不会。除了你通常永远不会打麻雀的事实,即使你不得不这样做,你也永远不会使用像大炮这样的大号武器。同样,你的服务检查间隔的正确选择是什么?为什么每隔 60 秒检查一次硬盘的使用情况,除非你或你的同事会在几分钟内对超过警告阈值的警告做出反应?也许五到十分钟的间隔就能达到同样的效果。而且如果文件系统中存储的数据的典型增长率为每周五%,那么 15 分钟的检查间隔肯定足够了。
如果你每天只安装一次安全补丁,每周只安装一次非关键安全更新,那么每五分钟检查相关版本状态就没什么用了。如果你每两小时才下载一次病毒签名,为什么还要每十五分钟检查一次病毒签名呢?你是在第一次警报后立即反应,还是只有在几个小时没有更新后才反应?
这些不仅仅是学术问题——它们旨在让你思考。当然,有些情况下服务需要每分钟检查一次,例如当涉及到服务等级协议的遵守时,并且停机合同罚款是按分钟计算的。但这并不是说如果十五分钟检查就足够了,还需要每分钟测试其他服务。总之,检查的频率要尽可能少,但又要满足必要的需求。
以平均 5 分钟的检查间隔开始。对于不太关键或静态的服务,可以将间隔延长到 10、15、30 或 60 分钟,甚至更长。只有当绝对必要时,才应该将间隔降低到 5 分钟以下——并且有选择性地为单个检查进行。
F.2.2 智能处理性能数据
在不利的条件下,处理性能数据可能会成为真正的性能杀手。
对于模板机制,其中 Nagios 首先需要格式化性能数据,然后将它们写入文件,并由外部命令定期处理这些文件(19.1.1 模板机制,第 405 页),当调用命令时,内部 Nagios 逻辑会停止。Nagios 期望在程序完成工作后得到确认。如果外部程序需要一些时间来完成其任务,很容易得出结论,直接为每个单独的检查结果调用外部命令(19.1.2 使用外部命令处理性能数据,第 407 页)会对 Nagios 造成相当大的压力。模板机制可以在这里提供缓解。如果每分钟有 400 个检查结果等待(5 分钟平均有 2,000 个检查),而 Nagios 每 30 秒就为模板机制调用外部命令,这将一次性处理大约 200 个结果。虽然这会比只处理单个结果的外部程序花费更长的时间,但不再需要 199 个程序启动。
对于大量的检查结果,这可能仍然不够,因为 Nagios 在这里每 30 秒也会等待外部程序,直到它终止。
为了尽可能缩短这个暂停时间,你可以使用 PNP 的批量模式(19.6 使用 PNP 进行平滑绘图,第 446 页):然后 Nagios 每 30 秒将带有缓存结果的文件移动到特殊目录。这不会造成任何时间损失。处理外部数据的全权责任交给一个 Nagios 不需要控制的守护进程。这些细节在 19.6.4 批量处理性能数据中有描述,从第 452 页开始。
智能处理的一个方面是仅在需要评估的地方记录性能数据。相反的例子可能是将所有检查的性能数据发送到像 NagiosGrapher(19.5 自动化到很大程度:NagiosGrapher,第 426 页)这样的工具,然后在收集守护进程collect2.pl的侧边丢弃不需要的数据。对于所需服务的性能数据处理是通过在服务定义中设置process_perf_data=1来启用的。
F.2.3 避免在解释型语言中使用插件
Nagios 的标准插件主要是用 C 和 C++编写的,这有很好的理由。诚然,通常在脚本语言中编写插件更容易;然而,在解释型语言中的插件每次运行时都会检查正确的语法,然后在运行时进行解释,最后执行。
更重要的是,每次调用此类插件时,都会启动相应的解释器。对于编译型插件,你不必忍受所有这些。语法检查和编译过程只发生一次,结果可以直接执行,无需额外支持另一个程序,比如解释器,这并不小。考虑到在解释型插件的生命周期中会进行数百万次调用,你可能会发现这些资源本可以用于更合理的目的。
这并不是从根本上质疑在一般情况下使用解释型语言。对于某些目的,将插件实现为脚本语言可能更容易。但如果你在 5 分钟的平均时间内仅使用解释型插件执行 5,000 次服务检查,你不需要对此所需的资源感到惊讶。那么简单的 PC 硬件肯定不足以满足 Nagios 服务器。
如果你想使用 Perl 插件,有一个几乎完美的解决方案:Nagios 内置的 Perl 解释器(见附录 G,第 669 页)。尽管不是所有 Perl 插件都能在这个环境下运行,但大多数都可以,这大大减轻了 Nagios 服务器的负担。
F.2.4 优化主机检查
一个不应被低估的性能因素是 Nagios 执行主机检查的方式。有时,无论 Nagios 版本如何,都可能在这里浪费大量时间。
对于主机检查,通常使用check_ping或check_icmp(参见 6.2 使用 Ping 进行可达性测试)。Reaper(这是 Nagios 核心的“收割机”)会定期检索这些结果。
两个参数控制该过程:check_result_reaper_frequency^([332])指定 Reaper 搜索新结果的时间间隔(秒)(参见 A.1 主配置文件 nagios.cfg)。如果间隔增加,延迟时间也可能增加。你应该只将默认的5秒更改为更低的值,并且只有在大量检查等待且 Nagios 从未真正清空检查结果目录的情况下才这样做。
第二个参数,max_check_result_reaper_time,在指定时间后中断活动,这样 Nagios 就不会因为 Reaper 而长时间停滞。这里的默认值是30秒(参见 A.1 主配置文件 nagios.cfg)。
在 Nagios 2.x 中,只有service_reaper_frequency (A.1 主配置文件 nagios.cfg)参数可用,而且 Nagios 不将检查结果以文件形式存储,而是存储在消息队列中。
在这一点上,我们应该提到,Reaper 对性能的影响是有限的。只要您保持两个参数的默认值不变,更改check_result_reaper_frequency参数将无法解决其他地方出现的问题。尽管如此,如果您已经尝试了其他方法但仍然没有头绪,更改此设置无疑是值得的。无论如何,您都应该通过图形方式监控检查的延迟时间。如果没有变化,您应该恢复到默认设置。
^([332]) 在 Nagios 2.x 中,该参数称为 service_reaper_frequency,参见 A.1 主配置文件 nagios.cfg。
F.2.6 优先考虑被动检查
而不是让 Nagios 主动逐个启动每个检查,您还可以使用外部应用程序并将检查结果作为被动检查转发给 Nagios。外部应用程序——即使这只是一个 cron 作业——也能在多个方面减轻 Nagios 的压力,包括调度。Nagios 只需要接受结果并相应地排序。
在许多情况下,您甚至可以更进一步,无需进行常规检查,例如,如果 UPS 在电源故障时发送 SNMP 陷阱,Nagios 将其作为被动检查处理(参见 14.6 应用示例 II:处理 SNMP 陷阱,第 312 页)。
Nagios 会缓存被动检查的结果。默认情况下,有 4096 个所谓的命令缓冲区槽位可用于此。每个缓冲区槽位只接受一个外部命令。如果这个最大值几乎已经达到,您应该肯定地使用参数external_command_buffer_slots(参见 A.1 主配置文件 nagios.cfg)来增加其值,无论您是否有具体的性能问题。有关缓冲区槽位使用的报告由nagio-stats提供;其值最好通过 MRTG 在时间轴上显示(参见 F.1.2 以图形方式显示 Nagios 性能)。缓冲区槽位太少肯定会引起性能下降。
F.2.7 优化大型 Nagios 环境
对于非常大的环境,Nagios 提供了use_large_installation_tweaks参数(A.1 主配置文件 nagios.cfg)。如果此参数设置为1,Nagios 将优化许多可能非常耗时的过程,尤其是在大型环境中。因此,系统无需为子进程显式释放内存,这项任务完全由操作系统负责。
通常,Nagios 通过双叉分支启动检查,以便在插件运行时能够防御崩溃和其他异常。检查不是作为子进程,而是作为孙进程执行的。双叉分支将孙进程的清理工作留给操作系统。如果 Nagios 满足于简单的叉(use_large_installation_tweaks=1),它将不得不负责所有检查进程的清理工作,因为这些进程现在直接作为子进程运行。但作为回报,系统负载会降低,因为只需要启动一半数量的进程。这通常可以提高性能。
作为第三项措施,Nagios 关闭了用于 摘要宏 的环境变量(D.1.7 统计宏)。使这些变量可用需要花费大量时间。
参数 enable_environment_macros (A.1 主配置文件 nagios.cfg) 更进一步——当值为 0 时,Nagios 通常不再将宏的内容作为环境变量提供(参见 D.1.8 关于环境的标准宏)。
这些宏可以在 Nagios 配置中正常使用,但现在外部脚本无法隐式访问它们。关闭这一功能可以节省大量资源,尤其是在大型环境中,而且在许多情况下,根本不需要这些环境变量。
F.2.8 优化 NDOUtils 数据库
NDOUtils 利用将 Nagios 可用的所有信息写入外部数据库的可能性,通过事件代理器(第十七章)。参数 event_broker_options 控制 Nagios 传递哪些数据。默认值为 −1,这意味着传递所有可用信息。
从性能角度来看,这是一个相当糟糕的选择。如果你只需要选择性的数据——例如主机和服务检查的结果——你应该只传递这些信息。其他所有内容都会消耗不必要的资源,并影响性能,而不会带来任何回报。包括参数 event_broker_options 的可能值在内的更多信息,请参阅 17.1 事件代理。
附录 G. 嵌入式 Perl 解释器
Perl 是一种解释型脚本语言。当启动一个 Perl 脚本时,它会被 Perl 解释器读取,检查错误,仅在运行时转换为可执行代码,并最终执行。用 C 或 C++等语言编写的程序在运行前会检查错误,只编译一次,并保存为可以直接运行的二进制代码。在这里,检查和编译过程只发生一次——在程序第一次运行之前——而 Perl 脚本每次运行时都会进行检查和编译。这个过程发生得非常快,但仍然需要时间。
但情况变得更糟——对于每个脚本,无论它有多小,都必须每次都加载这个重量级的 Perl 解释器。这就像,为了将两个数字相加,你需要打开你的电脑,等待登录,然后运行一个电子表格程序,你才能最终输入这两个数字。
如果你想继续使用电子表格,那么电脑必须开启,电子表格程序必须安装并运行,这样你才能输入你的数字。将这个类比应用到 Nagios 脚本中,这意味着 Perl 解释器的一个实例必须已经在 Nagios 服务器上运行——而且最好是这个实例用于所有插件,这样每个插件在被调用时都可以立即执行。这正是 Nagios 中嵌入的 Perl 解释器所做的事情。这项技术并不新颖;Apache 模块mod_perl也是以同样的方式工作的。
然而,嵌入的 Perl 解释器确实有一个小小的缺点:它对 Perl 脚本的要求比正常的 Perl 解释器更多。并不是每个在命令行上运行没有问题的插件都能在嵌入的解释器下工作。这通常是一些小细节的问题。使用这个解释器进行调试非常困难,即使是非常简单的错误,定位它们并相应地调整插件也不是一件容易的事情。但你不应该因此气馁,因为在 Nagios 3.x 中,解释器可以选择性地关闭,而在 Nagios 2.x 中,可以使用一个技巧来绕过它。
关于术语的简要说明:在官方 Nagios 文档中,ePN 代表嵌入 Perl Nagios,即编译了 Perl 解释器的 Nagios。在一般用法中,这个术语指的是集成的 Perl 解释器本身。在这本书中,我们也是这样使用这个术语的。无论如何,使用它都需要 Nagios。
G.1 具备 ePN 功能的插件的要求
如果你使用use strict和use warnings这两个 pragma,许多原始错误从一开始就可以避免:
#!/usr/bin/perl
use strict;
use warnings;
...
use strict 对代码非常精确,并强制预先定义所有变量(例如,my $var;)。use warnings 显示扩展的错误信息,这极大地简化了查找导致错误的行或语句。对于 5.6 版本之前的 Perl,use warnings 不存在,你必须使用 -w 开关,例如在脚本的第一个行:
#!/usr/bin/perl -w
...
关于语法的详细信息可以在 man 3perl strict 和 man 3perl warnings 中找到,以及互联网上相应的 Perldoc 页面.^([333])
为了更好地理解以下说明,你必须了解两件事。一方面,插件只被加载到解释器中一次,因此初始化序列仅在第一次运行时显式执行。另一方面,解释器将 Perl 代码嵌入到其他 Perl 代码中。因此,插件代码的结束并不是执行此插件的完整 Perl 代码的结束。因此,有时会生成不期望的副作用,你应该注意以下提示:
如果可能,尽量避免使用 BEGIN!
在一个 BEGIN 语句中,你通常包括初始化值或由于某种原因应该在代码的其他部分之前执行的语句。ePN 只在插件第一次执行时运行此部分。每次调用插件时都必须执行的语句将毫无意义。因此,最好完全省略 BEGIN 部分。
定义一个明确的退出代码!
正常的 Perl 脚本总是以退出代码 0 结束(除非你明确指定退出代码)。在 ePN 中这不起作用,因为脚本代码之后还有其他代码运行。尽管这样的插件在命令行上运行时(没有 ePN)会返回 OK,但在 ePN 中它们返回 UNKNOWN。
尽量避免使用 __DATA__ 或 __END__ 部分!
这两条指令都明确终止了 Perl 代码的执行。然而,在 ePN 中并非如此。因此,你必须省略此类指令。例如,你可以在 __DATA__ 部分使用 Here 指令:
my $data = <<DATA;
a 1 30
b 2 40
c 7 80
...
DATA
不要误用词法变量作为全局变量!
词法变量,如 my $value,定义了局部所需的值。因此,你应该不要直接从子程序中访问这些值。相反,将这些值作为全局值存储:
use vars qw($value);
更好的做法是将变量作为引用传递:
$result = &mysub( \$value );
终止所有操作和函数!
嵌入式 Perl 解释器也会在一些小细节上出现问题。以一个例子来说明,考虑将 POD 文档集成到脚本中(参见 25.2 Perl 在线文档,第 566 页):通常文档部分会用 =cut 来结束。在 Perl 脚本末尾,Perl 会确保一个隐式的结束,这样如果脚本末尾没有用 =cut 结束的文档部分,在命令行上就不会有问题。但是 ePN 会附加 Perl 代码到这个部分,所以省略 =cut 总是会导致错误。
这种错误模式也出现在其他上下文中,因此你应该养成总是显式清理的习惯。如果插件打开了一个文件,它也必须显式关闭它。
Nagios 在线文档^([334]) 和 mod_perl 用户指南^([335]) 提供了更多信息。对于仅与 ePN 相关的错误,包含的迷你版本很有帮助,并在 G.3 测试工具 new_mini_epn 页 674 中描述。
^([333]) perldoc.perl.org/strict.html 和 perldoc.perl.org/warnings.html
^([334]) nagios.sourceforge.net/docs/3_0/epnplugins.html
^([335]) perl.apache.org/docs/1.0/guide/
G.2 使用 ePN
为了使用嵌入式 Perl 解释器,这个特性必须编译到 Nagios 中。这适用于 Nagios 2.x,但对于 Nagios 3.0,你必须在主配置文件 nagios.cfg 中设置参数。此外,Nagios 3.0 允许每个单独的 Perl 插件激活或关闭嵌入式 Perl 解释器。
G.2.1 编译 ePN
解释器在 configure 调用期间集成,使用开关 --enable-embedded-perl。在 Nagios 2.x 中,你还应该使用选项 --with-perlcache,这确保了解释器缓存已加载的脚本,如果再次运行它们,则会加快速度。如果指定了 --enable-embedded-perl,Nagios 3.0 会隐式设置此选项。
在 Nagios 2.x 中,缓存有一个缺点:在某些情况下,Nagios 不会识别对 Perl 脚本后来所做的更改。这里唯一的补救措施是重新加载或重启 Nagios。在开发系统中,该系统仅用于开发或测试插件,不使用缓存当然是有意义的。然而,在生产 Nagios 系统中,缓存的好处不容忽视。在 Nagios 3.0 中,Perl 解释器会考虑脚本的更改,并在需要时重新加载这些更改。
G.2.2 nagios.cfg 中的解释器特定参数
从 Nagios 3.0 开始,主配置文件nagios.cfg中的参数确定是否使用嵌入式 Perl 解释器:
# /etc/nagios.cfg
...
enable_embedded_perl=1
use_embedded_perl_implicitly=1
...
enable_embedded_perl=1启用了解释器的通用使用,而值0将其关闭。第二个参数用于微调。use_embedded_perl_implicitly=1会自动为每个插件打开解释器,前提是插件本身不包含任何其他指令(参见下一节)。值0暂时关闭 ePN,然后每个插件必须自行决定是否使用它。
G.2.3 在每个插件的基础上禁用 ePN
在 Nagios 3.0 中,参数use_embedded_perl_implicitly被补充了一个可以在每个插件中设置的指令:
#!/usr/bin/perl -w
# nagios: -epn
...
文本# nagios: +epn或-epn必须出现在前十条线中。使用+epn时,插件将在 ePN 环境中执行,而使用-epn则不会。这个插件中的明确细节具有最高优先级。只有当缺少指令时,Nagios 3.0 才会使用参数use_embedded_perl_implicitly。
在许多情况下,现有的 Perl 插件将在 ePN 中工作。因此,我们建议使用设置use_embedded_perl_implicitly=1。对于引起问题的插件,你可以使用-epn显式关闭解释器的使用。
在 Nagios 2.x 版本中,没有选项可以在运行时或在插件中切换嵌入式解释器的开关。一旦它被编译进 Nagios,它就始终处于激活状态。但是,在定义命令时,你可以通过在实际命令行前加上/usr/bin/perl作为前缀来使用一种解决方案:
define command{
command_name check_disk
command_line **/usr/bin/perl** $USER1$/check_disk.pl $ARG1$
}
因此,对于插件check_disk.pl,每次运行插件时都会启动正常的 Perl 解释器,而 ePN 则被绕过。
G.3 测试工具new_mini_epn
在其源代码中,Nagios 包含了两个模拟 ePN 环境的实用工具,这大大简化了错误搜索:mini_epn和较新的new_mini_epn。它们的行为与 ePN 并不完全相同,但这只涉及少数几个特殊场景。一般来说,以下规则适用:如果一个 Nagios 插件在 mini 解释器中无法运行,那么在 ePN 中也无法运行。
这两个程序位于源代码的子目录./contrib中,并且不会自动安装。如果你想使用它们,请运行
linux:nagios/contrib **# make mini_epn**
...
linux:nagios/contrib **# make new_mini_epn**
...
但在任何情况下都不应该运行make install!。此目录中的 Makefile 没有考虑路径的默认值,可能会更改/bin和/var等目录的访问权限。程序必须在包含文件p1.pl的目录中执行。在 Nagios 的基本安装过程中,它被复制到/usr/local/nagios/bin,因此这两个程序也被复制到那里:
linux:nagios/contrib **# cp mini_epn new_mini_epn /usr/local/nagios/bin/**.
在 ./contrib 目录本身中有一个过时的 p1.pl,不应使用。Nagios 安装的最新版 p1.pl 位于源代码的主目录中。
为了运行迷你解释器,您需要以用户 nagios 的身份切换到目录 /usr/local/nagios/bin 并不带参数运行程序:
user@linux:nagios$ **~cd /usr/local/nagios/bin**
user@linux:nagios$ nagios/bin**./new_mini_epn**
plugin command line:
您将被带到简单的命令行,您可以在其中运行插件。您应该始终包含插件的完整路径:
plugin command line: **/usr/local/nagios/libexec/check_file_age -f /etc/hosts**
embedded perl plugin return code and output was: 2 & FILE_AGE CRITICAL:
/etc/hosts is 3718127 seconds old and 2671 bytes
迷你解释器显示返回代码,以及 & 字符之后的插件实际输出。
如果一个迷你解释器没有找到错误,您应该尝试使用另一个,因为在这种情况下它可能会有不同的反应。此外,您应该始终以 Nagios 运行的用户权限运行解释器(在这本书中是 nagios),以排除从开始就存在访问权限问题。
迷你解释器像其大哥一样缓存已执行的插件,并且在运行时不会意识到对插件所做的任何更改。如果您对插件进行了更改,您应该重新启动迷你解释器,否则您可能会在错误的位置徒劳地寻找错误。
附录 H. Nagios 3.0 的新特性
Nagios 3.0 相比 2.x 版本带来了一系列的改进和创新.^([336]). 其中许多改进在外观上并不明显,配置也几乎相同;通常 Nagios 3.0 也会使用一个功能正常的 Nagios-2.x 配置启动。所有新的配置参数都不是绝对必要的。
一些参数已被重命名,Nagios 3.0 在启动时会抱怨配置中包含的某个参数已被删除,然后将其设置为合理的值。对象 hostextinfo 和 service-extinfo 被认为是过时的,但仍然可以使用,至少在 3.0 版本中。
除了配置之外,内部逻辑在很多地方也得到了改进。例如,运行主机检查方式的变化导致性能显著提高,尤其是在非常大的安装中。
H.1 对象定义的变化
Nagios 3.0 现在允许在指定检查和通知间隔时使用浮点小数。新参数 check_interval =2.5,取代了 normal_check_interval,表示 Nagios 将每两个半时间单位执行一次检查。时间单位本身由主配置文件 nagios.cfg 中的 interval_length 定义(参见 A.1 主配置文件 nagios.cfg)。默认为 60 秒,check_interval 的 2.5 对应 150 秒。
H.1.1 host 对象
别名在 Nagios 3.0 中不再是绝对必要的。如果主机定义中缺少此细节,则自动使用主机名。host对象可以从 3.0 版本开始使用以下选项:
define host {
...
display_name *display_name*
contacts *contacts*
first_notification_delay *number*
flap_detection_options o,d,u
notification_options d,u,r,f,s
initial_state o,d,u
retry_interval *number*
...
}
display_name
定义一个替代名称,该名称应在 Web 界面和其他未来的用户界面中显示。Nagios 3.0 的 CGI 程序尚未使用此参数。默认值为host_name。
contacts
Nagios 3.0 现在允许在主机定义中直接指定单个联系人。到目前为止,您只能在此处输入联系人组,因此您必须首先为每个单个联系人定义一个特定的联系人组。您仍然可以使用联系人组,并可以与单个联系人一起指定它们。
first_notification_delay
延迟发送第一条通知(以 Nagios 时间单位发送,由新参数interval_length定义;参见 A.1 主配置文件 nagios.cfg)。通常 Nagios 在错误变为硬状态后立即发送通知。为了仅在经过一段时间后才发送第一条通知,您之前必须使用升级机制(参见 12.5 升级管理,第 282 页)。现在可以通过参数first_notification_delay更轻松地完成此操作。
flap_detection_options
使用flap_detection_options,可以排除某些翻转检测状态(附录 B,第 611 页)。
可能的值是o(OK)、u(UNREACHABLE)和d(DOWN)。如果您使用flap_detection_options o排除 OK 状态,Nagios 将只考虑 UNREACHABLE 和 DOWN 之间的变化。
notification_options
如果指定了新值s,则 Nagios 将在维护间隔(参见 16.3 计划停机时间,第 359 页)开始、结束或取消时发送通知。
initial_state
设置主机的初始状态。通常 Nagios 假设这是 UP(initial_state o)。d 将初始状态设置为 DOWN,u 设置为 UNREACHABLE。
retry_interval
如果max_check_attempts大于 1,则活动主机检查将在多少时间单位后重复?有关主机检查的新功能的更多信息,请参见 H.7 主机检查的新逻辑。
扩展主机信息
对象hostextinfo和serviceextinfo被认为是过时的,但 Nagios 3.0 仍然评估这些对象。在检查配置以及重启时,Nagios 会发出相应的警告。以后的 Nagios 版本将不再支持此对象类型。
Web 接口的附加信息(见第 363 页的 16.4.1 扩展主机信息中可以找到有关定义时间周期的更多信息,该部分位于第 74 页。
H.1.6 依赖描述
对象hostdependency和servicedependency有一个新参数称为dependency_period,它定义了依赖的有效时长。指定一个timeperiod对象作为值。如果此参数缺失,依赖在时间上不受限制:
define hostdependency {
dependency_period *timeperiod_name*
...
}
define servicedependency {
dependency_period *timeperiod_name*
...
}
所说的同一主机依赖性也是新的;这些是servicedependencies,它们引用同一主机。在这种情况下,参数dependend_host_name被简单地省略:
define servicedependency {
host_name linux
service_description Disk_Usage
dependent_service_description NRPE
...
}
因此,Disk_Usage服务依赖于同一主机上的NRPE服务。
如果将参数host_name替换为hostgroup_name,可以为整个主机组定义相同的依赖关系。在 Nagios 2.x 中这是不可能的。如果你定义了dependent_hostgroup_name,该组中所有主机的Disk_Usage服务将依赖于这些主机上的所有NRPE服务,这在许多情况下都是不利的。
H.1.7 升级对象
与主机和服务定义一样,从 Nagios 3.0 开始,也可以通过contacts指定个别联系人而不是整个联系人组来进行主机和服务升级,以代替:
define hostescalation {
contacts *contact*
...
}
define serviceescalation {
contacts *contact*
...
}
H.1.8 继承
在 Nagios 2.x 中,已经可以定义对象模板以及实际对象继承模板的属性。Nagios 3.0 现在允许多重继承,并且还可以选择性地抑制继承。在以下示例中,两个模板host_generic_t和host_site_t被主机linux01继承:
define host {
name **host_generic_t**
register 0
#
check_period 24×7
max_check_attempts 3
check_interval 10
retry_interval 2
...
hostgroups ALL_HOSTS
}
define host {
name **host_site_t**
register 0
#
check_interval 5
retry_interval 1
...
parents switch01
hostgroups HAMBURG
}
define host {
host_name linux01
use **host_site_t,host_generic_t**
...
parents **null**
hostgroups **+LINUX**
}
check_interval 和 retry_interval 参数在两个模板中都有定义。在这种情况下,使用的是首先定义的模板(host_site_t),结果如下所示:
define host {
host_name linux01
check_period 24×7
max_check_attempts 3
check_interval 5
retry_interval 1
...
hostgroups **HAMBURG,LINUX**
}
两个检查间隔都源自模板 host_site_t。对于 parents 的 zero 值会抑制继承;模板中定义的值不会传递,并且参数不会被设置。
同样新的是可以将指定值与模板中的值结合起来的选项。在 hostgroups 中的加号会传递模板中的值并添加指定的值。直到现在,继承的值会被对象完全覆盖。然而,模板中的默认值只能与对象中指定的值结合,这些值是包含文本形式列表的标准参数(例如,hostgroups、servicegroups、contact_groups)。
对于在升级中的 contact_groups,还有一个加号的额外变体。如果包含的升级对象没有定义可以继承属性的联系组,则使用伴随的主机(对于主机升级)或服务定义(对于服务升级)。三个参数 contact_groups、notification_interval 和 notification_period 会自动由服务对象从主机对象继承,因此在那里定义不再是必需的。
Nagios 包含的在线文档使用一个更复杂的示例来描述多重继承.^([337])
^([336]) 参见 nagios.sourceforge.net/docs/3_0/whatsnew.html。
^([337]) localhost/nagios/docs/objectinheritance.html
H.2 变量和宏
你可以在 host、service 和 contact 对象中定义自己的变量。这些变量的名称总是以下划线开头,并且像普通变量一样继承:
define host {
host_name linux01
use host_site_t,host_generic_t
...
**_NRPE_PORT** 5666
}
变量 _NRPE_PORT 通过 $_HOSTNRPE_PORT$ 访问,这意味着对象类型(HOST、SERVICE 或 CONTACT)在下划线后添加。这有点不幸,因为它更难阅读。创建的宏可以在其他地方使用,例如在命令的定义中:
define command {
command_name check_nrpe
command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -p $_HOSTNRPE_PORT$
-c $ARG1$
}
宏允许访问配置数据、状态和检查结果。在 Nagios 3.0 中,包含当前状态发送的通知数量的宏 $NOTIFICATIONNUMBER$ 已被移除。它已被主机和服务特定的宏 $HOSTNOTIFICATIONNUM-BER$ 和 $SERVICENOTIFICATIONNUMBER$ 替换。
可用宏的列表已经大幅增长。例如,一些新宏是 $L0NGH0ST0UTPUT$ 和 $LONGSERVICEOUTPUT$,它们包含多行插件结果的扩展插件输出(参见 H.10 扩展插件输出和 8.5.1 多行插件输出,第 193 页)。
宏 $H0STN0TIFICATI0NID$、$SERVICENOTIFICATIONID$、$H0ST-EVENTID$、$SERVICEEVENTID$、$LASTHOSTEVENTID$ 和 $LASTSERVICE-EVENTID$ 为每个事件分配一个唯一的识别号码,该号码是在 Nagios 3.0 中添加的。
$HOSTDISPLAYNAME$ 和 $SERVICEDISPLAYNAME$ 返回在主机和服务定义中设置的 display_name。
另一个值得关注的新宏是允许访问最后状态:$LASTHOSTSTATE$ 和 $LASTHOSTSTATEID$ 提供前一个主机状态,而 $LASTSERVICESTATE$ 和 $LASTSERVICESTATEID$ 用于前一个服务状态。*ID 宏提供数值(例如,服务的严重状态为2),而其他两个提供相应的文本(例如,服务为 WARNING,主机为 DOWN)。
宏通常也可以通过环境读取,但宏数量的增加会影响性能。如果你不通过环境变量访问 Nagios 宏,因此在 Nagios 3.0 中最好完全关闭此功能:
enable_environment_macros=0
如何使用宏在附录 D 第 625 页中描述。所有宏的完整列表可以在在线文档中找到.^([338]) Nagios 3.0 的变更日志将告诉你哪些是新的。
^([338]) nagios.sourceforge.net/docs/3_0/macrolist.html
^([339]) nagios.sourceforge.net/docs/3_0/whatsnew.html
H.3 停机时间、注释和确认
注释和维护间隔现在与其他信息一起保存在状态和保留文件中。这些特殊文件和相关参数 downtime_file 和 comment_file 已从 Nagios 3.0 中删除。从 Nagios 2.x 升级到这个版本,你可以保留任何现有的注释和维护间隔——如何做到这一点在 H.13 从 Nagios 2.x 升级到 3.0 中描述。
另一项变化涉及注释的处理。到目前为止,非持久性注释会在每次重启时被删除。在 Nagios 3.0 中,它们现在可以保留;系统仅在问题得到纠正时删除注释,以便服务或主机状态为正常。
H.4 状态快速变化
即使关闭了翻转检测,Nagios 3.0 现在也会记录状态历史。如果您全局开启 enable_flap_detection(参见第 796 页的 A.1 主配置文件 nagios.cfg),Nagios 将立即对所有主机和服务进行翻转测试。
对于全局关闭翻转检测,如果主机或服务定义中的 notification_options 中指定了 f(翻转),Nagios 将将翻转状态记录到日志文件,并发送通知类型为 FLAPPINGDISABLED 的消息。
与 Nagios 2.x 仍然记录每个状态变化不同,在 Nagios 3.0 中,参数 flap_detection_options(参见第 679 页的 H.1.1 主机对象)允许将其限制为某些状态。然后只将指定的状态包含在状态变化计算中。
H.5 外部命令
在 Nagios 3.0 中,外部命令列表变得更长,因此可以通过相关界面设置更多的事情(参见第 292 页的 13.1 外部命令的界面)。
其中,命令 PROCESS_FILE 特别引人注目,它传递一个包含外部命令的文件。这允许大量处理被动检查:
PROCESS_FILE; *path/to/file; number*
PROCESS_FILE 需要指定要处理的文件的完整路径。第二个参数决定在处理完成后是否保留文件(0 表示保留)或删除(非 0 值)。
另外两个新命令允许您创建自己的通知。通知实际上有一个固定的类型(PROBLEM、RECOVERY、ACKNOWLEDGE 等;参见第 277 页的 表 12-1),通过宏 $N0TIFI-CATI0NTYPE$ 进行查询。所谓的 自定义通知,相比之下,类型为 CUSTOM,允许在通常严格的规则之外进行通知。这意味着广播——对所有人的消息——也是可能的:
SEND_CUSTOM_SVC_NOTIFICATION;*host; service; options; author; comment*
SEND_CUSTOM_HOST_NOTIFICATION;*host; options; author; comment*
代替 选项 占位符,您指定一个位掩码,它控制两个命令的行为。值 0 表示“未设置选项。”1 确保向所有正常联系人以及在整个升级过程中添加的联系人发送广播消息。2 强制发送消息,无论主机、服务或联系人是否启用了通知,并且忽略可能设置的任何时间窗口。最后,值 4 增加通知计数器,消息随后在升级过程中被计数。通常自定义通知不会被计数。
所有外部命令的完整描述都提供在 Nagios 主页的开发者页面。^[[340]) 那里的 Web 界面允许进行选择性搜索,以查找特定 Nagios 版本允许的命令或处理特定主题(例如,服务、主机、计划内停机(维护窗口)、通知)。
^([340]) www.nagios.org/developerinfo/externalconunands/conunandlist.php
H.6 嵌入式 Perl
处理嵌入式 Perl 解释器(参见第 669 页的 附录 G)在 Nagios 3.0 中也更容易。它可以通过主配置文件 nagios.cfg 中的参数 enable_embeded_perl 来开启或关闭。参数 use_embedded_perl_implicitly 控制是否在没有相反指令的情况下,插件应隐式使用激活的解释器(有关更多信息,请参阅第 672 页的 G.2 使用 ePN)。在 Nagios 2.x 中,在编译 Nagios 系统时只有开启或关闭解释器的选项。
如果启用了开关 --with-embedded-perl,Nagios 3.0 的 configure 脚本将自动使用开关 --with-perlcache。如果 Nagios 检测到要执行的脚本中有所变化,它将重新加载脚本。在 2.x 版本中,您必须开启 Perl 缓存后重启 Nagios。
H.7 主机检查的新逻辑
Nagios 2.x 以串行方式执行主机检查,因此它会在检查直接附近的其他主机之前等待单个检查的结果,以确定第一个主机是否是 DOWN 或 UNREACHABLE(参见 4.1 考虑网络拓扑 中的图)。相比之下,Nagios 3.0 在这里以并行方式工作,前提是待检查的主机的 max_check_attempts 参数大于 1。对于 max_check_attempts=l,系统的行为与 2.x 版本相同。
在某些情况下,这会强烈影响性能,因此您应该在 Nagios 3.0 中始终设置一个大于 1 的值。并行运行主机检查也意味着有时会丢失检查结果,因为 Nagios 不再等待每个单个检查的结果都可用。参数 check_for_orphaned_hosts 现在确保 Nagios 将处理孤儿检查。
如果使用同样新功能的 缓存检查,主动主机检查甚至可以在某些环境中提高性能。在这种情况下,Nagios 访问最近执行的检查结果,前提是这可以被认为是最新的。这意味着系统在处理失败服务的宿主机检查、解决失败宿主机的拓扑结构以及前瞻性依赖性检查(见最后一节)时可以节省大量时间。对于服务检查,缓存仅在服务依赖性方面发挥作用。
缓存的时间范围应该有多大,对于主机检查由参数 cached_host_check_horizon (参见 A.1 主配置文件 nagios.cfg) 定义,对于服务检查由参数 cached_service_check_horizon (A.1 主配置文件 nagios.cfg) 定义。默认情况下,每个参数都是 15 秒,而值 0 完全关闭缓存。
Nagios 缓存结果的间隔越大,Nagios 访问缓存而不实际执行检查的频率就越高。然而,这确实有一个关键缺点:缓存的結果可能已过时。因此,您始终需要在过时的结果和减轻 Nagios 的负担之间做出妥协。您必须自己决定缓存的时间间隔应该有多大。再次强调,首选的方法是测量服务检查的延迟时间,这可以很好地指示 Nagios 的性能。如果在 30 秒和 60 秒的缓存时间之间,长时间内没有明显的差异,那么选择较短的时间间隔更好,因为在这种情况下,您将使用更及时的结果。如何测量检查的延迟时间,请参阅第 660 页的 F.1.3 监控延迟的插件。
是否通过结合主动主机检查和缓存检查可以提高性能,也可以用 nagiostats (F.1.1 命令行工具 nagiostats, 第 654 页)) 进行测试。程序显示在过去一分钟、过去五分钟和过去十五分钟内,Nagios 重新使用缓存的宿主机检查结果的次数。
在分布式环境中,或者对于冗余的 Nagios 安装,有时视角会发生变化:Nagios 服务器 A 对网络的拓扑视图与 Nagios 服务器 B 不同。服务器 A 发送给服务器 B 作为被动检查结果的主机检查结果在某些情况下可能不再匹配。服务器 A 分类为 UNREACHABLE 的,从服务器 B 的角度看可能是一个处于 DOWN 状态失败的主机。参数 translate_passive_host_checks (A.1 主配置文件 nagios.cfg) 允许 Nagios 重新分类它已接收的被动主机检查。
为了实现更精细的调整,如果将主机定义中的参数 max_check_attempts 设置为大于 1 的值,并在主配置文件中启用参数 passive_host_checks_are_soft(第 600 页),被动主机检查现在也可以接受软状态。到目前为止,被动主机检查始终是“硬”的。
H.8 重启
当你启动 Nagios 时,它会每次重新检查配置以查找错误和依赖关系。根据具体环境,这可能非常快,或者可能持续很长时间,在此期间 Nagios 将不会运行。在 Nagios 3.0 中,有一个选项可以将此测试与重启分离,并将结果保存到单独的临时文件中。当 Nagios 启动时,它会读取此文件,并且在这个点上省略了通常的对象处理。是否值得这样做可以通过 nagios -s 来揭示:
nagios@linux:~$ **/usr/local/nagios/bin/nagios -s /etc/nagios/nagios.cfg**
OBJECT CONFIG PROCESSING TIMES
(* = Potential for precache savings with -u option)
----------------------------------
Read: 0.019277 sec
Resolve: 0.001001 sec *
Recomb Contactgroups: 0.000737 sec *
Recomb Hostgroups: 0.003890 sec *
Dup Services: 0.005938 sec *
Recomb Servicegroups: 0.048659 sec *
Duplicate: 0.001527 sec *
Inherit: 0.005602 sec *
Recomb Contacts: 0.000001 sec *
Sort: 0.030277 sec *
Register: 0.010132 sec
Free: 0.001831 sec
============
TOTAL: 0.128874 sec * = 0.097634 sec (75.76%)
estimated savings
CONFIG VERIFICATION TIMES
(* = Potential for speedup with -x option)
----------------------------------
Object Relationships: 0.013131 sec
Circular Paths: 0.002341 sec *
Misc: 0.001032 sec
============
TOTAL: 0.016504 sec * = 0.002341 sec (14.2%)
estimated savings
标记有 * 的时间是通过这种 预缓存 程序保存的。在这个例子中,启动时间的 75%用于处理定义的对象,但从绝对意义上讲,这仅仅是十分之一秒,所以几乎不值一提。
如果有真正的节省潜力,可以通过以下步骤打开预缓存:
nagios@linux:~$ **/usr/local/nagios/bin/nagios -vp /etc/nagios/nagios.cfg**
nagios@linux:~$ **/etc/init.d/nagios stop**
nagios@linux:~$ **/usr/local/nagios/bin/nagios -udx /etc/nagios/nagios.cfg**
第一次调用使用选项 -v 检查配置,并使用 -p 将处理过的对象缓存到单独的文件中。该文件由 nagios.cfg 文件中的参数 precached_object_file 定义(A.1 主配置文件 nagios.cfg)。然后,在第二步停止 Nagios。
第三步是使用选项 -udx 启动系统。选项 -u 读取预缓存文件的內容,-d 正常启动 Nagios 作为守护进程。-x 防止循环依赖的测试,但假设这个调用始终基于一个经过测试的配置,就像步骤 1 中生成的配置一样。选项 -x 是否真的节省时间,可以从上面的例子中 CONFIG VERIFICATION TIMES 部分的 Circular Paths 行中看出。
H.9 性能优化
除了对外部不可见的性能优化之外,Nagios 3.0 还包括一些旨在提高大型安装性能的参数。其中最重要的是 large_installation_tweaks (F.2.6 优先使用被动检查)。
在现有环境中性能的提升处理可以在 附录 F 从第 653 页找到。
H.10 扩展插件输出
Nagios 3.0 最终能够处理多行插件输出。输出的总长度不得超过 8 KB——但你必须确保所有传输路径都能兼容这么大的数据量。NRPE 目前仍需要在源代码中进行调整(8.5.2 安装要求);标准插件反转 1.4.10 中的插件 check_by_ssh(第九章(第 193 页)中描述,插件 check_multi(8.5 使用 check_multi 汇总检查)中添加了一些新参数。lock_author_names 防止在设置主机或服务的确认或注释时包含的用户名被更改。相反,使用用户在向 Web 服务器进行身份验证时指定的用户名。因此,每个注册用户都是一个经过身份验证的用户。
escape_html_tags 决定了插件输出中的 HTML 格式是否被使用(值 0)或者 Nagios 是否将其移除(值 1)。为了与 action_url (16.4.1 扩展主机信息) 和 notes_url (16.4.1 扩展主机信息) 相关联,现在有一个额外的选项来指定目标窗口,即 action_url_target 和 notes_url_target。
使用 CGI 程序 status.cgi(参见 16.2.1 状态显示的变体:status.cgi),您现在也可以通过 hostprops 和 serviceprops 选择硬状态和软状态。这在使用 NagVis (第十八章)时尤其有用,因为 NagVis 默认只显示硬错误状态。
H.12 杂项
上述各节中未包含的改进之一是参数 use_timezone(第 606 页),您可以使用它独立于 Nagios 服务器上设置的时间区域来设置时区。这仅在多个 Nagios 实例在单个机器上运行时才是必要的。
参数 additional_freslmess_latency(参见 附录 A),通常使用以秒为单位指定的时间段,以防 Nagios 等待被动检查的结果时间过长。
指令 cfg_file 和 cfg_dir(参见 A.1 主配置文件 nagios.cfg 中描述的步骤运行安装,使用 configure 和 make all,但不运行 make install。您将在 base 子目录中获得可执行的 Nagios-3.0 二进制文件,您可以使用它从源代码目录测试现有的配置:
linux:src/nagios-3.0 # **./base/nagios -v /etc/nagios/nagios.cfg**
...
如果 Nagios 在这里发现错误,如果不消除这个错误,它将阻止新版本的 Nagios 启动。在某些点上,Nagios 3.0 会给出关于新特性的警告和信息,但这些不会阻碍重启。
尽管如此,在 Nagios 3.0 投入运行之前,还有一些小细节需要注意。参数service_reaper_frequency现在被称为check_result_reaper_frequency (A.1 主配置文件 nagios.cfg); 它在nagios.cfg.aggregate_status_updates中被完全删除,因此在nagios.cfg中被注释掉。
宏$NOTIFICATIONNUMBER$被合理地拆分为主机和特定服务的宏($HOSTNOTIFICATIONNUMBER$和$SERVICEN0TI-FICATI0NNUMBER$)。使用该宏的命令和脚本必须进行调整,以确保它们能正确工作。
为了保留在downtime_file和comment_file(在这本书中是comments.dat和downtime.dat)中指定的不再使用的文件中的维护间隔和注释,您必须停止 Nagios,保存它们,然后从它们中删除开头的 Info 块,因为在新文件中这可能只发生一次,该文件在retention_file中指定:
info {
created=1144429286
version=2.0
}
然后将这两个文件的内容复制到保留文件的末尾,在这里这本书中是文件/var/nagios/retention.dat:
linux:~ **# /etc/init.d/nagios stop**
linux:~ **# cd /var/nagios**
linux:var/nagios # cat **comments.dat downtime.dat >> retention.dat**
现在执行剩下的三个安装步骤(见 1.2 编译源代码):
linux:src/nagios-3.0 # **make install**
...
linux:src/nagios-3.0 # **make install-init**
...
linux:src/nagios-3.0 # **make install-commandmode**
...


浙公网安备 33010602011771号