Permalink
Switch branches/tags
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 71 lines (62 sloc) 2.79 KB
#!/bin/bash
#
# Script that extracts information from the latest request in the access
# log and enriches this with info from the error-log.
#
# Script is meant to be called regularly via watch.
#
ACCESSLOG="$1"
ERRORLOG="$2"
ACCESS_IGNORE_REGEX="(heartbeat)"
if [ -z "$ACCESSLOG" ]; then
echo "Accesslog not passed via commandline. Please pass path to accesslog as first parameter. This is fatal. Aborting."
exit 1
fi
if [ ! -f "$ACCESSLOG" ]; then
echo "Accesslog $ACCESSLOG not found. This is fatal. Aborting."
exit 1
fi
if [ -z "$ERRORLOG" ]; then
echo "Errorlog not passed via commandline. Please pass path to errorlog as first parameter. This is fatal. Aborting."
exit 1
fi
if [ ! -f "$ERRORLOG" ]; then
echo "Errorlog $ERRORLOG not found. This is fatal. Aborting."
exit 1
fi
ACCESSLINE=$(tail -200 $ACCESSLOG | grep -E -v "$ACCESS_IGNORE_REGEX" | tail -1)
ID=$(echo "$ACCESSLINE" | egrep -o " [a-zA-Z0-9@-]{24,27} " | tr -d " ")
METHOD_PATH=$(echo "$ACCESSLINE" | cut -d\ -f6,7 | cut -b2-)
STATUS=$(echo "$ACCESSLINE" | cut -d\ -f9)
SCORES=$(echo "$ACCESSLINE" | egrep -o "[0-9-]+ [0-9-]+$")
TIME=$(echo "$ACCESSLINE" | cut -d\ -f5 | cut -d. -f1)
echo "$(date +"%H:%M:%S") watching: $ACCESSLOG $ERRORLOG"
echo
echo "$TIME $STATUS $SCORES $METHOD_PATH ($ID)"
echo
echo "ModSecurity Rules Triggered:"
MODSEC=$(tail -500 $ERRORLOG | grep $ID | grep -o -E " (at|against) .*\[file.*\[id \"[0-9]+.*\[msg \"[^\"]+" | tr -d \" | sed -e "s/ at the end of input at/ at/" -e "s/ required. /. /" -e "s/\[rev .*\[msg/[msg/" -e "s/\. / /" -e "s/(Total .*/(Total ...) .../" | tr -d \] | cut -d\ -f3,9,11- |
sed -e "s/^\([^ ]*\) \([^ ]*\)/\2 \1/" | awk "{ printf \"%+6s %-35s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n\", \$1, \$2, \$3, \$4, \$5, \$6, \$7, \$8, \$9, \$10, \$11, \$12, \$13, \$14, \$15, \$16, \$17, \$18, \$19, \$20 }" | sed -e "s/\ *$//" | sort )
# This is a crazy oneliner. A description starting with "grep -o -E":
# We grep for the various ModSec alert messages and take the content from the
# at/against via the parameter name, the id up and including the message. tr
# and sed and again tr are then used to strip this down. Now cut is used to
# extract (1) the parameter, (2) the id and (3) the message. Then we use sed
# to swap the position of the parameter and the id. Then we used awk to print
# the three fields in a clean table. This demands the used of a lot of %s
# fields, which results in a lot of empty spaces at the end of the line, which
# are finally removed.
if [ -z "$MODSEC" ]; then
MODSEC="***NONE***"
fi
echo "$MODSEC"
echo
echo "Apache Error Log:"
ERRORLINES=$(tail -500 $ERRORLOG | grep $ID | grep -v -E "ModSecurity.*\b(at|against)\b")
if [ -z "$ERRORLINES" ]; then
ERRORLOG="***NONE***"
fi
echo "$ERRORLINES"
echo
echo "Full Apache Access Log:"
echo "$ACCESSLINE"