Lets face it, some of us may have had our share of FreePBX/Asterisk compromises and abusers almost always use the facility to make international calls to exotic numbers. The bill at the end of the month is already too late and there’s significant monetary damage. While its good to know in realtime of what’s going on, its of course best to prevent anything to compromise your server. see this guide here to get you started. Here’s a small script we wrote that works for me to check as often as cronjob/Nagios allows it to, based on the parameters you set and report back via email if the script is triggered. This script here does the following;
- It checks the CDR for n minutes of past records also set by flags
- Uses filters based on the dst column on your CDR to match that you specify during execution (the parameters), this can be prefixes or whole numbers, and run multiple instances.
- You can set the flag to check the prefix and the number of digits which is same or greater so that you won’t catch local calls, normally international calls have higher number of called digits, i.e. > 10
- To automatically check or do it almost realtime, you can use cron on your server locally (It can also work with Nagios too, however, this guide does not cover configuring on Nagios, set NAGIOSMODE=YES). If you set Nagiosmode, it will not independently send out email and instead your Nagios server will decide what to do according to what you’ve set it to.
- Be sure to change SYSADMINEMAIL, FROMUSER,SERVER,PORT,DATABASE,TABLE,USER,PASS in the script relevant to your setup
Getting started:
- Copy paste this script below in /usr/bin/checkintl.sh (or any location of your choice)
- Modify the parameters as described below
- Make it executable (chmod +x /usr/bin/checkintl.sh)
- Put this script in a cronjob if you wish to automate checking (crontab –e), e.g. like this */15 * * * * /usr/bin/checkintl.sh -w 5 -c 10 -i 30 -p 00:6,900:6″
- Above cronjob does the checks for every 15 minutes 30 records in CDR and warns on 5 critical alerts on 10 for pattern 00, with length greater than or equals 6 numbers and for pattern 900 with length greater than or equals 6 numbers
- Test manually. You surely can run this manually and try to invoke the trigger by making n number of calls and you should get an email alert based on the email address you specified
- This script requires a MySQL CDR for Asterisk (therefore making it perfect for use with FreePBX, out of the box)
- IMPORTANT: THIS SCRIPT CHECKS AFTER ASTERISK WRITES TO CDR AND ALSO WHILE IN CALL COMBINED, SO CHECK BOTH PLACES
Set these below before running the script
- The emailtoSYSADMINEMAIL, emailFROMUSER,SERVERip,serverPORT,cdrDATABASE,cdrTABLE,dbUSER,dbPASS
- If using Nagios, just set the flag NAGIOSMODE=YES
- Everything copied from below must be in a single line, no line breaks
Here’s the script, copy paste this as per item 1. getting started guide.
###PASTE START### #!/bin/bash RELEASE=”Version 2″ AUTHOR=”[email protected]” PROGNAME=”checkintl.sh” # # PRE-REQ # – BASH 4.1.X or higher # – FREEPBX and MYSQL of course # – ASTERISK WITH CDR SUPPORT # – ACCESS TO ASTERISKCDR DB # – CLI tools like mail, awk, tr, curl,grep,mysql bin # – ABLE TO SEND EMAIL OUT USING #mail with exim etc.. # # ChangeLog # – FIRST RELEASE # – 1.1 Minor changes encapsulating output for compatibility # – 2.0 Updated checking algorithm # # Place a cronjob, e.g. check every 5 minutes # */15 * * * * /<locationofscript>/checkintl.sh # # NOTHING TO CHANGE HERE STATE_OK=0 STATE_WARNING=1 STATE_CRITICAL=2 STATE_UNKNOWN=3 USERDATEFORMAT=`date +%d-%m-%Y_%H:%M:%S` # ########MODIFY HERE######## NAGIOSMODE=NO SYSADMINEMAIL=[email protected] #add more separated by commas FROMUSER=[email protected] EMAILSUBJECT=”CALL ALERTER – By Astiostech” server=”localhost” port=”3306″ database=”asteriskcdrdb” table=”cdr” user=”<mysqluser>” pass=”<mysqlpass>” ########END MODIFY######## # # ##FUNCTIONS function sendoutmail() { ( echo [$USERDATEFORMAT] – $2 ) | mail -aFrom:$FROMUSER -s “$EMAILSUBJECT” $SYSADMINEMAIL return } # print_release() { echo “$RELEASE $AUTHOR” } # print_usage() { clear echo “” echo “$PROGNAME $RELEASE – Checks international calls” echo “” echo “Usage: checkintl.sh [flags]” echo “” echo “e.g : ./checkintl.sh -w 5 -c 10 -i 30 -p 00:6,900:6” echo “Where it warns at 5 intl calls, and makes a critcal alert 10 calls at every 30 minutes “ echo “of past CDR record for prefixes 00 and 900 combined total of equals to or higher than 6 digits” echo “” echo “Flags:” echo ” -w <number> : Warning value for number of international calls.” echo ” -c <number> : Critical value for number of international calls” echo ” -i <number> : How many minutes of CDR data to poll to evaluate” echo ” -p <prefix:length,prefix:length,prefix:length> : Comma separated prefixes with IDD, e.g. 900:5,800:5,00:5. Length value is equals or higher. Default is 5 or higher chars” echo ” -h Show this page” echo “” echo “Usage: $PROGNAME –help” echo “” } print_help() { print_usage echo “” echo “This plugin will check international calls made on Asterisk CDR” echo “” exit 0 } # Parse parameters while [ $# -gt 0 ]; do case “$1” in -h | –help) print_help exit $STATE_OK ;; -v | –version) print_release exit $STATE_OK ;; -w | –warning) shift WARNING_THRESHOLD=$1 ;; -c | –critical) shift CRITICAL_THRESHOLD=$1 ;; -i | –interval) shift INTERVAL=$1 ;; -p | –prefix) shift PREFIXES=$1 ;; *) echo “Unknown argument: $1” print_usage exit $STATE_UNKNOWN ;; esac shift done # if [[ “$WARNING_THRESHOLD” == “” ]]; then echo “Warning value not set, quitting..” exit $STATE_OK fi if [[ “$CRITICAL_THRESHOLD” == “” ]]; then echo “Critical value not set, quitting..” exit $STATE_OK fi if [[ “$INTERVAL” == “” ]]; then echo “Interval value not set, quitting..” exit $STATE_OK fi if [[ “$PREFIXES” == “” ]]; then echo “You must define at least one prefix, quitting..” exit $STATE_OK fi # # SET VARIABLES warning_value=”$WARNING_THRESHOLD” critical_value=”$CRITICAL_THRESHOLD” interval=”$INTERVAL” PREFIX=”$PREFIXES” MYSQLBIN=`which mysql` MYAST=`which asterisk` # # CONSTANTS todate=`/bin/date` unixtime=`/bin/date –date=”$todate” +%s` filename=mycdrlogforintl.$unixtime.txt # # DB CONNECTION CHECKER checkdb=`$MYSQLBIN -b -n -N -s -h $server -P $port -u $user -p$pass -D $database -e “show databases;” | grep -c $database` # START CHECKING CALLS IFS=$OLDIFS IFS=, if [[ $checkdb -lt 1 ]]; then echo “Error connecting to MySQL CDR DB” if [[ “$NAGIOSMODE” == “NO” ]]; then sendoutmail -f “Error connecting to MySQL CDR DB” fi exit $STATE_UNKNOWN else for i in $PREFIX; do i=`echo $i | awk -F’:’ ‘{print $1}’` length=`echo $i | awk -F’:’ ‘{print $2}’` if [[ $length == 0 ]]; then length=5 fi rawdata=`$MYSQLBIN -b -n -N -s -h $server -P $port -u $user -p$pass -D $database -e “SELECT dst FROM $table WHERE cdr.calldate > now() – INTERVAL $interval MINUTE and CHAR_LENGTH(dst) >= ‘$length’;” | grep -o ‘[0-9]*’ | grep -e ‘<‘$i’.*>’ | tr -d ‘ ‘` subtotal=`echo $rawdata | awk ‘NF > 0’ | wc -l` echo $rawdata >> /tmp/$filename ((totalcalls+=$subtotal)) done for n in $PREFIX; do n=`echo $n | awk -F’:’ ‘{print $1}’` length=`echo $n | awk -F’:’ ‘{print $2}’` if [[ $length == 0 ]]; then length=5 fi rawdata2=`$MYAST -rx “core show channels concise” |grep Outgoing | grep -e ‘<‘$n’.*>’ ` if [[ “$rawdata2” != “” ]]; then subtotal=`echo $rawdata2 | awk ‘NF > 0’ | wc -l` echo $rawdata2 >> /tmp/$filename ((totalcalls+=$subtotal)) fi done IFS=$OLDIFS fi csved=`cat /tmp/$filename | tr -d ‘ ‘ | awk ‘NF > 0’ | tr “n” “,”` # # Now we start reporting to Nagios/sendmail if required # if [[ “$totalcalls” == “0” ]]; then echo “OK:$totalcalls |intl_calls=$totalcalls;$warning_value;$critical_value” exit $STATE_OK elif [[ “$totalcalls” -ge “$critical_value” ]]; then echo “CRITICAL:$totalcalls LISTING:[START] $csved[END]|intl_calls=$totalcalls;$warning_value;$critical_value” if [[ “$NAGIOSMODE” == “NO” ]]; then sendoutmail -f “CRITICAL:$totalcalls LISTING:[START]$csved[END] | Critical threshold set: $critical_value” fi exit $STATE_CRITICAL elif [[ “$totalcalls” -ge “$warning_value” ]]; then echo “WARNING:$totalcalls LISTING:[START] $csved[END]|intl_calls=$totalcalls;$warning_value;$critical_value” if [[ “$NAGIOSMODE” == “NO” ]]; then sendoutmail -f “WARNING:$totalcalls LISTING:[START] $csved[END] | Warning threshold set: $warning_value” fi exit $STATE_WARNING else echo “TOTAL:$totalcalls LISTING:[START] $csved[END]|intl_calls=$totalcalls;$warning_value;$critical_value” exit $STATE_OK fi ###PASTE END### |