使用 SMS 服务器为 Nagios 提供强大的警报服务

作者:Eric Pearce

我是 Nagios 网络监控系统的忠实粉丝,并依靠它来告知我负责的系统是否出现问题。我投入了大量时间配置 Nagios 以精确监控我感兴趣的内容,如果 Nagios 检测到问题,但未能将该问题传达给我,那么这些努力将付诸东流。为了使 Nagios 更加强大,我想确保其警报机制不依赖于互联网连接——这将包括物理连接本身以及内部和外部服务,例如电子邮件、路由和 DNS。

过去,我曾依赖基于电子邮件的系统来传递警报;然而,我的困境是,如果我没有收到电子邮件,我不知道这意味着一切正常,还是存在一些问题阻止我收到电子邮件警报,例如互联网连接中断或其他类型的电子邮件故障。我发现,在长时间的沉默之后,我会感到不安,并感到有必要“轮询”系统以确保一切正常。

另一方面,我认为如果我的警报系统足够强大并且我可以信任它,我的想法就会变成“没有消息就是好消息”,并且没有警报就意味着一切都很好。

我发现 GSM 蜂窝网络上提供的短消息服务 (SMS) 文本服务满足了我对可信警报服务器的要求。它通常可用,并且不太可能出现故障。重大灾难肯定可能会导致蜂窝服务瘫痪或不堪重负,但我想我会意识到此类事件,并且可能比那时处理网络管理有更大、更紧迫的担忧。

有几种不同的方法可以实现 Nagios 到 SMS 的服务,我当然没有探索所有方法。本文介绍了我正在使用的系统,该系统是 MultiTech Systems MultiModem iSMS 智能 SMS 服务器(图 1)与在基于 Linux 的 Nagios 服务器上运行的公共领域 Perl 脚本的组合。

Using an SMS Server to Provide a Robust Alerting Service for Nagios

图 1. MultiTech Systems MultiModem iSMS 智能 SMS 服务器

我选择这种硬件和软件组合的原因如下

  • 另一家公司已经完成了将 iSMS 设备与 Nagios 集成所需的所有工作,清楚地记录了该过程,并在 Web 上免费提供,包括本文中描述的 Perl 脚本。

  • Perl 脚本的一个主要功能是能够“ACK”或确认 Nagios 警报。这意味着您无需与 Nagios 服务器建立任何类型的 IP 连接即可执行确认。当您不在 IP 网络上时,确认警报的能力很有帮助,因为它可以停止任何未来的警报,并且如果您已将 Nagios 配置为这样做,则可以防止警报发送给其他人。如果需要,该脚本还可以强制服务或主机恢复到“OK”状态。

  • iSMS 设备是一个独立的“设备”,除了(本地)以太网连接、GSM 蜂窝服务和电力之外,不依赖于任何基础设施。该领域的其他大多数产品都类似于传统的模拟调制解调器,因为它们具有硬连线到特定主机的串行连接。由于 iSMS 通过以太网连接,因此可以由多个主机访问和共享。我使用的特定型号只有一个 GSM 调制解调器,但也提供四调制解调器或八调制解调器版本。

  • 其他 Nagios 用户正在此角色中使用传统的移动电话手机,但我认为消费级电源和在机房中以某种方式临时安装电话会破坏我想要的可靠性。iSMS 具有坚固的金属外壳,可以牢固地连接到机架。电源插头带有螺纹连接到机箱,以防止意外拔出。

  • iSMS 具有基于 Web 的管理界面,并支持多种通信方法,包括用于直接连接到 GSM 调制解调器以使用“AT”命令的“Telnet”接口和多个 API。这些包括用于发送和接收 SMS 消息或查询排队消息状态的 TCP 和 HTTP API。当然,您可以使用基于 Web 或基于电子邮件的工具来创建类似的警报功能,但 SMS 在某种程度上是独一无二的,因为它不需要 IP 连接,并且在现代蜂窝基础设施存在的任何地方通常都可用。

如图 1 所示,iSMS 封装在坚固的金属外壳中。我使用大型塑料扎带将 iSMS 安装到水平机架柱上,但也可以用螺钉安装。天线在顶部可见,底部有一个小舱口,Subscriber Identity Module (SIM) 卡插在那里。

订购 iSMS

该产品通常可用,我只是使用价格比较网站找到了最便宜的产品,因为我不觉得我需要供应商的支持。在我撰写本文期间,MultiTech 对其产品进行了多次更改。这些更改包括重命名产品、更新固件版本和降低价格。iSMS 以前名为 SMSFinder,您将在 Perl 脚本的名称和其他地方看到这一点。固件更新需要对 Perl 代码进行一些更改。原始产品定价约为 700 美元,但现在价格在 400 美元左右。本文介绍了最新版本的 iSMS 和 Perl 脚本。

订购 SMS 服务

我没有在不同的运营商之间货比三家 SMS 服务,因为我的公司已经在 AT&T 开设了公司帐户。最初,我试图走进 AT&T 零售店为 iSMS 购买服务,但我无法购买不包含语音的服务套餐。最终,我通过电话与 AT&T 公司完成了所有订购和设置。我能够在零售店拿到 SIM 卡,这让我不必等待卡片邮寄到我的所在地。AT&T 将其纯文本 SMS 服务称为遥测。如果您在与运营商交谈时使用此术语,可能会使订购过程更容易。

一旦您联系到正确的订购部门,您只需要向他们读取两个号码:第一个号码标识 iSMS,第二个号码标识 SIM 卡。iSMS 的号码是印在 iSMS 机箱标签上的国际移动设备身份 (IMEI) 号码。第二个号码,集成电路卡 ID (ICC-ID) 印在 SIM 卡上。一旦我将这些号码告知运营商,我就能够在几分钟内建立服务并发送测试消息。请务必记下给您的用户号码,因为这将是 SMS 警报的来源和您的“ACK”和“OK”响应的目标。最好将联系人姓名与此号码关联,以便在您的手机上进行来电显示(例如,“Nagios”)。根据我购买的服务,一次性设置费为 18 美元,每月费用约为 9 美元,具体取决于使用情况。

iSMS 的物理位置

我希望 iSMS 和 Nagios 服务器能够在网络连接或电源出现问题时尽可能长时间地发送消息。在我的情况下,这意味着将 iSMS、Nagios 服务器及其共享的以太网交换机都放置在同一计算机房中,并插入同一个冗余 UPS。当然,我可以从这种配置中消除交换机,方法是使用以太网交叉电缆直接连接 iSMS 和 Nagios 服务器,但这会将通信限制为一个服务器。这也将消除我在试图改进的硬连线 GSM 调制解调器的大部分优势。

smsfinder Perl 脚本

可以在 MonitoringExchange 网站 (www.monitoringexchange.org) 或 Nagios Wiki (www.nagioswiki.org) 上找到 Perl 脚本。搜索“smsfinder”应该可以找到正确的位置。该脚本的文档包括安装说明、Nagios 配置文件示例和 iSMS Web 用户界面的屏幕截图。作者使用了一种有趣的方法来创建一个脚本,该脚本具有三种不同的用途。该脚本检查以查看用于调用脚本的文件名,然后根据使用的名称执行完全不同的功能。该脚本有三个名称

  • smssend.pl:Nagios “命令”,用于通过 SMS 发送有关主机和服务的消息。

  • smsack.cgi:iSMS 使用的 CGI 脚本,用于确认通过移动电话发送的 SMS 消息收到的警报。

  • check_smsfinder.pl:典型的 Nagios “插件”或“检查”脚本,由 Nagios 按计划调用以监控 iSMS 设备本身的运行状况。

脚本安装

我将实际脚本存储为 /usr/local/nagios/smsack/smsack.cgi,并使用以下名称/路径创建了两个指向它的符号链接

  • /usr/local/nagios/smsack/sendsms.pl

  • /usr/local/nagios/libexec/check_smsfinder.pl

Apache 希望将实际文件作为 CGI 执行,而 Nagios 不会关心符号链接。图 2 概述了脚本如何与系统的其他组件交互。

Using an SMS Server to Provide a Robust Alerting Service for Nagios

图 2. SMSFinder 操作方法

脚本最简单的用法是在调用 check_smsfinder.pl 时。Nagios 按计划的时间间隔运行此检查脚本,并且该脚本通过 HTTP 查询 iSMS 上的状态页面,以确保其运行正常。该脚本将退出状态返回给 Nagios。性能数据包括 GSM 调制解调器的信号强度、型号和固件版本。

脚本的下一个用途是在 Nagios 将其称为 sendsms.pl 时。在这种形式下,它用于将主机和服务警报和确认发送到 iSMS,以便传递给移动用户。该脚本使用“HTTP Send API”来请求它传输 SMS 消息。iSMS 将请求排队并返回消息 ID。最终用户可以使用消息 ID 查询 iSMS,以了解 SMS 消息是否已成功发送或因某种原因失败。当作为 sendsms.pl 调用时,该脚本具有 --noma 选项,该选项将在消息排队后查询 iSMS 以获取其状态。这需要稍长的时间才能执行,因为脚本必须等待确认消息是否已实际发送(或失败)。文档提到了“NoMa”,但没有解释为什么该选项以此命名。

脚本最复杂的用途是在 Apache 下作为 smsack.cgi CGI 脚本运行时。SMS 警报的接收者可以将整个消息发回 iSMS,并在消息文本前加上字符串“ACK”或“OK”。当 iSMS 收到此 SMS 消息时,它会使用“HTTP Receive API”调用带有 ACK 消息的 smsack.cgi CGI 脚本。smsack.cgi CGI 脚本解析消息文本,确定它是主机还是服务被确认,验证发送者的电话号码是否在 Nagios 对象缓存中,然后使用 Nagios “外部命令”接口向 Nagios 发出信号。然后,Nagios 尝试将主机名或服务名称与它知道的名称匹配,如果匹配成功,它会确认问题。该脚本还在主机或服务页面上创建注释,指示问题已由发送者的手机号码确认。

确认功能期望将整个 SMS 警报消息发回 iSMS,并在前面加上“ACK”文本。我发现,在较旧的基于文本的移动电话和较新的图形移动电话上执行此操作的最佳方法是将从 Nagios 收到的整个消息“转发”回 Nagios 电话号码,然后在消息开头插入 ACK 文本。

Using an SMS Server to Provide a Robust Alerting Service for Nagios

图 3. Apple iPhone 屏幕截图

图 3 显示了 Apple iPhone 的屏幕截图。从 iSMS 收到的初始“PROBLEM”警报在顶部(以灰色显示)。转发回 iSMS 并带有前置“ACK”的消息在中间(以绿色显示),而从 iSMS 发送的确认接收在底部(以灰色显示)。整个事务可以在不到一分钟的时间内完成。

调试安装和运行时问题

我能够在一两天内让一切运行起来,但我确实必须解决安装过程中的几个问题。我还发现了一些需要更改 Perl 脚本的问题。因此,测试脚本非常重要。

您可以在命令行上运行 check_smsfinder.pl 和 sendsms.pl 脚本以直接查看其输出。例如

% /usr/local/nagios/libexec/check_smsfinder.pl \
     -H 192.168.1.50 -u nagios -p secret
OK: GSM signal strength is 100.0% - \
    model: SF100-G - \
    firmware: 1.31|loginID=1607132337 strength=100.0%;40;20;;

% /usr/local/nagios/smsack/sendsms.pl \
     --noma -H 192.168.1.50 -u nagios -p secret \
     -n 14155551212 -m 'this is a SMS from nagios'
"this%20is%20a%20SMS%20from%20nagios" to 14155551212 \
     via 192.168.1.50 send successfully. MessageID: 37

smsack.cgi 脚本比命令行脚本更难调试,但常用的 Apache 日志文件 access_log 和 error_log 非常有用,因为当 iSMS 调用 CGI 时,它们将包含 HTTP 响应代码。您还可以使用下面“网络捕获”下描述的方法来查找 CGI 脚本的问题。

日志记录

在 Nagios、Perl 脚本和 iSMS 设备中的许多地方都包含调试信息。了解这些信息的位置将有助于您的安装。

iSMS 可以通过 syslog 将有用的调试消息发送到远程主机。Nagios 服务器将是消息的理想目的地,因为所有日志记录都可以合并在一个位置。远程 syslog 主机在 iSMS Web GUI 中指定。iSMS syslog 消息使用 LOG_LOCAL0 工具。我添加了一个local0.* /var/log/isms条目到我的 /etc/syslog.conf 文件中以捕获所有消息。日志文件将记录 iSMS 发送和接收的所有 SMS 消息,例如

Nov 23 09:27:59 smsgw MultiModemiSMS modem: sentlog:
    [SENT TO] : 14155551212 : [MSG] : this is a SMS from Nagios

日志还包含任何身份验证失败信息。这很有用,因为 check_smsfinder.pl 和 sendsms.pl 脚本每次运行时都会向 iSMS 验证身份。

iSMS 具有 SMS 消息的“收件箱”(用于从移动用户接收的 SMS 消息)和“发件箱”(用于从 iSMS 发送出去的 SMS 消息)的概念。您可以通过 iSMS Web 界面检查这些框,以了解消息是否已实际接收或传输。

Nagios 记录到 nagios.log 文件,该文件通常位于 /usr/local/nagios/var 目录中。您可以使用此日志来验证 Nagios 是否正在为问题生成警报,以及是否已使用命令发送 SMS (notify-host-by-sms)

[1258664139] HOST NOTIFICATION:
    epearce-sms;mailserv2;DOWN;notify-host-by-sms;CRITICAL -
    Host Unreachable (192.168.1.250)

Nagios 日志还将显示在从移动用户收到“ACK”后运行的 smsack.cgi 的结果

[1258500602] EXTERNAL COMMAND:
    ACKNOWLEDGE_HOST_PROBLEM;mailserv2;1;1;1;14155551212;
    Acknowledged by 14155551212 at 09/11/17 15:29:57
    ACK PROBLEM mailserv2> is DOWN /11-17-2009 15:28:21/ CRITICAL -
    Host Unreachable(192.168.1.250)

smsfinder 脚本记录到 smsfinder.log(也在 Nagios var 目录中)。此文件将包含脚本的 sendsms.pl 和 smsack.cgi 用法的调试信息。包含“SMSsend”的行显示 sendsms.pl 在 Nagios 运行时的状态。例如

2009/11/19 12:55:39 SMSsend:
    "PROBLEM...mailserv...is...DOWN...CRITICAL..."
    to 14155551212 via 192.168.1.250 queued successfully.
    MessageID: 14

包含“SMSreceived”和“SMSverify”的行将显示解析 smsack.cgi 脚本接收到的任何确认 SMS 消息的进度

2009/11/12 09:15:41 SMSreceived:
    username=nagios&password=secret&XMLDATA=
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <Message Notification>
      <SenderNumber>14155551212</SenderNumber>
      <Message>
        ACK PROBLEM HostAlert mailserv2 192.168.1.250
        /AllServices is DOWN
        /11-12-2009 09:11:46/ CRITICAL -
        Host Unreachable (192.168.1.250)
      </Message>
      <Date>09/11/12</Date>
      <Time>09:15:36</Time>
    </Message Notification>

2009/11/12 09:15:41 SMSverify
    status = ACKed - ACCEPTED:
    From=14155551212 Received=09/11/12 09:15:36
    Status=ACK Host=mailserv2 Service=AllServices
    MSG="ACK PROBLEM ... Host Unreachable (192.168.1.250)"

Apache

最初,我在 Apache 配置文件的 Nagios 部分中有多个重叠的“Directory”语句。最终结果是在运行 CGI 时出现“Permission denied”(权限被拒绝)。我通过使用下面描述的方法并查看 Apache access_log 和 error_log 文件解决了这个问题。

网络捕获

如果您认为脚本存在一些通信问题,您可以通过监听网络来监控 Nagios、Apache 和 iSMS 之间的流量。我使用 tcpdump 来捕获 HTTP 流量并查看错误消息

% tcpdump -v -s 0 -w /tmp/cap host 192.168.1.50

在此示例中,我使用了-v选项用于详细输出,-s 0选项用于尽可能多地捕获数据包,以及-w选项用于将捕获的流量写入 /tmp/cap 文件。“host”关键字指示我想要所有进出 iSMS IP 地址 (192.168.1.50) 的流量。我在托管 Nagios 和 Apache 的机器上运行了此命令,因此它应该看到这些服务与 iSMS 之间的所有通信。然后,我通过导致 Nagios 发送“PROBLEM”消息来生成一些 SMS 消息流量,然后我通过我的手机确认了该消息。您应该看到在捕获数据包时,“Got”后面的数字递增

tcpdump: listening on eth0, link-type EN10MB (Ethernet),
          capture size 65535 bytes
Got 22

然后我中断了捕获并将捕获的数据转换为纯文本

% tcpdump -A -r /tmp/cap > /tmp/txt

The-A选项输出 ASCII 文本,-r选项从文件读取捕获数据。检查 /tmp/txt 文件允许您查看 Nagios、iSMS 和 CGI 脚本之间的整个 HTTP 事务

12:50:09.434851 IP nagios.46058 > smsgw.http:
    P 1:266(265) ack 1 win 46
    <nop,nop,timestamp 2801435752 1987587011>

GET /sendmsg?user=nagios&passwd=secret...text=ACKNOWLEDGEMENT...

12:50:09.501524 IP smsgw.http > nagios.46058:
    P 1:29(28) ack 266 win 6432
    <nop,nop,timestamp 1987587017 2801435752>

HTTP/1.0 200 OK
ID: 2078

在此捕获中,您可以看到由 Nagios(主机名 nagios)调用的 sendsms.pl 脚本已向 iSMS(主机名 smsgw)发送了一个 HTTP GET,其中包含 Nagios “ACKNOWLEDGEMENT”(确认)消息。来自 iSMS 返回给 Nagios 的“ID: 2078”响应表明该消息已排队等待发送,并且此 SMS 消息的 ID 为 2078。您可能还会注意到 iSMS “nagios”帐户的用户名和密码是以明文形式发送的——虽然不完美,但我认为这是一个非常低的安全风险,因为此事务是在公司网络内部进行的。

iSMS 的固件版本

我的原始 iSMS 随附了 1.20 版固件。这与原始 Perl 脚本配合良好,但它存在一个问题,即它有点“单用户”。例如,如果您在 check_smsfinder.pl 脚本运行时碰巧登录到 iSMS Web 用户界面,它将返回错误状态,并且 Nagios 将为该设备创建警报。升级到较新的固件解决了此问题,但破坏了 check_smsfinder.pl 脚本。Perl 脚本已更新,但现在脚本版本与 iSMS 上运行的固件版本相关联。

由于这是一个 Perl 脚本,因此可以轻松修改它。如果您不喜欢 Nagios 发送的消息格式,您可以在 Nagios “command”定义中更改它——例如,“notify-host-by-sms”,也可以更改 Perl 脚本以解析您想要从手机发回的任何消息格式。脚本作者随着时间的推移更改了他们的消息格式,使其更易于解析,因为在服务名称和主机警报中发现了空格问题,这些问题会根据主机定义是否包含 IP 地址(例如 DHCP 客户端的情况)而更改格式。

结论

我对这种警报服务的工作方式非常满意。iSMS 自我安装以来一直很稳定,并且一旦我调整了 Nagios 设置以匹配它,相关的脚本就完美地工作了。我对无论问题的性质如何都能收到警报充满信心。

致谢

感谢 Birger Schmidt 及其 NETWAYS GmbH (www.netways.de) 的同事编写了原始脚本,对其进行了更新,并花时间审查了本文,以及 Chris Reilley (www.reilleydesign.com) 制作了图 2。

Eric Pearce 是 AmberPoint, Inc. 的 IT 负责人,AmberPoint, Inc. 是一家位于加利福尼亚州奥克兰市的应用程序管理和治理软件公司。他为 O'Reilly & Associates 撰写了多本关于 UNIX 和 Windows 系统管理的书籍。

加载 Disqus 评论