Skip to main content

Detecting Rootkits on Linux: rkhunter and chkrootkit

Security · 19.04.2026 · 5 min read
Illustration for “Detecting Rootkits on Linux: rkhunter and chkrootkit”

Rootkits are malicious programs that hide their presence in the system at the kernel or filesystem level. Regular scanning with rkhunter and chkrootkit lets you detect a compromised server.

Installing and configuring rkhunter

apt install rkhunter -y

# Update the hash database
rkhunter --update
rkhunter --propupd  # Save current file properties as the baseline

# Run a full scan
rkhunter --check --sk --rwo  # --sk = skip keypresses, --rwo = warnings only

Important /etc/rkhunter.conf settings

MAIL-ON-WARNING=admin@example.com
MAIL_CMD=mail -s "[rkhunter] Warning on $(hostname)"
CRON_DAILY_RUN=yes

# Exclude false positives
SCRIPTWHITELIST=/usr/sbin/adduser
ALLOWHIDDENFILE=/etc/.gitconfig
PKGMGR=DPKG  # Use dpkg to verify packages

Installing and using chkrootkit

apt install chkrootkit -y
chkrootkit
# Output: INFECTED means a potential threat
# Output: not infected — clean

Automatic scheduled scanning

# /etc/cron.daily/rkhunter-check
#!/bin/bash
/usr/bin/rkhunter --cronjob --update --quiet 2>&1 |   mail -s "rkhunter Daily Report - $(hostname)" admin@example.com

chmod +x /etc/cron.daily/rkhunter-check

What to do if a threat is detected

  1. Isolate the server — disconnect it from the network (do not power it off!)
  2. Create a disk image for forensic analysis
  3. Check running processes: ps aux, netstat -tulnp
  4. Check cron and startup entries: crontab -l, systemctl list-units
  5. Restore from a clean backup onto a new server
Best practice: Run rkhunter --propupd right after installing a clean system and after every package update. This creates an up-to-date baseline for comparison during the next scan.
rkhunter false positives are common. Investigate every warning before concluding the server is compromised. Start by checking with dpkg -V package.

Common scanner warnings explained

  • Warning: The command '/usr/bin/which' has been replaced by a script: /usr/bin/which — a classic false positive on Debian and Ubuntu, where /usr/bin/which is a plain shell script rather than a binary. rkhunter expects a binary file and mistakes a normal distribution quirk for tampering.
  • Warning: The SSH configuration option 'PermitRootLogin' has been set to 'yes' — this warning is about the sshd setting itself, not an infection. It is fixed by editing /etc/ssh/sshd_config, not by hunting for a rootkit on disk.
  • Warning: The file properties have changed for: /usr/sbin/adduser, along with the current and stored hash — reports that the file changed since the last rkhunter --propupd. On its own this does not mean compromise if the change came from a routine package update via apt.
  • The following suspicious files and directories were found: — the section header in chkrootkit's output under which specific findings are listed. An empty list right under this header is the expected clean result.
  • The System checks summary at the end of rkhunter's output shows the number of warnings and the path to the detailed log at /var/log/rkhunter.log — that is what to check for any warning, rather than guessing from console fragments.

rkhunter versus chkrootkit

Criterionrkhunterchkrootkit
File checksum verificationYes, via the --propupd databaseNo
sshd and sudo configuration checksYesNo
Known rootkit signature scanningYes, an updatable databaseYes, a separate built-in list
Scheduled automationA ready-made script in /etc/cron.dailyNeeds to be set up manually
Project maintenance activityUpdated regularlyUpdated noticeably less often
Useful to run togetherThe primary toolA secondary cross-check with a different signature engine

When rootkit scanners do not protect you

  • As the only method of protection — both rkhunter and chkrootkit look for already-known signatures and typical traces; a targeted rootkit built for a specific victim can slip past both scanners unnoticed.
  • Checking an already-compromised system with its own utilities — if an attacker gained root, they may have replaced the rkhunter or chkrootkit binaries themselves, or the libraries they depend on, and the scanner will honestly report "clean" even though that is no longer true. A real investigation needs a disk image and analysis from external media.
  • Containers and immutable infrastructure, where the server is recreated from an image on every deploy — manually scanning for rootkits inside a container loses its point; the focus there is on image immutability and integrity checks before launch, not after.
  • Production with a strict SLA on load during a full scan — --check walks the entire filesystem and can cause noticeable disk load; such scans are scheduled for a low-load window rather than run manually at peak traffic.

Verifying that scanning is actually configured

# Confirm the file properties database exists and is not empty
ls -la /var/lib/rkhunter/db/rkhunter.dat

# Check the date of the last signature update
rkhunter --versioncheck

# Run a one-off check and look at the final summary right away
rkhunter --check --sk --rwo | tail -20

# Confirm the daily automated run is actually scheduled
ls -la /etc/cron.daily/rkhunter-check

A clean result means zero warnings in the System checks summary, a database file with a recent modification date, and an executable file in cron.daily with rwxr-xr-x permissions. If the cron file is missing or not executable, daily checks simply never run, regardless of what a manual scan showed.

Was this article helpful?
← Back to Knowledge Base Ask Support