1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
#!/bin/sh -ue
## Run chkrootkit daily and email results to the user
# This is run by the systemd timer or cron
# note that all variables can be changed by editing $CONFIG
CONFIG=/etc/chkrootkit/chkrootkit.conf
CHKROOTKIT=/usr/sbin/chkrootkit
LOG_DIR=/var/log/chkrootkit
OUTPUT="$LOG_DIR/log.today"
RAW_OUTPUT="$OUTPUT.raw"
EXPECTED_OUTPUT="$LOG_DIR/log.expected"
# If you do not want to use ionice, set IONICE="" in $CONFIG
if [ -x /usr/bin/ionice ] && /usr/bin/ionice -c3 true 2>/dev/null; then
IONICE="/usr/bin/ionice -c3"
else
IONICE=""
fi
RUN_DAILY=false # $CONFIG should set this to 'true'
DIFF_MODE=false
RUN_DAILY_OPTS=""
MAILTO="" # CONFIG should set this to an email address/username to have the output sent
SUBJECT="[chkrootkit] alert for $(hostname --fqdn 2>/dev/null || hostname --short 2>/dev/null || echo "localhost")"
## lines matching patterns in here are omitted entirely from the output, if the file exists.
IGNORE_FILE="/etc/chkrootkit/chkrootkit.ignore"
## The output (after any IGNORE_FILE) is passed through $FILTER)
FILTER="sed -re 's![[:alnum:]]+: PACKET SNIFFER\(((/lib/systemd/systemd-networkd|(/usr)?/sbin/(dhclient|dhcpc?d[0-9]*|wpa_supplicant|NetworkManager))\[[0-9]+\](, )?)+\)!<interface>: PACKET SNIFFER\([systemd-networkd|dhclient|dhcpd|dhcpcd|wpa_supplicant|NetworkManager]{PID}\)!' -e 's/(! [[:alnum:]+-]+)\s+[0-9]+/\1 {PID}/'"
if [ -r "$CONFIG" ]; then
. "$CONFIG"
fi
# support upgrades from bullseye where $OLD_CONFIG was used
OLD_CONFIG=/etc/chkrootkit.conf
if [ -r "$OLD_CONFIG" ]; then
echo "WARNING: $OLD_CONFIG is deprecated. Please put your settings in $CONFIG instead: $OLD_CONFIG will be ignored in a future release and should be deleted."
. "$OLD_CONFIG"
fi
if [ "$RUN_DAILY" = "false" ]; then
exit 0
fi
if [ ! -r "$IGNORE_FILE" ]; then
IGNORE_FILE=/dev/null
fi
if [ -z "$FILTER" ]; then
# explicitly disabled
FILTER=cat
elif ! echo "test" | eval "$FILTER" >/dev/null 2>&1; then
echo "Ignoring invalid \$FILTER='$FILTER'"
FILTER=cat
fi
# Run, filter, and save output
run(){
eval "$IONICE" "$CHKROOTKIT" "$RUN_DAILY_OPTS" 2>&1 \
| tee "$RAW_OUTPUT" 2>&1 \
| eval "$FILTER" \
| grep -E -v -f "$IGNORE_FILE" 2>&1 \
> "$OUTPUT" 2>&1 || true
# show results
if [ "$DIFF_MODE" = "false" ]; then
cat "$OUTPUT" 2>&1 || true
elif [ ! -f "$EXPECTED_OUTPUT" ]; then
echo "No file $LOG_DIR/log.expected"
echo "This file should contain expected output from chkrootkit"
echo
echo "Today's run produced the following output:"
echo "--- [ BEGIN: cat $OUTPUT ] ---"
cat "$LOG_DIR/log.today" 2>&1 || true
echo "--- [ END: cat $OUTPUT ] ---"
echo
echo "To create this file containing all output from today's run, do (as root)"
echo "# cp -a $OUTPUT $EXPECTED_OUTPUT"
echo "# (note that unedited output is in $RAW_OUTPUT)"
elif ! diff -q "$EXPECTED_OUTPUT" "$OUTPUT" > /dev/null 2>&1; then
echo "chkrootkit output was not as expected."
echo
echo "The difference is:"
echo "--- [ BEGIN: diff -u $EXPECTED_OUTPUT $OUTPUT ] ---"
diff -u "$EXPECTED_OUTPUT" "$OUTPUT" 2>&1 || true
echo "--- [ END: diff -u $EXPECTED_OUTPUT $OUTPUT ] ---"
echo
echo "To update the expected output, run (as root)"
echo "# cp -a -f $OUTPUT $EXPECTED_OUTPUT"
echo "# (note that unedited output is in $RAW_OUTPUT)"
fi
}
FILE="$LOG_DIR/chkrootkit-daily.log"
run > "$FILE"
if [ -s "$FILE" ]; then
if [ -n "$MAILTO" ]; then
if [ -n "${STARTED_BY_SYSTEMD-}" ]; then
# run by systemd: product a line on stdout for the journal
echo "sending alert to $MAILTO: $SUBJECT"
fi
mail -s "$SUBJECT" "$MAILTO" < "$FILE"
else
# output on stdout - this will end up in the journal (systemd)
# or if running under cron will be emailed
cat "$FILE"
fi
fi
|