Tuesday, July 24, 2012

Email important log entries (Tomato firmware)

My last post went though getting your router setup to send email. Now, to write a simple script to check the log and send an email. The router runs an extremely lean "sh" shell and is very limited. The script looks for key words and sends those lines from the log. It makes sure not to send logs that have already been sent.


Router: Asus RT-N16 (newegg)
Firmware: Tomato-Toastman (version: tomato-K26USB-1.28.7500.2MIPSR2Toastman-RT-VPN.trx)
Note: TomatoUSB or any mod running kernel 2.6 should work. Iptables in kernel 2.4 requires some tweaks (see below).





Change the highlighted line with key words to check the log for (not case sensitive). Separate each word by a pipe.

Place this script in /opt/scripts/email_knock.sh
#!/bin/sh

CHECK_WORD='knock|bad'
LOG="/var/log/messages"
LOG_FOUND="/opt/scripts/log_last_found"
LOG_LAST="/opt/scripts/log_last_check"

# Get the last time the log was checked.
if [ -f $LOG_LAST ] && [ -r $LOG_LAST ]
then
  MIN_DATE=$(cat $LOG_LAST)
else
  MIN_DATE=0
fi

# Write the new last checked time as now.
CUR_DATE=`date +%s`
echo $CUR_DATE > $LOG_LAST

# Create vars for the current year and list of month names.
YR=`date +%Y`
MONTHS="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"

# Loop though any lines in the log that match words to check.
grep -iE "$CHECK_WORD" $LOG |
{
while read LINE
do
  # Get the log's date and time.
  LDATE=`echo $LINE | awk '{print $1,$2,$3}'`
  
  # Loop though the months and replace the month's name with YYYY-MM-
  cnt=1
  for i in $MONTHS
  do
    LDATE=`echo $LDATE | sed 's/'$i\ '/'$YR-$cnt-'/'`
    let cnt=$cnt+1
  done

  # Change the date to seonds.
  LDATE=`date --date="$LDATE" +%s`

  # Loop the next line if the log line time is before the last check time  
  if [ $MIN_DATE -gt $LDATE ]; then continue ; fi 
  
  # Write the log line to a temp log file if before current time.
  if [ $LDATE -le $CUR_DATE ]; then echo $LINE >> $LOG_FOUND ; fi
  
  # Leave while loop if log line time is after current time.
  if [ $LDATE -gt $CUR_DATE ]; then break ; fi

done

# If a the log lines found was written, send email.
if [ -f $LOG_FOUND ] && [ -r $LOG_FOUND ]
then
  # Double space the temp log for readability.
  sed -i G $LOG_FOUND
  
  # Send temp log.
  /opt/bin/python2.7 "/opt/scripts/mail_message.py" "$(cat $LOG_FOUND)"
  
  # Remove temp log.
  rm $LOG_FOUND
fi
}
The below code will create a small script and execute the mail check script every 600 seconds (10min). Log into the Tomato admin interface and navigate to Administration -> Scripts -> INIT Tab. Paste the following code, save and reboot your router.
#!/bin/sh
#################
# Create the log email timer.
#################
echo '#!/bin/sh
while true;do
     [ -f /opt/scripts/email_knock.sh ] && sh /opt/scripts/email_knock.sh
     sleep 600
done
fi
'>/tmp/home/root/email_log.sh

# Make executable.
chmod +x /tmp/home/root/email_log.sh

# Start the email log check. Write process ID file.
sh /tmp/home/root/email_log.sh &
echo $! > /tmp/home/root/email_log.sh.pid
logger -s "### email_log process $! started ###"

Happy Hacking!

2 comments: