Detect Rootkits on Linux with rkhunter

Deepak Prasad
Tested on RHEL 10.2 (Coughlan) — vm1.lab.example; Debian 12 (bookworm) container for apt install
Package rkhunter 1.4.6-31.el10_2 (RHEL via EPEL)
rkhunter 1.4.6-11 (Debian)
Applies to RHEL, Rocky Linux, AlmaLinux, Fedora, Ubuntu, Debian, and other Linux hosts with rkhunter packages
Privilege sudo or root
Scope Install rkhunter, update signatures when network allows, baseline with --propupd, run --check, and read /var/log/rkhunter/rkhunter.log. Does not replace antivirus, EDR, or incident response on a compromised host.
Related guides Install chkrootkit on Ubuntu
ClamAV on RHEL family
View logs with journalctl
grep command
Fail2ban SSH

Rootkit Hunter (rkhunter) compares your system against known rootkit signatures, suspicious ports, and (after you baseline it) stored file properties. Install steps differ by distribution; everything after that is the same rkhunter workflow.

Use one generic guide: a short install section per package family, then shared update → propupd → check → log steps tested on RHEL (vm1.lab.example) and Debian (apt install in a bookworm container).

IMPORTANT
rkhunter is a host integrity checker, not antivirus. It helps on a server you already trust or right after a clean install. If the host is already compromised, an attacker with root can tamper with rkhunter itself — pair scans with backups, package verification, and broader monitoring.

What rkhunter checks

rkhunter is a shell-based scanner that looks for:

  • Known rootkit files and directories
  • Listening ports associated with backdoors
  • Changes to system binaries compared with a baseline you store
  • Basic misconfigurations such as SSH settings that disagree with /etc/rkhunter.conf

It does not remove malware. It reports warnings so you can investigate.


Install on RHEL, Rocky Linux, AlmaLinux, and Fedora

On RHEL 10 the package comes from EPEL. Enable EPEL if it is not already present — see install EPEL on RHEL family when you need the full steps.

Install rkhunter with dnf:

bash
sudo dnf install -y rkhunter

Sample output:

output
Installed:
  rkhunter-1.4.6-31.el10_2.noarch
Complete!

Confirm the package and version:

bash
rkhunter --version

Sample output:

output
Rootkit Hunter 1.4.6

That NEVRA and version string confirm the EPEL build this guide uses on RHEL 10.


Install on Debian and Ubuntu

On Debian and Ubuntu, install from the distribution repository with apt. Refresh package indexes first:

bash
sudo apt update

Install the scanner package:

bash
sudo apt install -y rkhunter

The Debian package post-install script can run an initial rkhunter --propupd automatically. You still follow the baseline and check steps below so you know what landed on disk.

Verify the package:

bash
dpkg -l rkhunter

Sample output:

output
ii  rkhunter  1.4.6-11  all  rootkit, backdoor, sniffer and exploit scanner

Update rootkit signatures

Refresh rkhunter data files when the host can reach the upstream mirrors:

bash
sudo rkhunter --update

Sample output when the updater cannot download new data files:

output
Checking file mirrors.dat                                  [ Update failed ]
Checking file programs_bad.dat                             [ Update failed ]
Checking file backdoorports.dat                            [ Update failed ]
Checking file suspscan.dat                                 [ Update failed ]
Checking file i18n versions                                [ Update failed ]

Please check the log file (/var/log/rkhunter/rkhunter.log)

rkhunter --update needs access to its configured update sources. Proxy restrictions, DNS or network problems, WEB_CMD, mirror configuration in /etc/rkhunter.conf, or upstream availability can cause update failures.

Scans still run using databases shipped with the package under /var/lib/rkhunter/db/. Treat failures as a maintenance item — fix network or proxy access, adjust mirrors, or install a vendor package refresh when the bundled data is stale.

On Debian, if --update prints Invalid WEB_CMD configuration option, check WEB_CMD in /etc/rkhunter.conf (some defaults set it to /bin/false to block web downloads).


Baseline file properties with --propupd

Before you trust file-change warnings, store properties for system binaries on a known-good system:

bash
sudo rkhunter --propupd

Sample output:

output
[ Rootkit Hunter version 1.4.6 ]
File created: searched for 177 files, found 134

rkhunter writes rkhunter.dat under /var/lib/rkhunter/. Later checks compare live files against that baseline. Run --propupd only after you have verified that the changed files are legitimate. Package upgrades commonly change binaries, but confirm those changes with the package manager before updating the rkhunter baseline.


Run a rootkit check

Interactive rkhunter -c pauses for Enter between sections. For scripting and this walkthrough, use a non-interactive check that prints warnings only:

bash
sudo rkhunter --check --skip-keypress --report-warnings-only --nocolors

A full run on vm1.lab.example took about six minutes after the baseline step above. The lab host still reported policy warnings (SSH settings, empty backdoor-port data when --update failed) but Possible rootkits: 0 in the log summary.


Read warnings in the log file

Detailed output lands in /var/log/rkhunter/rkhunter.log. List recent warnings:

bash
sudo grep -i warning /var/log/rkhunter/rkhunter.log | tail -10

Read the summary block at the end of the last run:

bash
sudo grep -A6 'System checks summary' /var/log/rkhunter/rkhunter.log | tail -8

Sample output:

output
System checks summary
=====================

File properties checks...
    Files checked: 134
    Suspect files: 0

Rootkit checks...
    Rootkits checked : 476
    Possible rootkits: 0

Possible rootkits: 0 means rkhunter did not flag a possible rootkit in those checks. It does not prove the system is clean — read other warnings in the log and treat rkhunter as one integrity check, not a full incident-response verdict.


Common warnings and false positives

Warning Likely meaning What to do
egrep / fgrep replaced by a script Normal on distributions that ship grep wrappers Accept after --propupd; investigate only if the script path changed recently
rkhunter.dat does not exist No baseline yet Run rkhunter --propupd on a trusted system
backdoorports.dat missing or empty --update failed or never run Fix updates or reinstall the package; scans still use other tests
SSH / ALLOW_SSH_ROOT_USER mismatch /etc/ssh/sshd_config differs from /etc/rkhunter.conf Align settings or set ALLOW_SSH_ROOT_USER in rkhunter.conf to match policy
Suspect files after propupd Binary changed since baseline Verify with rpm or dpkg which package owns the file
Warnings in a minimal container No kernel modules, no syslog, incomplete OS Expected in containers — run serious checks on full VMs or bare metal

Schedule regular checks (optional)

For unattended scans, --cronjob implies non-interactive checking, including --check, --nocolors, and --skip-keypress. Combine it with --report-warnings-only when you only want warnings in job output. Wire the command into cron or a systemd timer after you have tested the same flags manually.


Troubleshooting

Symptom Likely cause Fix
rkhunter: command not found Package not installed Install with dnf (EPEL) or apt as above
All --update lines show Update failed Network, proxy, WEB_CMD, mirror, or upstream problem Fix access or mirrors in /etc/rkhunter.conf; scan with bundled DB until updates work
Every file-property check warns Baseline never created Run sudo rkhunter --propupd once on a clean system
Check hangs waiting for input Interactive mode Add --skip-keypress or use --cronjob
Many warnings only inside containers Incomplete guest environment Run rkhunter on the full host, not a slim container image

References


Summary

Use one generic rkhunter article for Linux: install with dnf and EPEL on RHEL family hosts, install with apt on Debian and Ubuntu, then run the same maintenance commands everywhere. Update signatures when the network allows, run --propupd once on a trusted baseline, and scan with rkhunter --check --skip-keypress --report-warnings-only.

Read /var/log/rkhunter/rkhunter.log for the summary and grep warnings before you treat a hit as a rootkit — wrapper scripts, SSH settings, and failed updates generate noise. For a second opinion on Ubuntu, pair this with chkrootkit; for malware scanning, see ClamAV on RHEL family.


Frequently Asked Questions

1. Do I need separate rkhunter articles for RHEL and Ubuntu?

No. Package installation differs by distribution, but update, propupd, check, and log review use the same rkhunter commands everywhere. One generic guide with distro-specific install steps is enough.

2. What is the difference between rkhunter and chkrootkit?

chkrootkit focuses on known rootkit signatures and quick system checks. rkhunter adds file-property baselines, backdoor-port lists, and more configuration checks. Many admins run both and compare warnings.

3. Why does rkhunter --update fail?

rkhunter --update needs access to its configured update sources. Proxy restrictions, DNS or network problems, WEB_CMD, mirror configuration, or upstream availability can cause update failures. Installed package databases under /var/lib/rkhunter/db/ still work for scans until you fix access or refresh the package.

4. Why does rkhunter warn that egrep was replaced by a script?

On modern distributions grep often ships egrep and fgrep as shell wrappers. That is normal and not a rootkit by itself. Baseline the system with propupd on a known-good host and treat new changes as suspicious.

5. How long does an rkhunter check take?

A full check walks hundreds of files and rootkit signatures. On a small VM expect several minutes. Use --skip-keypress and --report-warnings-only for automation instead of the interactive check mode.
Omer Cakmak

Linux Administrator

Highly skilled at managing Debian, Ubuntu, CentOS, Oracle Linux, and Red Hat servers. Proficient in bash scripting, Ansible, and AWX central server management, he handles server operations on OpenStack, KVM, Proxmox, and VMware.

  • Debian
  • Ubuntu
  • Linux
  • Red Hat Enterprise Linux
  • Shell Script
  • System Administration