Tuesday, January 19, 2016

Nagios alerts implemented via VoIP

Nagios Calling


Out of the box, Nagios can only alert you by email when a service fails, but these email messages can be easily overlooked. A call is more sustainable.
It's difficult to ignore a ringing phone, so it makes sense to teach Nagios how to make phone calls. You can do this with a combination of Nagios [1] and Asterisk [2]. Configuring Asterisk is less than trivial, and setting up a complete PBX just for monitoring is slightly over the top; however, you can sign up for a SIP (Session Initiation Protocol) account for not too much money, add a CLI SIP client and a simple shell script, and do the same thing with less overhead (Figure 1).
Figure 1: As you can see, the command that picks up the message – here, an email script – works.
First, the SIP account; you could opt for any VoIP provider. Setting up an account is trivial: Just complete the online form, wait for the confirmation email, and set up your account.

A Matching SIP Client

The process for the CLI SIP client is slightly more complex. Most VoIP clients are designed for the desktop and cannot be scripted at all, or at least not very well. Of the available clients, PJSUA [3] turns out to be the best choice. PJSUA is the PJSIP reference implementation, and it comprises a function library for SIP, RTP, STUN, and some other VoIP-related protocols.
Unfortunately, there are no PJSUA packages, which means building from the source code – although this is done easily enough. You can do the following to pick up the PJSIP/PJSUA source code:
wget http://www.pjsip.org/release/2.0./pjproject-2.0.1.tar.bz2
Next, go to the directory where you unpacked the tarred and zipped file and type:
./configure
make dep
make
You will now have a file starting with pjsua in your pjsip-apps/bin directory. This is the SIP client. You can copy it to anywhere you like on your system and make it executable. Next, you need a configuration file for the client; you define the access credentials for the SIP provider here.
To define the access credentials, create a text file with the content from Listing 1. You need to modify the content to match your own SIP provider, of course; this might be difficult in some cases because providers tend to use their own designations for id and realm. If in doubt, you can call your provider's hotline. --null-audio tells the server not use any audio output and thus avoids outputting calls via the computer's loudspeakers.
Listing 1
Provider Data
--null-audio
--registrar sip:sipgate.de
--realm=sipgate.de
--id sip:username@sipgate.de
--username sipgateusername
--password sipgatepasswort

The Call Script

Next, you need a script that Nagios can call when the need arises (Listing 2). This script also ensures that messages do not interfere with one another. If Nagios needs to make two calls in quick succession, the script ensures that the first call terminates before the second one begins. Otherwise, the client would refuse to cooperate because the line was occupied, and the second message would be lost.
Listing 2
Call Script
01 #! /bin/bash
02
03 EXPECT=/usr/bin/expect
04 PJSUA=/opt/pjsua
05 PJSUACONFIG=/opt/pjsua.conf
06 SOUNDFILE=/tmp/alert.wav
07 TEXT2WAVE=/usr/bin/text2wave
08 DURATION=20
09 NUMBER=01234567890
10 MESSAGE="Monitoring Alert"
11
12 # Setting a lock file
13 # We can't make more than one call
14 # at a time, because pjsua blocks the port
15 # so we have to make sure that nobody else tries to call
16 # If there is already a call we have to wait.
17
18 locked=false
19 while [[ $locked == false ]]; do
20     if [[ ! -f /tmp/caller.lock ]]; then
21         touch /tmp/caller.lock
22         locked=true
23     else
24         sleep 5
25     fi
26 done
27
28 # Generating the message
29 $TEXT2WAVE -o $SOUNDFILE -f 8000 << EOF
30 $MESSAGE
31 EOF
32
33 # Making the call it self.
34 # Expect will start pjsua and work with
35 # it so that it will end it self automatically
36
37 $EXPECT << EOF
38 spawn $PJSUA --config-file $PJSUACONFIG [UCC:z-inhbullet][/UCC]
   --play-file $SOUNDFILE --auto-play --duration $DURATION    --max-calls 1 sip:$NUMBER@sipgate.de
39 expect "VAD re-enabled"
40 sleep $DURATION
41 send "q\n"
42 EOF
43
44 # Cleaning up
45 rm $SOUNDFILE
46
47 # Removing the lock file
48 rm /tmp/caller.lock
The script needs two other tools: expect, to control pjsua, and text2wave, to create a WAV from a line of text. The text2wave tool is part of Festival, a program for voice synthesis [4]. Both packages can be installed via your package manager. Next, you should make the script in Listing 2 executable.
In the listing, you should set the value of NUMBER to the phone number you want Nagios to call. MESSAGE contains what you want the call recipient to hear. If you prefer not to hard wire the phone number into the script, you can pass the number in to Nagios. DURATION lets you configure the maximum duration for the call. If nobody picks up the phone within this time, the script hangs up. If somebody takes the call, the script plays the message in a loop. You may need to modify the last argument to match your own SIP provider in the line starting with spawn.

On My Command

Finally, you need to reconfigure Nagios to call the script in case of an alert. To do so, start by defining a new command. If you are using Ubuntu 12.04 and Nagios3, you will find the matching file in /etc/nagios3/resource.cfg. For other distributions, the path might differ slightly. Next, insert the content from Listing 3.
Listing 3
resource.cfg
01 # Additional commands, so that nagios can call the sysadmins
02 define command {
03     command_name notify-host-by-phone
04     command_line /opt/pjsua_wrapper
05 }
06
07 define command {
08     command_name notify-service-by-phone
09     command_line /opt/pjsua_wrapper
10 }
In Listing 3, /opt/pjsua_wrapper is the path to the script. You may also need to modify this. Then, you simply need to modify the contact definition for the administrator in Nagios. The configuration typically looks like this:
define contact {
    ...
    service_notification_commands notify-service-by-email
    host_notification_commands notify-service-by-email
    ...
}
Simply add the new commands to the two parameters:
define contact {
    ...
    service_notification_commands
    notify-service-by-email,notify-host-
    by-phone host_notification_commands
    notify-service-by-email,
    notify-service-by-phone
    ...
}
Finally, you can restart Nagios and wait for calls to come in.
The Author

No comments:

Post a Comment