| Server IP : 212.114.33.6 / Your IP : 216.73.217.30 Web Server : Apache System : Linux ger18 6.12.94+deb13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.94-1 (2026-06-20) x86_64 User : immotrainerde ( 2287) PHP Version : 8.2.32 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /sbin/ |
Upload File : |
#!/usr/bin/env bash
#
# Copyright (C) 2004-2012,2014,2017-2019 Debian Logcheck Team
# <logcheck@packages.debian.org>
# Copyright (C) 2002,2003 Jonathan Middleton <jjm@ixtab.org.uk>
# Copyright (C) 1999-2002 Rene Mayrhofer <rmayr@debian.org>
# Copyright (C) 1996-1997 Craig Rowland <crowland@psionic.com>
# This file is part of Logcheck
# Logcheck is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# Logcheck is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with Logcheck; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
if [ "$(id -u)" = 0 ]; then
echo "logcheck should not be run as root. Use su to invoke logcheck:"
echo "su -s /bin/bash -c \"/usr/sbin/logcheck${*:+ $*}\" logcheck"
echo "Or use sudo: sudo -u logcheck logcheck${*:+ $*}."
# you may want to uncomment that hack to let logcheck invoke itself.
# su -s /bin/bash -c "$0 $*" logcheck
exit 1
fi
if [ ! -f /usr/bin/lockfile-create ] || \
[ ! -f /usr/bin/lockfile-remove ] || \
[ ! -f /usr/bin/lockfile-touch ]; then
echo "fatal: lockfile-progs is a prerequisite for logcheck, but was not found."
exit 1
fi
# Set the umask
umask 077
# Set the flag variables
SYSTEM=0
SECURITY=0
ATTACK=0
# Set the getopts string
GETOPTS="c:dhH:l:L:D:m:opr:RsS:tTuvw"
# Set date for the email message
DATE="$(date +'%Y-%m-%d %H:%M %z')"
# Used by 'logcheck -v'
VERSION=1.4.5+deb13u1
# Set the default report level
REPORTLEVEL="server"
# default is to send mails to the local root user
SENDMAILTO="root"
# by default, mark the email as auto-generated
MIMECONSTRUCTARGS=(--header 'Auto-Submitted: auto-generated')
# Set the default subject lines
ATTACKSUBJECT="Security Alerts"
SECURITYSUBJECT="Security Events"
EVENTSSUBJECT="System Events"
ADDTAG="no"
# Default paths
RULEDIR="/etc/logcheck"
CONFFILE="/etc/logcheck/logcheck.conf"
STATEDIR="/var/lib/logcheck"
LOGFILES_LIST="/etc/logcheck/logcheck.logfiles"
LOGFILES_LIST_D="/etc/logcheck/logcheck.logfiles.d"
LOGFILE_FALLBACK="/var/log/syslog"
LOGTAIL="/usr/sbin/logtail2"
SYSLOG_SUMMARY="/usr/bin/syslog-summary"
# Defaults for options
INTRO=1
LOGCHECKDEBUG=0
MAILOUT=0
MAILASATTACH=0
MIMEENCODING=
NOCLEANUP=0
REBOOT=0
FQDN=0
SORTUNIQ=0
SUPPORT_CRACKING_IGNORE=0
SYSLOGSUMMARY=0
LOCKDIR=/run/lock/logcheck
LOCKFILE="$LOCKDIR/logcheck"
# Allow globs to return zero files
shopt -s nullglob
# remove the lockfile
remove_lockfile(){
if [ -n "$LOCK" ]; then
debug "Killing lockfile-touch - $LOCK"
kill "$LOCK" && unset LOCK
fi
if [ -f "$LOCKFILE.lock" ]; then
debug "Removing lockfile: $LOCKFILE.lock"
lockfile-remove "$LOCKFILE"
fi
}
# cleanup() is called at the end to remove temporary files
cleanup() {
remove_lockfile
if [ -d "$TMPDIR" ]; then
if [ "$NOCLEANUP" -eq 0 ];then
debug "cleanup: Removing working dir: $TMPDIR"
rm -r "$TMPDIR"
else
debug "cleanup: Not removing working dir: $TMPDIR"
fi
fi
debug "cleanup: Done"
}
# debug() output (does nothing unless -d given, if -d, writes to stderr)
# First argument - string describing what is happening
# Second argument - file, whose contents are shown
debug() {
local file="${2-}"
local lines=0
if [ "$LOGCHECKDEBUG" -eq 1 ]; then
echo "DEBUG: [$(date)] $1" >&2
if [ -n "$file" ]; then
lines=$(wc -l "$file" | cut -d ' ' -f1)
echo "--- START [ $file (LINES: $lines) ] ---" >&2
cat "$file" >&2
echo -e "--- END [ $file (LINES: $lines) ] ---\n" >&2
fi
fi
}
# Issue warnings on stdout (not used)
warn() {
local message="$1"
debug "Warning - $message"
echo "Warning: $message"
if [ -d "$TMPDIR" ]; then
echo "$message" >> "$TMPDIR/warnings" \
|| error "Could not append to $TMPDIR/warnings"
fi
return 0
}
# Mail error message to sysadmin
# (Also show on stderr)
# (If 2nd argument is 'noclean' then do not remove the lockfile)
error() {
debug "error(): $*"
local message="${1-}"
echo "Error: $message" >&2
if [ "${2-}" = "noclean" ]; then
debug "error(): Not removing lockfile"
else
remove_lockfile
fi
if [ "$MAILOUT" -eq 0 ]; then
{
cat<<EOF
Logcheck failed: Your log entries may not have been checked.
Details:
$message
To identify the cause you may wish to:
${TMPDIR:+"- Check temporary directory: $TMPDIR"
}
- verify that the logcheck user can read all
logfiles specified in;
/etc/logcheck/logcheck.logfiles
/etc/logcheck/logcheck.logfiles.d/*.logfiles
- check the system has enough space; (df -h output follows):
$(df -h 2>&1|| :)
- check the settings (environment follows):
$(export 2>&1||:)
EOF
} | mime-construct "${MIMECONSTRUCTARGS[@]}" \
--subject "Logcheck: $HOSTNAME $DATE exiting due to errors" "${ENCODING[@]}" \
--file - --to "$SENDMAILTO"
fi
exit 1
}
# Add an introduction to the report
setintro() {
if [ -f "$RULEDIR/header.txt" ] && [ -r "$RULEDIR/header.txt" ] ; then
debug "Adding a header to the report" "$RULEDIR/header.txt"
cat "$RULEDIR/header.txt" >> "$TMPDIR/report" \
|| error "Could not append header to $TMPDIR/report"
else
debug "Unable to add a header to the report: $RULEDIR/header.txt does not exist or could not be read"
fi
}
# Add a footer to the report.
setfooter() {
if [ -f "$RULEDIR/footer.txt" ] && [ -r "$RULEDIR/footer.txt" ] ; then
cat "$RULEDIR/footer.txt" >> "$TMPDIR/report" \
|| error "Could not append footer to $TMPDIR/report"
fi
}
# Clean a directory of rules:
# - For every rules file in the directory, remove blank lines and comments
# run-parts is used to list rules, so backup files are ignored
# - Store the results in a new directory (passed as the second argument)
# takes two args: directory to clean and output directory
cleanrules() {
local dir="$1"
local cleaned="$2"
local rulefile x
debug "cleanrules $dir => $cleaned"
if [ -d "$dir" ]; then
mkdir -p "$cleaned" \
|| error "Could not make dir $cleaned (for cleaned rulefiles from $dir)"
# report unreadable files - run-parts silently discards them
for x in "$dir"/*; do
if [ -f "$x" ] && [ ! -r "$x" ]; then
error "Could not read $x"
fi
done
for rulefile in $(run-parts --list "$dir"); do
rulefile="$(basename "$rulefile")"
if [ -f "${dir}/${rulefile}" ]; then
debug "cleanrules: ${dir}/${rulefile} -> $cleaned/$rulefile"
# pipe outut of 'grep' to 'cat' because we want a exit status of 0 even if grep did not find matches
command grep -E --text -v '^[[:space:]]*$|^#' "$dir/$rulefile" \
| cat >> "$cleaned/$rulefile" \
|| error "Could not append to $cleaned/$rulefile"
fi
done
elif [ -f "$dir" ]; then
error "cleanrules: '$dir' is a file, not a directory"
elif [ -z "$dir" ]; then
error "cleanrules: called without argument"
fi
}
# Add any events to the report
report() {
if [ -s "$TMPDIR/checked" ]; then
debug "report(): $*"
printheader "$*" >> "$TMPDIR/report" \
|| error "Could not append to report"
if [ "$SYSLOGSUMMARY" -eq 1 ] && [ -x "$SYSLOG_SUMMARY" ]; then
debug "report ($*): running syslog-summary on $TMPDIR/checked"
"$SYSLOG_SUMMARY" "$TMPDIR/checked" | \
command grep -Ev "^Summarizing " \
| cat >> "$TMPDIR/report" \
|| error "Could not append to report"
else
if [ "$SYSLOGSUMMARY" -eq 1 ] && [ ! -x "$SYSLOG_SUMMARY" ]; then
debug "report ($*): WARNING: can't exec $SYSLOG_SUMMARY. Running without syslog-summary"
fi
debug "report ($*): Adding lines to $TMPDIR/report" "$TMPDIR/checked"
cat "$TMPDIR/checked" >> "$TMPDIR/report" \
|| error "Could not append to report"
fi
echo >> "$TMPDIR/report" \
|| error "Could not append a blank line to the report"
return 0
else
debug "report ($*): Nothing to report"
return 1
fi
}
# Add section headings to the report
printheader() {
local char="="
local header="$1"
local number="${#header}"
local line=""
debug "Writing section heading '$header' to $TMPDIR/report"
for _ in $(seq "$number"); do
line="${line}${char}"
if [ "$char" = "=" ]; then
char="-"
else
char="="
fi
done
echo "$header"
echo "$line"
}
# Mail the report
sendreport() {
local subject
if [ "$REBOOT" -eq 1 ]; then
subject="Reboot: $HOSTNAME $DATE $*"
else
subject="$HOSTNAME $DATE $*"
fi
if [ "$ADDTAG" = "yes" ]; then
subject="[logcheck] $subject"
fi
if [ "$MAILOUT" -eq 1 ]; then
debug "Sending report to STDOUT"
cat "$TMPDIR/report"
debug "Sent report to STDOUT"
else
debug "Sending report: '$subject' by email to $SENDMAILTO"
if [ "$MAILASATTACH" -eq 1 ]; then
debug "Sending report as attachment"
mime-construct "${MIMECONSTRUCTARGS[@]}" --subject "$subject" "${ENCODING[@]}" \
--string "Report attached" --to "$SENDMAILTO" \
--attachment "logcheck_report" "${ENCODING[@]}" --file "$TMPDIR/report"
return $?
elif [ "$MAILASATTACH" -eq 2 ]; then
debug "Sending report as gzip attachment"
gzip --to-stdout "$TMPDIR/report" \
| mime-construct "${MIMECONSTRUCTARGS[@]}" --subject "$subject" "${ENCODING[@]}" \
--string "Report attached" --to "$SENDMAILTO" \
--type "application/x-gzip" --attachment "logcheck_report.gz" \
--file -
return $?
else
mime-construct "${MIMECONSTRUCTARGS[@]}" --subject "$subject" --to "$SENDMAILTO" "${ENCODING[@]}" \
--file "$TMPDIR/report"
fi
fi
}
# Grep the log output ($TMPDIR/logoutput-sorted) storing result in $TMPDIR/checked
# using:
# $1 - directory of positive rules: any matches are added to the report
# $2 - heading for matches
# $3 - (optional) directory of ignore rules: filters out matches
# $4 - (optional) directory of ignorehigher rules: filters out matches
greplogoutput() {
local raise="$1"
local sectionstring="$2"
local ignore="$3"
local ignorehigher="$4"
local RETURN=1
local ignore_rules grepfile
debug "greplogoutput ($*): Starting"
for grepfile in "$raise"/*; do
debug "greplogoutput: Using $grepfile to find entries to report" "$grepfile"
# Report entries that match
command grep -E --text -f "$grepfile" "$TMPDIR/logoutput-sorted" \
| cat > "$TMPDIR/checked" \
|| error "Could not output to $TMPDIR/checked"
debug "greplogoutput: After using $grepfile we have the following entries to report" \
"$TMPDIR/checked"
# apply different 'ignore' rules
if [ -s "$TMPDIR/checked" ]; then
ignore_rules="$ignore/$(basename "$grepfile")"
debug "Filtering reportable entries using '$ignore_rules' (if it exists)"
if [ -n "$ignore" ] && [ -f "$ignore_rules" ]; then
cleanchecked "$ignore_rules"
else
debug "(It does not exist)"
fi
ignore_rules="$ignore/logcheck-$(basename "$grepfile")"
debug "Filtering entries using '$ignore_rules' (if it exists)"
if [ -n "$ignore" ] && [ -f "$ignore_rules" ]; then
cleanchecked "$ignore_rules"
else
debug "(It does not exist)"
fi
# If it's the logcheck file, we do something special
if [ "$(basename "$grepfile")" = "logcheck" ]; then
if [ -n "$ignore" ]; then
# Ignore files _always_ impact matches from logcheck
debug "Filtering entries using all rules in: $ignore (if it is set)"
for file in "$ignore"/* ; do
if [ -s "$TMPDIR/checked" ]; then
cleanchecked "$ignore"
fi
done
else
debug "(It is not set)"
fi
# Remove any entries already reported under a separate section
debug "Filtering using any file in $raise that does not start with 'logcheck'"
for file in "$raise"/*; do
if [ -s "$TMPDIR/checked" ]; then
if ! [[ "$(basename "$file")" =~ ^logcheck* ]]; then
debug "Filtering using: $file"
cleanchecked "$file"
fi
fi
done
fi
if [ -n "$ignorehigher" ]; then
if [ -d "$ignorehigher" ] && [ -s "$TMPDIR/checked" ]; then
debug "Filtering out already-reported entries found by 'higher ignore' dir $ignorehigher"
cleanchecked "$ignorehigher"
fi
fi
# Apply local rules before we report
if [ -n "$ignore" ]; then
debug "Filtering using: $ignore/local (if it exists)"
if [ -f "$ignore/local" ] && [ -s "$TMPDIR/checked" ]; then
cleanchecked "$ignore/local"
else
debug "(It does not exist)"
fi
# Now apply any local-* files
debug "Filtering using: $ignore/local-*"
for file in "$ignore"/local-* ; do
if [ -f "$file" ] && [ -s "$TMPDIR/checked" ]; then
cleanchecked "$file"
fi
done
fi
debug "greplogoutput: Finished all filters."
if [ "$(basename "$grepfile")" = "logcheck" ]; then
report "${sectionstring}" && RETURN=0
else
report "${sectionstring} for $(basename "$grepfile")" \
&& RETURN=0
fi
fi
done
debug "greplogoutput: Finished, with the following entries remaining" "$TMPDIR/checked"
return $RETURN
}
# Clean $TMPDIR/checked using a rules file (or directory of rules files) (passed as $1)
cleanchecked() {
clean="$1"
if [ -f "$clean" ]; then
debug "cleanchecked - filtering using file: $clean" "$clean"
command grep -E --text -v -f "$clean" "$TMPDIR/checked" \
| cat >> "$TMPDIR/checked.1" \
|| error "Could not output to $TMPDIR/checked.1"
debug "cleanchecked - after using $clean remaining lines are as follows:" "$TMPDIR/checked.1"
mv "$TMPDIR/checked.1" "$TMPDIR/checked" \
|| error "Could not move $TMPDIR/checked.1 to $TMPDIR/checked"
elif [ -d "$clean" ]; then
debug "cleanchecked - filtering using all files in dir: $clean"
for file in "$clean"/*; do
cleanchecked "$file"
done
else
error "cleanchecked: Not a file or a directory $clean"
fi
}
# Get the unseen part of a logfile (or the journal).
# $1 - log file to use
logoutput() {
local file="$1"
local JOURNALCTL="journalctl"
local JOURNALCTL_OPTS=() OPTS=()
local offsetfile offsettime
# There are some problems with this section.
debug "logoutput called with file: $file"
if [ -f "$file" ]; then
offsetfile="$STATEDIR/offset$(echo "$file" | tr / .)"
debug "Running $LOGTAIL on $file"
OPTS=( -f "$file" -o "$offsetfile" )
if [ -n "${LOGTAIL_OPTS-}" ]; then
OPTS+=("$LOGTAIL_OPTS")
fi
"$LOGTAIL" "${OPTS[@]}" >> "$TMPDIR/logoutput/$(basename "$file")" 2>&1 \
|| error "Could not run logtail or save output"
else
if [ "$file" = "journal" ] && [ -x "$(command -v $JOURNALCTL)" ]; then
offsetfile="$STATEDIR/offset.$file"
offsettime=""
if [ -f "$offsetfile" ]; then
offsettime="--since=@$(stat -c %Y "$offsetfile")"
else
echo "This is the first time logcheck has checked the systemd journal." \
>> "$TMPDIR/report" || error "Could not write message about first-time check of journal to report"
echo "Only recent entries (from the last 5 hours) will be checked" \
>> "$TMPDIR/report" || error "Could not write message about first-time check of journal to report"
echo "If you do not wish to check the systemd journal, please see /etc/logcheck/logcheck.logfiles.d/journal.logfiles" \
>> "$TMPDIR/report" || error "Could not write message about first-time check of journal to report"
offsettime="--since=-5h"
fi
debug "Running $JOURNALCTL ${JOURNALCTL_OPTS[*]} -q $offsettime"
"$JOURNALCTL" "${JOURNALCTL_OPTS[@]}" --quiet "$offsettime" \
>> "$TMPDIR/logoutput/$file" 2>&1 \
|| error "Could not run journalctl or save output"
if [ "$LOGTAIL_OPTS" != '-t' ]; then
touch "$offsetfile"
fi
else
echo "E: File could not be read: $file" >> "$TMPDIR/errors" \
|| error "Could not output to $TMPDIR/errors"
fi
fi
}
# Show options
usage() {
debug "usage: Printing usage and exiting"
cat<<EOF
usage: logcheck [-c CFG] [-d] [-h] [-H HOST] [-l LOG] [-L CFG] [-D DIR] [-m MAIL] [-o]
[-r DIR] [-s|-p|-w] [-R] [-S DIR] [-t] [-T] [-u]
-c CFG = override default configuration file
-d = debug mode
-h = print this usage information and exit
-H HOST = use this hostname in the subject of any generated mail
-l LOG = check the specified logfile
-L CFG = override default logfiles list
-D DIR = override default logfiles lists directory
-m MAIL = send the report to the specified recipient
-o = send the report to stdout, no mail will be sent
-p = use the "paranoid" runlevel
-r DIR = override default rules directory
-R = adds "Reboot:" to email subject
-s = use the "server" runlevel
-S DIR = override default state directory
-t = testing mode, don't update the logfile offsets
-T = do not remove the TMPDIR
-u = enable syslog-summary
-v = print version
-w = use the "workstation" runlevel
EOF
}
# Check the commandline options for a change to the config file option
while getopts "$GETOPTS" opt; do
case "$opt" in
c)
debug "Setting CONFFILE to $OPTARG"
CONFFILE="$OPTARG"
if [ ! -r "$CONFFILE" ]; then
error "Config file $CONFFILE is unreadable or does not exist"
fi
;;
d)
LOGCHECKDEBUG=1
debug "Turning debug mode on"
;;
h)
usage
exit 0
;;
T)
debug "Setting NOCLEANUP to 1"
NOCLEANUP=1
;;
v)
echo "logcheck $VERSION"
exit 0
;;
\?)
usage
exit 1
;;
esac
done
# Now reset $OPTIND to 1
OPTIND=1
debug "Sourcing - $CONFFILE"
# Now source the config file - before things that should not be changed
if [ -r "$CONFFILE" ]; then
# shellcheck source=/etc/logcheck/logcheck.conf
. "$CONFFILE"
elif [ -f "$CONFFILE" ]; then
error "Config file $CONFFILE could not be read"
fi
# Ensure $INTRO is set correctly
if [ -z "$INTRO" ]; then
INTRO=1
elif [ "$INTRO" = "no" ]; then
INTRO=0
elif [ "$INTRO" = "yes" ]; then
INTRO=1
fi
# Use sort -u or -k 1,3 -s
if [ "$SORTUNIQ" -eq 1 ];then
SORT="sort -u"
else
SORT="sort -k 1,3 -s"
fi
# Set the mime encoding if required (blank means auto-detected)
if [ -n "$MIMEENCODING" ]; then
ENCODING=(--encoding "$MIMEENCODING")
else
ENCODING=()
fi
# HOSTNAME is either 'fully qualified' or 'short'
if [ "$FQDN" -eq 1 ]; then
HOSTNAME="$(hostname --fqdn 2>/dev/null)"
else
HOSTNAME="$(hostname --short 2>/dev/null)"
fi
# Now check for the other options
while getopts "$GETOPTS" opt; do
case "$opt" in
H)
debug "Setting HOSTNAME to $OPTARG"
HOSTNAME="$OPTARG"
;;
l)
debug "Setting LOGFILE to $OPTARG"
LOGFILE="$OPTARG"
;;
L)
debug "Setting LOGFILES_LIST to $OPTARG"
LOGFILES_LIST="$OPTARG"
;;
D)
debug "Setting LOGFILES_LIST_D to $OPTARG"
LOGFILES_LIST_D="$OPTARG"
;;
m)
debug "Setting SENDMAILTO to $OPTARG"
SENDMAILTO="$OPTARG"
;;
o)
debug "Setting MAILOUT to 1"
MAILOUT="1"
;;
p)
debug "Setting REPORTLEVEL to paranoid"
REPORTLEVEL="paranoid"
;;
r)
debug "Setting RULEDIR to $OPTARG"
RULEDIR="$OPTARG"
;;
R)
debug "Setting REBOOT to 1"
REBOOT=1
;;
s)
debug "Setting REPORTLEVEL to server"
REPORTLEVEL="server"
;;
S)
debug "Setting STATEDIR to $OPTARG"
STATEDIR="$OPTARG"
;;
u)
debug "Setting SYSLOGSUMMARY to 1"
SYSLOGSUMMARY="1"
;;
t)
debug "Setting LOGTAIL_OPTS to -t"
LOGTAIL_OPTS='-t'
;;
w)
debug "Setting REPORTLEVEL to workstation"
REPORTLEVEL="workstation"
;;
\?)
usage
exit 1
;;
esac
done
debug "Finished getopts $GETOPTS"
shift $((OPTIND - 1))
if [ "$REPORTLEVEL" = "workstation" ]; then
REPORTLEVELS="workstation server paranoid"
elif [ "$REPORTLEVEL" = "server" ]; then
REPORTLEVELS="server paranoid"
elif [ "$REPORTLEVEL" = "paranoid" ]; then
REPORTLEVELS="paranoid"
else
error "REPORTLEVEL is set to an unknown value" "noclean"
fi
debug "Using rules from the following REPORTLEVELs: $REPORTLEVELS"
trap 'cleanup' 0
debug "Setting lockfile: $LOCKFILE.lock"
if [ ! -d "$LOCKDIR" ]; then
mkdir -m 0755 "$LOCKDIR"
fi
lockfile-create --retry 1 "$LOCKFILE" > /dev/null 2>&1
if [ $? -eq 1 ]; then
trap 0
if [ -e "${LOCKFILE}.lock" ]; then
error "Another logcheck process is still running" "noclean"
else
error "Failed to get lockfile: $LOCKFILE.lock" "noclean"
fi
else
debug "Running lockfile-touch $LOCKFILE.lock"
lockfile-touch "$LOCKFILE" &
LOCK="$!"
fi
# Create a secure temporary working directory (or exit)
TMPDIR="$(mktemp -d -p "${TMP:-/tmp}" logcheck.XXXXXX)" \
|| TMPDIR="$(mktemp -d -p /var/tmp logcheck.XXXXXX)" \
|| error "Could not create temporary directory"
debug "Using working dir: $TMPDIR"
# Clean the rulefiles into $TMPDIR
cleanrules "$RULEDIR/cracking.d" "$TMPDIR/cracking"
cleanrules "$RULEDIR/violations.d" "$TMPDIR/violations"
cleanrules "$RULEDIR/violations.ignore.d" "$TMPDIR/violations-ignore"
# Clean the rulefiles into $TMPDIR/ignore
for level in $REPORTLEVELS; do
cleanrules "$RULEDIR/ignore.d.$level" "$TMPDIR/ignore"
done
# The cracking.ignore.d directory is only used if
# SUPPORT_CRACKING_IGNORE is set to 1 in the configuration file.
# This is *only* for local admin use.
if [ "$SUPPORT_CRACKING_IGNORE" -eq 1 ]; then
cleanrules "$RULEDIR/cracking.ignore.d" "$TMPDIR/cracking-ignore"
fi
# Get the list of log files to check
# Handle log rotation correctly (idea taken from Wiktor Niesiobedzki)
mkdir "$TMPDIR/logoutput" \
|| error "Could not create $TMPDIR/logoutput"
LOGFILES=("$LOGFILES_LIST" "$LOGFILES_LIST_D"/*.logfiles)
if [ -z "${LOGFILE-}" ] && [ "${#LOGFILES[@]}" != "0" ]; then
for file_list in "${LOGFILES[@]}" ; do
if [ -f "$file_list" ] && [ -r "$file_list" ]; then
SAVEIFS=$IFS; IFS=$(echo -en "\n\b");
for file in $(command grep -E --text -v -h "(^#|^[[:space:]]*$)" "$file_list"); do
logoutput "$file"
done
IFS=$SAVEIFS
else
error "$file_list does not exist or could not be read"
fi
done
elif [ -n "$LOGFILE" ]; then
if [ -f "$LOGFILE" ] && [ -r "$LOGFILE" ]; then
logoutput "$LOGFILE"
else
error "$LOGFILE does not exist or could not be read"
fi
elif [ -f "$LOGFILE_FALLBACK" ] && [ -r "$LOGFILE_FALLBACK" ]; then
logoutput "$LOGFILE_FALLBACK"
else
error "Gave up: No logfile settings and unable to read fallback file $LOGFILE_FALLBACK"
fi
# First sort the logs to remove duplicate lines (including from different logfiles with
# the same lines) to reduce CPU and memory usage.
debug "Sorting logs"
$SORT "$TMPDIR/logoutput"/* | sed -e 's/[[:space:]]\+$//' > "$TMPDIR/logoutput-sorted" \
|| error "Could not save sorted log content to $TMPDIR/logoutput-sorted"
debug "After sorting, we have the following log entries to check" "$TMPDIR/logoutput-sorted"
# See if the logoutput-sorted file actually has data to check,
# if not, we have nothing to do: erase it and exit
if [ ! -s "$TMPDIR/logoutput-sorted" ] && [ ! -f "$TMPDIR/errors" ]; then
debug "Nothing to report"
exit 0
elif [ ! -s "$TMPDIR/logoutput-sorted" ] && [ -f "$TMPDIR/errors" ]; then
error "$(< "$TMPDIR/errors")"
fi
if [ "$INTRO" -eq 1 ]; then
setintro
else
debug "Not adding a header to the report (INTRO=$INTRO)"
fi
if [ -f "$TMPDIR/errors" ]; then
{
cat<<EOF
$(< "$TMPDIR/errors")
EOF
} >> "$TMPDIR/report" \
|| error "Could not output errors to $TMPDIR/report"
fi
# Check for blatant cracking attempts
if [ -d "$TMPDIR/cracking" ]; then
if [ "$SUPPORT_CRACKING_IGNORE" -eq 1 ]; then
debug "Using cracking-ignore"
if [ -d "$TMPDIR/cracking-ignore" ]; then
greplogoutput "$TMPDIR/cracking" "$ATTACKSUBJECT" \
"$TMPDIR/cracking-ignore" && ATTACK="1"
fi
else
debug "Checking for cracking alerts ($ATTACKSUBJECT) using cracking.d"
greplogoutput "$TMPDIR/cracking" "$ATTACKSUBJECT" \
&& ATTACK="1"
debug "Finished check for security alerts (ATTACK=$ATTACK)"
fi
fi
# Check for security events
if [ -d "$TMPDIR/violations" ]; then
debug "Checking for violations ($SECURITYSUBJECT) using violations.d"
rm -f "$TMPDIR/checked"
if [ "$ATTACK" -eq 1 ]; then
greplogoutput "$TMPDIR/violations" "$SECURITYSUBJECT" \
"$TMPDIR/violations-ignore" "$TMPDIR/cracking" && SECURITY="1"
else
greplogoutput "$TMPDIR/violations" "$SECURITYSUBJECT" \
"$TMPDIR/violations-ignore" && SECURITY="1"
fi
debug "Finished check for violations (SECURITY=$SECURITY)"
fi
# Check for system events: Unlike the above, this filters _out_ patterns
debug "Starting check for system events"
cp "$TMPDIR/logoutput-sorted" "$TMPDIR/checked" \
|| error "Could not copy $TMPDIR/logoutput-sorted to $TMPDIR/checked"
if [ -d "$TMPDIR/ignore" ]; then
debug "Filtering using dir: $TMPDIR/ignore (which has files from ignore.d.*)"
cleanchecked "$TMPDIR/ignore"
fi
if [ -s "$TMPDIR/checked" ]; then
debug "Removing alerts from system events (as they were reported already)"
cleanchecked "$TMPDIR/cracking"
fi
if [ -s "$TMPDIR/checked" ]; then
debug "Removing violations from system events (as they were reported already)"
cleanchecked "$TMPDIR/violations"
fi
report "$EVENTSSUBJECT" && SYSTEM="1"
debug "Finished check for system events (SYSTEM=$SYSTEM)"
# Add any warnings to report
if [ -f "$TMPDIR/warnings" ]; then
printheader "Logcheck Warnings" >> "$TMPDIR/report" \
|| error "Could not append warnings to report"
cat "$TMPDIR/warnings" >> "$TMPDIR/report" || error "Could not append warnings to report"
echo >> "$TMPDIR/report" || error "Could not append warnings to report"
fi
# Include the footer if required
if [ "$INTRO" -eq 1 ]; then
debug "Adding the footer to the report"
setfooter
else
debug "Not adding a footer to the report (INTRO=$INTRO)"
fi
# If there are results, report them (mail or stdout)
if [ "$ATTACK" -eq 1 ]; then
sendreport "$ATTACKSUBJECT"
elif [ "$SECURITY" -eq 1 ]; then
sendreport "$SECURITYSUBJECT"
elif [ "$SYSTEM" -eq 1 ]; then
sendreport "$EVENTSSUBJECT"
fi