Make chkrootkit-daily Reports Useful Without Hiding Alerts
You will configure Debian's chkrootkit-daily job, establish a known-good output baseline, and recognise when a later report needs investigation. The installed package here is chkrootkit 0.58b-1, with the scanner reporting version 0.58b. Allow about 20 minutes for the first run and baseline review. You need a shell and a user who can use sudo; the daily job itself is normally run with elevated privileges by its timer or cron.
The route
Jump straight to the step you need, or tick off Done means at the end.
This is a local rootkit check, not proof that a machine is clean. It can report false positives, and an attacker with control of the host may be able to interfere with local tools or their output. Keep the raw report and investigate unexpected changes separately.
1. Confirm the installed command and scheduler
Start with read-only checks. They do not need sudo:
$ command -v chkrootkit-daily
/usr/sbin/chkrootkit-daily
$ dpkg-query -W -f='\${Package} \${Version}\n' chkrootkit
chkrootkit 0.58b-1
$ chkrootkit -V
chkrootkit version 0.58b
$ systemctl list-timers --all 'chkrootkit*' --no-pager
The manual describes chkrootkit-daily as suitable for a systemd timer or a cron job. On a systemd host, the last command should show chkrootkit.timer if the packaged timer is installed. Do not enable a second scheduler just because one command produced no output: first check your distribution's package files and existing cron configuration.
Checkpoint
You know which package and scheduler are present. If the binary or timer is missing, stop here and use your normal package-management process rather than copying a script from elsewhere.
2. Read the configuration before changing it
The configuration file is /etc/chkrootkit/chkrootkit.conf. It is sourced as shell code by the daily script, so it must remain valid shell syntax and should be owned and writable only by trusted administrators. Read it without changing anything:
$ sudo sed -n '1,220p' /etc/chkrootkit/chkrootkit.conf
$ sudo test -r /etc/chkrootkit/chkrootkit.ignore && sudo sed -n '1,120p' /etc/chkrootkit/chkrootkit.ignore || echo 'no ignore file'
The important settings are RUN_DAILY, RUN_DAILY_OPTS, DIFF_MODE, FILTER, IGNORE_FILE and MAILTO. The packaged defaults enable the daily run, pass no scanner options, compare output with an expected file, normalise changing process identifiers and network-manager messages, and send the resulting report to root. Your installed file is authoritative if it differs from those defaults.
Do not treat FILTER or the ignore file as a way to make an alert disappear. A filter can rewrite output, while each line in IGNORE_FILE is an extended regular expression that removes matching lines. Every removed line is evidence you will no longer see in the report.
3. Choose reporting and email deliberately
Edit the configuration only after deciding where the report should arrive. This is a persistent, security-sensitive change. Make a backup first, then use an editor that preserves the file's ownership and permissions:
$ sudo cp -a /etc/chkrootkit/chkrootkit.conf /etc/chkrootkit/chkrootkit.conf.bak
$ sudoedit /etc/chkrootkit/chkrootkit.conf
For a first setup, leave RUN_DAILY_OPTS="" so the report contains all scanner output. Keep DIFF_MODE="true" if you want routine output compared with a baseline. Set MAILTO="[email protected]" to a local address or account that your mail system can deliver to. If MAILTO is empty, output is left on standard output, which normally means the systemd journal or a cron-generated message.
If you deliberately want the complete filtered report every day, set DIFF_MODE="false". In that mode, RUN_DAILY_OPTS="-q" can reduce noise, but quiet mode suppresses tests that find nothing suspicious. Do not add -q merely to make email shorter.
Check the edited file before running it:
$ sudo sh -n /etc/chkrootkit/chkrootkit.conf
$ sudo grep -E '^(RUN_DAILY|RUN_DAILY_OPTS|DIFF_MODE|IGNORE_FILE|MAILTO)=' /etc/chkrootkit/chkrootkit.conf
A non-zero result from sh -n means the daily job may fail before scanning. Restore the backup with sudo cp -a /etc/chkrootkit/chkrootkit.conf.bak /etc/chkrootkit/chkrootkit.conf if you need to undo this edit.
4. Run the first scheduled scan and inspect its files
The daily command writes under /var/log/chkrootkit, so this step requires elevated privileges and changes host state. It can take a little while. Do not run it concurrently with the timer:
$ systemctl list-timers --all 'chkrootkit*' --no-pager
$ sudo systemctl start chkrootkit.service
$ sudo systemctl status --no-pager chkrootkit.service
The service should finish without an active process left behind. A successful service run is not the same as a clean scan: inspect the report and the files it creates:
$ sudo ls -l /var/log/chkrootkit/
$ sudo sed -n '1,160p' /var/log/chkrootkit/chkrootkit-daily.log
$ sudo sed -n '1,160p' /var/log/chkrootkit/log.today
$ sudo sed -n '1,80p' /var/log/chkrootkit/log.today.raw
The script stores the raw scanner output in log.today.raw, then applies FILTER and IGNORE_FILE to produce log.today. The wrapper's own messages and the final report are written to chkrootkit-daily.log. Variable process IDs or normal network-manager notices are why the default filter exists. A line containing INFECTED, an unexpected binary, or an unfamiliar process is a reason to investigate, not a reason to add a new ignore pattern.
5. Create and review the expected baseline
With diff mode enabled, the first run explains that /var/log/chkrootkit/log.expected does not exist. Review log.today and the raw file first. Only establish a baseline when you understand every remaining line:
$ sudo diff -u /var/log/chkrootkit/log.today /var/log/chkrootkit/log.today.raw || true
$ sudo cp -a /var/log/chkrootkit/log.today /var/log/chkrootkit/log.expected
The first command may show differences because filtering is expected. The second is an elevated, persistent change. It replaces an existing expected file, so make a backup first if one already exists:
$ sudo test -f /var/log/chkrootkit/log.expected && sudo cp -a /var/log/chkrootkit/log.expected /var/log/chkrootkit/log.expected.bak
$ sudo cp -a /var/log/chkrootkit/log.today /var/log/chkrootkit/log.expected
On a later run, unchanged filtered output produces no alert text. A changed report prints a unified diff between log.expected and log.today. Compare the change with the raw output before editing the baseline. To undo the baseline update, restore log.expected.bak; if it was a new file, remove only that file after checking that no current investigation needs it.
6. Use scanner options sparingly
chkrootkit supports -q for quiet output, -x for expert detail, -d for debug output, -e for named exclusions, -s for sniffer-test exclusions, -n to ignore NFS directories, and -l to list tests. The daily wrapper passes RUN_DAILY_OPTS to the scanner. Options cannot be combined, so write -q -n, not -qn.
Use exclusions only when you have recorded why a result is a known false positive. For example, a standard network manager can appear in the sniffer test. Prefer the documented -s regular expression or a narrow ignore pattern, then retain the raw report so the original evidence is not lost. Never use -r or -p in the daily job without testing the alternate root or trusted command path separately.
Done means
- The installed package and scheduler were confirmed.
/etc/chkrootkit/chkrootkit.confpasses shell syntax checking.- Reports arrive at the intended local address, or are available in the journal or cron mail.
log.today.raw,log.todayandchkrootkit-daily.logwere inspected.- The expected baseline was created only after its contents were reviewed.
- Unexpected findings are investigated from the raw report instead of hidden with filters or ignores.