{"id":1626,"date":"2015-05-30T16:52:18","date_gmt":"2015-05-30T15:52:18","guid":{"rendered":"http:\/\/www.zarrelli.org\/blog\/?p=1626"},"modified":"2015-06-10T13:52:52","modified_gmt":"2015-06-10T12:52:52","slug":"nagios-sending-sms-notifications-through-gsmsmsd","status":"publish","type":"post","link":"https:\/\/www.zarrelli.org\/blog\/nagios-sending-sms-notifications-through-gsmsmsd\/","title":{"rendered":"Nagios: Sending SMS notifications through gsmsmsd"},"content":{"rendered":"<p style=\"text-align: justify;\">Critical, that&#8217;s a point you would not ever want to reach. Monitoring is all, or quite all, on recovering a situation before it becomes a problem.<\/p>\n<p style=\"text-align: justify;\">When it becomes a problem, you must move quickly and solve the issue.<\/p>\n<p style=\"text-align: justify;\">So, \u00a0when you have a problem, we do not need a genius, we need flat, plain procedures which help you to undestand that<\/p>\n<ol style=\"text-align: justify;\">\n<li>There&#8217;s a problem<\/li>\n<li>How fast you need to move<\/li>\n<li>How to solve it<\/li>\n<\/ol>\n<p style=\"text-align: justify;\">To help you to understand the severity of a problem, there&#8217;s a common practice: what is really critical to you business must be notified with a less used, probably more expensive channel. So, using sms adresses these needs. Reading and dealing with a SMS text message is far more unconfortable than working with emails, but reaches you in a more pervasive way than other channes. Sending emails is virtually free of costs, SMS costs. So, you use sms just to read important messages, your daddy who want&#8217;s to know where you are, the one you love who reminds \u00a0you about buyng milk coming back home, your dear Nagios alerting you on a CRITICAL, really critical problem on you IT infrastructure.<\/p>\n<h6 style=\"text-align: justify;\">On the SMS server side<\/h6>\n<p style=\"text-align: justify;\">So, let&#8217;s start with the sms server part. On the server you must be sure that gsmsend is always on, watching the right directory and with its hands (doh, does gsmsend has hands?) on the terminal connected to the sms modem (I used a Fastrack Supreme 10, serial, for this post).<\/p>\n<p style=\"text-align: justify;\">If you issue a command like<\/p>\n<pre class=\"lang:sh decode:true\">ps ax | grep\u00a0gsmsmsd<\/pre>\n<p style=\"text-align: justify;\">you should\u00a0see something like:<\/p>\n<pre class=\"lang:sh decode:true\">\/usr\/bin\/gsmsmsd -d \/dev\/ttyS0 -s \/var\/spool\/sms\/<\/pre>\n<p style=\"text-align: justify;\">How to reach this goal? Simple, let&#8217;s have a look to the root user crontab:<\/p>\n<pre class=\"lang:sh decode:true\">crontab -l root<\/pre>\n<p style=\"text-align: justify;\">And here&#8217;s what we can see:<\/p>\n<pre class=\"lang:sh decode:true\">* * * * * \/usr\/local\/sbin\/check_gsmsmsd<\/pre>\n<p style=\"text-align: justify;\">Using the following chart, it&#8217;s easy to undestand what we found in the crontab.<\/p>\n<pre class=\"lang:sh decode:true\" title=\"Courtesy of Wikipedia\"> # * * * * *  command to execute\r\n # \u2502 \u2502 \u2502 \u2502 \u2502\r\n # \u2502 \u2502 \u2502 \u2502 \u2502\r\n # \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500 day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)\r\n # \u2502 \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 month (1 - 12)\r\n # \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 day of month (1 - 31)\r\n # \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 hour (0 - 23)\r\n # \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 min (0 - 59)<\/pre>\n<p style=\"text-align: justify;\">&#8220;Execute \/usr\/local\/sbin\/check_ gsmsmsd every minute&#8221;.<\/p>\n<p style=\"text-align: justify;\">As you can undestand from its name, it is in charge of check if gsmsmsd is running and relaunch it if necessary.<\/p>\n<pre class=\"lang:sh decode:true\">cat \/usr\/local\/sbin\/check_gsmsmsd<\/pre>\n<p style=\"text-align: justify;\">And here&#8217;s its content:<\/p>\n<pre class=\"lang:sh decode:true\" title=\"check_gsmsend\">#!\/bin\/sh\r\nif pidof gsmsmsd &gt; \/dev\/null\r\nthen\r\n    logger gsmsmsd is running\r\n    exit 0\r\nelse \r\n    logger gsmsmsd is not running, restart forced\r\n    rm -fr \/var\/spool\/sms\/* \r\n    \/usr\/bin\/sudo -u gsmsend \/usr\/bin\/gsmsmsd -d \/dev\/ttyS0 -s \/var\/spool\/sms\/  &amp;\r\nfi\r\n<\/pre>\n<p style=\"text-align: justify;\">Nothing special: the script checks wether the pid of gsmsmsd proces exists or not. If it exists, exit nicely logging that the daemon is running, else it logs that the daemon is not working, remove any contents from the sms spool directory and launches gsmsmsd as user gsmsend with the device on ttyS0 and the sms spool directory in \/var\/sms. \u00a0Not the &#8220;&amp;&#8221;, the process is being detached from the terminal.<\/p>\n<p style=\"text-align: justify;\">Do we have the sms spool directory? Bet not, in this case, let&#8217;s create it:<\/p>\n<pre class=\"lang:sh decode:true\">mkdir -p \/var\/spool\/sms\/<\/pre>\n<p style=\"text-align: justify;\">Now, let&#8217;s be sure that the user the gmssend daemon belongs to is able to read and write on that directory:<\/p>\n<pre class=\"lang:sh decode:true\">chown gsmsend. \/var\/spool\/sms\/<\/pre>\n<p style=\"text-align: justify;\">We have no more to do on the sms server side. Time to go on Nagios server.<\/p>\n<h6 style=\"text-align: justify;\">On the Nagios server side<\/h6>\n<p style=\"text-align: justify;\">Here is the actual Nagios notification plugin. Use it as the notification plugin for you sms host and service contact.<\/p>\n<p style=\"text-align: justify;\">Let&#8217;s give a look at the plugin:<\/p>\n<pre class=\"width:700 lang:sh decode:true\">#!\/bin\/bash\r\n\r\n# Few lines coded by Giorgio Zarrelli zarrelli@linux.it- \r\n# 2014.\r\n# This nagios plugin is free software, and comes with  \r\n# ABSOLUTELY NO WARRANTY. It may be used, redistributed   \r\n# and\/or modified under the terms of the GNU General \r\n# Public Licence (see \r\n# http:\/\/www.fsf.org\/licensing\/licenses\/gpl.txt).\r\n\r\nCAT=$(which cat)\r\nTR=$(which tr) \r\nFOLD=$(which fold)\r\nHEAD=$(which head)\r\n<\/pre>\n<p style=\"text-align: justify;\">The first lines, \u00a0start with the shabang and few command substitutions that will auto configure the script finding the right paths to the system utilities we are going to use.<br \/>\nThe following line will create a (pseudo) random string. On the sms server we will have to create a file containing the actual sms message and number, and each file must have a unique file name to avoid &#8220;collisions&#8221;.<\/p>\n<pre class=\"width:700 lang:sh decode:true\">RANDOM_STRING=$($CAT \/dev\/urandom | $TR -dc 'a-zA-Z0-9' | $FOLD -w 32 | $HEAD -n 1)<\/pre>\n<p style=\"text-align: justify;\">\/dev\/urandom is\u00a0character special device which gives access to the random numer generator of the kernel. With the string we wrote, we have a command substitution a bit more complex than usual:<\/p>\n<ol style=\"text-align: justify;\">\n<li>We extract some random byte from urandom with cat \u00a0\/dev\/urandom;<\/li>\n<li>Pass the result (|) to tr wich will \u00a0delete from the random string everything but letters and numbers, so we won&#8217;t have any strange chars. To be true, tr translates all the chars from \/dev\/urandom to the chars defined in the charset we provide after &#8220;-dc&#8221;;<\/li>\n<li>On the third step we pass the output of the previouse operation (|) to the fold utility which formats\u00a0everything in a 32 chars width column;<\/li>\n<li>Finally we take only the first line of the column an this is our random string.<\/li>\n<\/ol>\n<h6 style=\"text-align: justify;\">Passwordless\u00a0ssh connection<\/h6>\n<p style=\"text-align: justify;\">Well, what the plugin does is to put a file on the sms server. Easy, that&#8217;s it, but we want to do it in a secure way and here is where ssh becomes handy: you will setup everything we need to let our plugin connect to the sms-server using ssh and without any user\/password prompt.<\/p>\n<p style=\"text-align: justify;\">How do you reach this goal?<\/p>\n<p style=\"text-align: justify;\">First, keep in mind wich user will execute this script: it&#8217;s &#8220;nagios&#8221; user.<\/p>\n<p style=\"text-align: justify;\">So you have to setup a way to let nagios user to connect to the sms-server as users gmssend, so it will be able to write in the spool.<\/p>\n<p style=\"text-align: justify;\">To do the magic you must create an rsa private key and it&#8217;s \u00a0public counterpart and the transfer the public key on the sms server. Then you reference the public key in the<\/p>\n<pre class=\"lang:sh decode:true\">~\/.ssh\/authorized_keys<\/pre>\n<p style=\"text-align: justify;\">of the gsmsend user and so, when you will connect\u00a0the server will encrypt all the trafic with you public key of user nagios on the Nagios server and only this user will be able to decrypt it with the matching private key.<\/p>\n<p style=\"text-align: justify;\">Now it&#8217;s time to create a new pair of keys for the user nagios, so let&#8217;s &#8220;su&#8221; to this user:<\/p>\n<pre class=\"lang:sh decode:true \">su - nagios<\/pre>\n<p style=\"text-align: justify;\">As user nagios, you can finally issue the keygen command:<\/p>\n<pre class=\"lang:sh decode:true\">ssh-keygen -t rsa -b 4096 -f key.to.connect.to.sms.server\r\nGenerating public\/private rsa key pair.\r\nEnter passphrase (empty for no passphrase): \r\nEnter same passphrase again: \r\nYour identification has been saved in key.to.connect.to.sms.server.\r\nYour public key has been saved in key.to.connect.to.sms.server.pub.\r\nThe key fingerprint is:\r\n7f:d7:6a:e2:bf:a0:38:11:7c:3f:46:38:c8:1b:4d:3a nagios@nagios-server\r\nThe key's randomart image is:\r\n+---[RSA 4096]----+\r\n|                 |\r\n|          .      |\r\n|       o = .     |\r\n|        E = .    |\r\n|        S* +     |\r\n|        o.  +  . |\r\n|         ...o.. .|\r\n|        .. o.o.. |\r\n|        .....++. |\r\n+-----------------+<\/pre>\n<p style=\"text-align: justify;\">Time to create a safe directory to store the keys in:<\/p>\n<pre class=\"lang:sh decode:true\">mkdir ~\/.ssh\r\nchmod 700 ~\/.ssh<\/pre>\n<p style=\"text-align: justify;\">And now let&#8217;s move the keys in:<\/p>\n<pre class=\"lang:sh decode:true\">mv key.to.connect.to.sms.server* .ssh\/<\/pre>\n<p style=\"text-align: justify;\">Let&#8217;s restrict the permissions on the key files:<\/p>\n<pre class=\"lang:sh decode:true\">chmod 600 .ssh\/key.to.connect.to.sms.server*<\/pre>\n<p style=\"text-align: justify;\">Let&#8217;s check the permissions on files and directories:<\/p>\n<pre class=\"lang:sh decode:true\">ls -lah .ssh\/\r\ntotale 8,0K\r\ndrwx------ 2 nagios nagios   80 apr 17 21:49 .\r\ndrwxr-xr-x 3 nagios nagios   85 apr 17 21:39 ..\r\n-rw------- 1 nagios nagios 3,2K apr 17 21:34 key.to.connect.to.sms.server\r\n-rw------- 1 nagios nagios  741 apr 17 21:34 key.to.connect.to.sms.server.pub\r\n\r\n<\/pre>\n<p style=\"text-align: justify;\">Once you have the pair of key you can upload the public one to the sms-server using the ssh-copy-id utility with the following syntax:<\/p>\n<pre class=\"lang:sh decode:true\">ssh-copy-id -i public.key &lt;username&gt;@&lt;host&gt;<\/pre>\n<p style=\"text-align: justify;\">The username is the name of the user you will connect as to the sms-server, for this example is the gsmsend, since we want to write in its sms spool. The host is the sms-server and so:<\/p>\n<pre class=\"lang:sh decode:true\">ssh-copy-id -i .ssh\/key.to.connect.to.sms.server.pub gsmsend@sms-server\r\nThe authenticity of host 'sms-server (xxx.xxx.xxx.xxx)' can't be established.\r\nECDSA key fingerprint is d3:57:2c:e0:96:91:2e:7e:c2:ce:31:a0:ff:bf:06:79.\r\nAre you sure you want to continue connecting (yes\/no)? yes\r\n\/usr\/bin\/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed\r\n\/usr\/bin\/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys\r\ngsmsend@sms-server's password: \r\n\r\nNumber of key(s) added: 1<\/pre>\n<p style=\"text-align: justify;\">Now , try loggin onto the remote host using:<\/p>\n<pre class=\"lang:sh decode:true \">ssh gsmsend@sms-server<\/pre>\n<p style=\"text-align: justify;\">and check that only the key(s) you wanted were added.<\/p>\n<p style=\"text-align: justify;\">Time to see if you can login without being prompted for a password:<\/p>\n<pre class=\"lang:sh decode:true\">ssh -i key.to.connect.to.sms.server gsmsend@sms-server\r\nThe authenticity of host 'sms-server (xxx.xxx.xxx.xxx)' can't be established.\r\nECDSA key fingerprint is d3:57:2c:e0:96:91:2e:7e:c2:ce:31:a0:ff:bf:06:79.\r\nAre you sure you want to continue connecting (yes\/no)? yes\r\nWarning: Permanently added 'sms-server' (ECDSA) to the list of known hosts.\r\n\r\nThe programs included with the Debian GNU\/Linux system are free software;\r\nthe exact distribution terms for each program are described in the\r\nindividual files in \/usr\/share\/doc\/*\/copyright.\r\n\r\nDebian GNU\/Linux comes with ABSOLUTELY NO WARRANTY, to the extent\r\npermitted by applicable law.\r\nLast login: Fri Apr 17 22:11:29 2015 from nagios-server\r\n<\/pre>\n<p style=\"text-align: justify;\">Well, WOW, you are in and no password prompt seen in the meanwhile!<\/p>\n<p style=\"text-align: justify;\">We can make things easier writing down some lines of configuration so that the ssh connection to the sms-server will act as we will.<\/p>\n<p style=\"text-align: justify;\">Configure a ssh connection to a host for a user is a straightforward task: go to the user&#8217;s home directory, and check for the presence of a<\/p>\n<pre class=\"lang:sh decode:true \">.ssh<\/pre>\n<p style=\"text-align: justify;\">directory, with the proper access rights: we already created it, so you should have it and with the proper access rights. If you don&#8217;t see it, look back in this post and you&#8217;ll find how to create.<\/p>\n<p style=\"text-align: justify;\">Move inside the .ssh directory:<\/p>\n<pre class=\"lang:sh decode:true \">cd .ssh<\/pre>\n<p style=\"text-align: justify;\">There you&#8217;ll find the private and public keys we already created. Ignore them, now it&#8217;s time to edit a new file:<\/p>\n<pre class=\"lang:sh decode:true \">vi .config<\/pre>\n<p style=\"text-align: justify;\">Here you are going to write the following lines:<\/p>\n<pre class=\"lang:sh decode:true\">\"Host sms-server\"\r\n\"AddressFamily inet\"\r\n\"ConnectionAttempts 10\"\r\n\"ForwardAgent no\"\r\n\"ForwardX11 no\"\r\n\"ForwardX11Trusted no\"\r\n\"GatewayPorts yes\"\r\n\"HostBasedAuthentication no\"\r\n\"HostKeyAlias sms-server\"\r\n\"HostName sms-server\"\r\n\"IdentityFile ~\/.ssh\/key.to.connect.to.sms.server\"\r\n\"PasswordAuthentication no\"\r\n\"Port 22\"\r\n\"Protocol 2\"\r\n\"ServerAliveCountMax 3\"\r\n\"ServerAliveInterval 15\"\r\n\"TCPKeepAlive no\"\r\n\"User gsmsend\"<\/pre>\n<p style=\"text-align: justify;\">Let&#8217;s see what do they mean, line by line:<\/p>\n<pre class=\"lang:sh decode:true\">\"Host sms-server\"<\/pre>\n<p style=\"text-align: justify;\">As said in the manual<\/p>\n<pre class=\"lang:sh decode:true\">man ssh_config<\/pre>\n<p style=\"text-align: justify;\">The keyword host limits the scope of the following declarations. Take the word following Host as a label for a bunch of instructions and give it a proper name.<\/p>\n<pre class=\"lang:sh decode:true\">\"AddressFamily inet\"<\/pre>\n<p style=\"text-align: justify;\">That is for the &#8220;kind&#8221; of address we use to connect to the remote host. \u00a0Any, inet to use ipv4 only or inet6 for ipv6.<\/p>\n<pre class=\"lang:sh decode:true\">\"ConnectionAttempts 10\"<\/pre>\n<p style=\"text-align: justify;\">Let&#8217;s say that after 10 tries we give up. One try per second. The default is 1.<\/p>\n<pre class=\"lang:sh decode:true\">\"ForwardAgent no\"<\/pre>\n<p style=\"text-align: justify;\">Do you want to forward to the remote host the connection to the autentication agent ? No, trust me, you do not want.<\/p>\n<pre class=\"lang:sh decode:true\">\"ForwardX11 no\"<\/pre>\n<p style=\"text-align: justify;\">We do not need, we do not use, better to switch it off. We do not want to have the\u00a0X11 connections \u00a0automatically redirected over the secure channel and DISPLAY\u00a0set.<\/p>\n<pre class=\"lang:sh decode:true\">\"ForwardX11Trusted no\"<\/pre>\n<p style=\"text-align: justify;\">We do not want remote X11 clients to fiddle with data owned by trusted X11 clients.<\/p>\n<pre class=\"lang:sh decode:true\">\"GatewayPorts yes\"<\/pre>\n<p style=\"text-align: justify;\">We allow remote hosts to connect to local forwarded ports. Can be useful.<\/p>\n<pre class=\"lang:sh decode:true\">\"HostBasedAuthentication no\"<\/pre>\n<p style=\"text-align: justify;\">We do not need to try rhosts based authentication with public key authentication.<\/p>\n<pre class=\"lang:sh decode:true\">\"HostKeyAlias sms-server\"<\/pre>\n<p style=\"text-align: justify;\">Is just an alias to be used instead of the real host name when looking up or saving the\u00a0host key in the host key database files. Useful when you have multiple servers running on the same host.<\/p>\n<pre class=\"lang:sh decode:true\">\"HostName sms-server\"<\/pre>\n<p style=\"text-align: justify;\">It should specify the real host name we want to log into. Well we use it to specify an alias for the host we want to connect to. \u00a0Write what makes it easy for you to remember the host you want to connect to.<\/p>\n<pre class=\"lang:sh decode:true \">\"IdentityFile ~\/.ssh\/key.to.connect.to.sms.server\"<\/pre>\n<p style=\"text-align: justify;\">Easy to guess, here we point to the file containing the identity we will use to autenticate to the remote host.<\/p>\n<pre class=\"lang:sh decode:true\">\"PasswordAuthentication no\"<\/pre>\n<p style=\"text-align: justify;\">We are using an identity file to authenticate so let&#8217;s make sure we do not fiddle with passwords.<\/p>\n<pre class=\"lang:sh decode:true\">\"Port 22\"<\/pre>\n<p style=\"text-align: justify;\">Here we define wich remote port to connect to. The port 22 is the standard for the ssh service but if you want to make more difficult a brute force attack from automated penetration tools, change the port on the remote host and write here the new value.<\/p>\n<pre class=\"lang:sh decode:true\">\"Protocol 2\"<\/pre>\n<p style=\"text-align: justify;\">Really? You would use the old protocol version 1? Not at all!<\/p>\n<pre class=\"lang:sh decode:true\">\"ServerAliveCountMax 3\"<\/pre>\n<p style=\"text-align: justify;\">It sets the number of max retry sending\u00a0server alive messages and not receiving an answer from the remote host. Let&#8217;s take it as a timeout counter. If the host doesn&#8217;t answer to the server alive messages for 3 times, the ssh session will be disconnected.<\/p>\n<pre class=\"lang:sh decode:true\">\"ServerAliveInterval 15\"<\/pre>\n<p style=\"text-align: justify;\">This keyword sets the interval in seconds after wich if no data is received from the remote server ssh will send a server alive message through the ssh encrypted channel.<\/p>\n<pre class=\"lang:sh decode:true\">\"TCPKeepAlive no\"<\/pre>\n<p style=\"text-align: justify;\">TCP keepalive are not sent through a secure channel and so they are spoofable. Better not to use it.<\/p>\n<pre class=\"lang:sh decode:true\">\"User gsmsend\"<\/pre>\n<p style=\"text-align: justify;\">This is the user on the remote host we are logging as.<\/p>\n<h6 style=\"text-align: justify;\">The dirty thingy string<\/h6>\n<pre class=\"width:700 lang:sh decode:true\">$SSH SMS_SERVER \"echo -e \"$MOBILE_NUMBER\\\"\\\\n\\\"$NOTIFICATION_TEXT\" &gt; $SMS_SPOOL_DIR\/$RANDOM_STRING\"<\/pre>\n<p style=\"text-align: justify;\">At the end of the script you&#8217;ll find the string that actual do the dirty job.<\/p>\n<ol style=\"text-align: justify;\">\n<li>First it connects to the remote hosts;<\/li>\n<li>Then, on the remote host, it echoes the mobile number;<\/li>\n<li>A new line char follows;<\/li>\n<li>And on the second line there will be the notification text;<\/li>\n<li>Finally, the standard output to \u00a0a file in the spool directory, using as a file name \u00a0a random string calculated at the beginning of the script .<\/li>\n<\/ol>\n<p style=\"text-align: justify;\">That&#8217;s it. We won&#8217;t look at the rest of the code, it&#8217;s quite simple and should give us no problems.<\/p>\n<p style=\"text-align: justify;\">Just have a look to a handy variable definition:<\/p>\n<pre class=\"width:700 lang:sh decode:true\">SMS_SERVER=${SMS_SERVER:=\"change.me\"}<\/pre>\n<p style=\"text-align: justify;\">When the variable is defined with a<\/p>\n<pre class=\"width:700 lang:sh decode:true\">${SOMETHING:=\"SOMEVALUE\"}<\/pre>\n<p style=\"text-align: justify;\">means that if you do not pass any value, the variable defaults to<\/p>\n<pre class=\"lang:sh decode:true \">SOMEVALUE<\/pre>\n<p style=\"text-align: justify;\">call it a fallback value.<\/p>\n<p style=\"text-align: justify;\">Here you find the actual script:<\/p>\n<pre class=\"width:700 lang:sh decode:true \">#!\/bin\/bash\r\n\r\n# Few lines coded by Giorgio Zarrelli zarrelli@linux.it- \r\n# 2014.\r\n# This nagios plugin is free software, and comes with  \r\n# ABSOLUTELY NO WARRANTY. It may be used, redistributed   \r\n# and\/or modified under the terms of the GNU General \r\n# Public Licence (see \r\n# http:\/\/www.fsf.org\/licensing\/licenses\/gpl.txt).\r\n\r\nCAT=$(which cat)\r\nTR=$(which tr)\r\nFOLD=$(which fold)\r\nHEAD=$(which head)\r\nRANDOM_STRING=$($CAT \/dev\/urandom | $TR -dc 'a-zA-Z0-9' | $FOLD -w 32 | $HEAD -n 1)\r\nSMS_SPOOL_DIR=\"\/var\/spool\/sms\"\r\nECHO=$(which echo)\r\nSSH=$(which ssh)\r\nSMS_SERVER=${SMS_SERVER:=\"change.me\"}\r\nMOBILE_NUMBER=${MOBILE_NUMBER:=\"+1234567890\"}\r\nNOTIFICATION_TEXT=${NOTIFICATION_TEXT:=\"CHANGE ME\"}\r\n\r\n\r\nprint_license() {\r\n\r\n$ECHO \"\"\r\n$ECHO \"This nagios plugin is free software, and comes with ABSOLUTELY\" \r\n$ECHO \"NO WARRANTY. It may be used, redistributed and\/or modified under\" \r\n$ECHO \"the terms of the GNU General Public Licence (see\" \r\n$ECHO \"http:\/\/www.fsf.org\/licensing\/licenses\/gpl.txt).\"\r\n$ECHO \"\"\r\nexit 0\r\n\r\n\r\n}\r\n\r\nprint_help() {\r\n\r\n$ECHO \"\"\r\n$ECHO \"This plugins allows you to send sms notifications using a remote gsmsend server.\"\r\n$ECHO \"\"\r\n$ECHO \"It requires three parameters:\"\r\n$ECHO -e \"\\n\"\r\n$ECHO \" -s name of the sms server it must be the same name you wrote in config file in .ssh dir of the nagios user\"\r\n$ECHO -e \"\\n\"\r\n$ECHO \" -n +xxxxxxx is the mobile number of the of the contact receiving the notification\"\r\n$ECHO -e \"\\n\"\r\n$ECHO \" -t 'Message' is the message to send.\"\r\n$ECHO \"\"\r\n$ECHO \"\"\r\n$ECHO \"Other parameters:\"\r\n$ECHO -e \"\\n\"\r\n$ECHO \"-l Prints the license of this program\"\r\n$ECHO -e \"\\n\"\r\n$ECHO \"-c Prints a .ssh\/config example\"\r\n$ECHO \"\"\r\nexit 0\r\n}\r\n\r\n\r\nprint_ssh_config() {\r\n\r\n$ECHO \"\"\r\n$ECHO \"Host sms-server\"\r\n$ECHO \"AddressFamily inet\"\r\n$ECHO \"ConnectionAttempts 10\"\r\n$ECHO \"ForwardAgent no\"\r\n$ECHO \"ForwardX11 no\"\r\n$ECHO \"ForwardX11Trusted no\"\r\n$ECHO \"GatewayPorts yes\"\r\n$ECHO \"HostBasedAuthentication no\"\r\n$ECHO \"HostKeyAlias sms-server\"\r\n$ECHO \"HostName xxx.xxx.xxx.xxx\"\r\n$ECHO \"IdentityFile ~\/.ssh\/my.private.key.to.gsmsend.server.key\"\r\n$ECHO \"PasswordAuthentication no\"\r\n$ECHO \"Port 22\"\r\n$ECHO \"Protocol 2\"\r\n$ECHO \"ServerAliveCountMax 3\"\r\n$ECHO \"ServerAliveInterval 15\"\r\n$ECHO \"TCPKeepAlive no\"\r\n$ECHO \"User gsmsend\"\r\n$ECHO \"\"\r\n\r\n\r\n}\r\n\r\n\r\n# Check wheter the script has at least one argument.\r\n\r\nif [ $# -lt 1 ]\r\n\r\nthen\r\nprint_help\r\nexit $STATE_UNKNOWN\r\nfi\r\n\r\n\r\ncase \"$1\" in\r\n-h | --help)\r\nprint_help\r\nexit $STATE_OK\r\n;;\r\n-l | --license)\r\nprint_license\r\nexit $STATE_UNKNOWN\r\n;;\r\n-c | --config)\r\nprint_ssh_config;\r\nexit $STATE_UNKNOWN\r\n;; \r\n-n | --number)\r\nshift\r\nMOBILE_NUMBER=$1\r\n;;\r\n-t | --text)\r\nshift\r\nNOTIFICATION_TEXT=$1\r\n;;\r\n-s | --server)\r\nshift\r\nSMS_SERVER=$1\r\n;;\r\n*) $ECHO \"Unknown argument: $1\"\r\nprint_help\r\nexit $STATE_UNKNOWN\r\n;;\r\nesac\r\nshift\r\ndone\r\n\r\n$SSH SMS_SERVER \"echo -e \"$MOBILE_NUMBER\\\"\\\\n\\\"$NOTIFICATION_TEXT\" &gt; $SMS_SPOOL_DIR\/$RANDOM_STRING\"<\/pre>\n<h6 style=\"text-align: justify;\">Setting up Nagios to send SMS<\/h6>\n<p style=\"text-align: justify;\">Now we have all the bits we require to send some notifications using SMS, what we need now is to glue all together in Nagios.<\/p>\n<p style=\"text-align: justify;\">We need to:<\/p>\n<ol style=\"text-align: justify;\">\n<li>Copy the code above and save on a file;<\/li>\n<li>Upload the file on the Nagios plugin directory on the Nagios server;<\/li>\n<li>Make the file executable by the nagios user;<\/li>\n<li>Create a Nagios command to call the script from within Nagios;<\/li>\n<li>Create a contact which will use this command as a notification command;<\/li>\n<li>Assign the command.<\/li>\n<\/ol>\n<p style=\"text-align: justify;\">Let&#8217;s say we call the new script<\/p>\n<pre class=\"lang:sh decode:true\">send_sms.sh<\/pre>\n<p style=\"text-align: justify;\">Copy it on the Nagios plugin directory server, make nagios user its owner<\/p>\n<pre class=\"lang:sh decode:true\">chown nagios. send_sms.sh<\/pre>\n<p style=\"text-align: justify;\">and make it executable by Nagios, restricting a bit the rights on it:<\/p>\n<pre class=\"lang:sh decode:true \">chmod 550 send_sms.sh<\/pre>\n<p style=\"text-align: justify;\">Now we create two different notify command, one for hosts notifications and another for services notifications:<\/p>\n<pre class=\"lang:sh decode:true\">define command {\r\ncommand_name notify-host-by-sms\r\ncommand_line $USER1$\/send_sms.sh -n '$CONTACTPAGER$' -t \"'$HOSTNAME$' '$HOSTSTATE$' '$DATE$' '$TIME$'\"\r\nregister 1\r\n}\r\n\r\ndefine command {\r\ncommand_name notify-service-by-sms\r\ncommand_line $USER1$\/send_sms.sh -n '$CONTACTPAGER$' -t \"'$HOSTNAME$' '$SERVICEDESC$' '$SERVICESTATE$' '$SERVICEOUTPUT$' '$DATE$' '$TIME$'\"\r\nregister 1\r\n}<\/pre>\n<p style=\"text-align: justify;\">Notice that<\/p>\n<pre class=\"lang:sh decode:true\">$USER1$<\/pre>\n<p style=\"text-align: justify;\">points to the Nagios plugins directory and is defined in the file<\/p>\n<pre class=\"lang:sh decode:true \">resource.cfg<\/pre>\n<p style=\"text-align: justify;\">All the other variables are passed to the script by Nagios. If you want\u00a0more informations on Nagios macros, follow this link<\/p>\n<p style=\"text-align: justify;\">http:\/\/nagios.sourceforge.net\/docs\/3_0\/macros.html<\/p>\n<p style=\"text-align: justify;\">Now it&#8217;s time to create a contact which will use the new command<\/p>\n<pre class=\"lang:sh decode:true \">define contact {\r\ncontact_name\u00a0oncall-sms\r\nalias\u00a0SMS notifications to on call mobile\r\nhost_notifications_enabled 1\r\nservice_notifications_enabled 1\r\nhost_notification_period 24x7\r\nservice_notification_period 24x7\r\nhost_notification_options d,u,r,f,s\r\nservice_notification_options w,u,c,r,f,s\r\nhost_notification_commands notify-host-by-sms\r\nservice_notification_commands notify-service-by-sms\r\ncan_submit_commands 1\r\nretain_status_information 0\r\nretain_nonstatus_information 1\r\npager +XXXXXXXXXXXX\r\nregister 1\r\n}<\/pre>\n<p style=\"text-align: justify;\">Just put after<\/p>\n<pre class=\"lang:sh decode:true \">pager<\/pre>\n<p style=\"text-align: justify;\">the mobile number to send SMS notifications to.<\/p>\n<p style=\"text-align: justify;\">Let&#8217;s attach the SMS notification to a service<\/p>\n<pre class=\"lang:sh decode:true\">define service {\r\nservice_description\u00a0On call service\r\nhost_name my_host\r\ncheck_command my_command\r\nis_volatile 0\r\nmax_check_attempts 3\r\ncheck_interval 5\r\nretry_interval 1\r\nactive_checks_enabled 1\r\npassive_checks_enabled 1\r\ncheck_period 24x7\r\nparallelize_check 1\r\nobsess_over_service 1\r\ncheck_freshness 0\r\nevent_handler_enabled 1\r\nflap_detection_enabled 1\r\nprocess_perf_data 1\r\nretain_status_information 1\r\nretain_nonstatus_information 1\r\nnotification_interval 1440\r\nnotification_period 24x7\r\nnotification_options w,u,c,r\r\nnotifications_enabled 1\r\ncontacts oncall-sms\r\nfailure_prediction_enabled 1\r\nregister 1\r\n}<\/pre>\n<p style=\"text-align: justify;\">Now, let&#8217;s do the same for the host:<\/p>\n<pre class=\"lang:sh decode:true \">define host {\r\nhost_my_host\r\ncheck_command check-host-alive\r\nmax_check_attempts 4\r\ncheck_interval 5\r\nretry_interval 1\r\npassive_checks_enabled 1\r\ncheck_period 24x7\r\ncheck_freshness 1\r\nfreshness_threshold 0\r\nevent_handler_enabled 1\r\nflap_detection_enabled 1\r\nprocess_perf_data 1\r\nretain_status_information 1\r\nretain_nonstatus_information 1\r\ncontacts oncall-sms\r\nnotification_interval 1440\r\nnotification_period 24x7\r\nnotification_options d,u,r,f,s\r\nnotifications_enabled 1\r\nfailure_prediction_enabled 1\r\nregister 1\r\n}<\/pre>\n<p style=\"text-align: justify;\">Keep in mind that these are just examples: modify your Nagios objects accordingly.<\/p>\n<p style=\"text-align: justify;\">Final step, check that the modified configuration is not broken<\/p>\n<pre class=\"lang:sh decode:true \">nagios -v \/path\/to\/nagios\/main\/config\/file\/nagios.cfg<\/pre>\n<p style=\"text-align: justify;\">If it&#8217;s all ok, reload Nagios and try to get a CRITICAL notification on a fake service or host witch uses oncall-sms as contact. Don&#8217;t you have it? Create a fake just for testing and if you do not see any errors and everything is working fine, attach the new contact to your most valuable host and services.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Critical, that&#8217;s a point you would not ever want to reach. Monitoring is all, or quite all, on recovering a situation before it becomes a problem. When it becomes a problem, you must move quickly and solve the issue. So, \u00a0when you have a problem, we do not need a genius, we need flat, plain &hellip;<\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[31,326],"tags":[494,463,138,177,462],"class_list":["post-1626","post","type-post","status-publish","format-standard","hentry","category-gnulinux","category-nagios","tag-nagios","tag-notification","tag-plugin","tag-script","tag-sms","without-featured-image"],"_links":{"self":[{"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/posts\/1626","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/comments?post=1626"}],"version-history":[{"count":0,"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/posts\/1626\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/media?parent=1626"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/categories?post=1626"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/tags?post=1626"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}