Rootkit Hunter is, as its name describe, a rootkits detection tool. It can detect if a system has been compromised. It is a required tool for checking a system health. This guide describe how to configure rkhunter on Debian.
This howto is tested on:
- Debian 10.0 Buster
This howto is tested with these versions of the software:
- 1.4.6
Requirements
This howto recommends:
Settings
Set the external email address to which rootkits alerts are sent (set to local root account by default):
sysadminEmail="root"
Installation
Detect if sudo is available (“command” is used if not):
cmdProxy='command'
command type -f 'sudo' &>'/dev/null' && cmdProxy='sudo'
Install the software and its requirements:
${cmdProxy} apt install 'rkhunter' 'bsd-mailx'
Configuration
Create the modular configuration folder:
${cmdProxy} mkdir --parent '/etc/rkhunter.d'
Email notifications
Enable email notifications when the software find a problem:
${cmdProxy} tee '/etc/rkhunter.d/mail-on-warning.conf' <<< "#
# Email a message to this address if a warning is found when the system is
# being checked.
#
MAIL-ON-WARNING=${sysadminEmail}
# This option specifies the mail command to use if MAIL-ON-WARNING is set.
#MAIL_CMD=mail -s \"[rkhunter] Warnings found for ${HOST_NAME}\""
Enable all tests
By default, allow for all available tests:
${cmdProxy} sed -i -e 's/^DISABLE_TESTS=/#&/' '/etc/rkhunter.conf'
Enable all available tests:
${cmdProxy} tee '/etc/rkhunter.d/enabled-tests.conf' <<< "#
# These two options determine which tests are to be performed.
ENABLE_TESTS=ALL
DISABLE_TESTS=NONE"
Updates downloading
Choose the tool used to download updates:
${cmdProxy} tee '/etc/rkhunter.d/web-updates.conf' <<< "#
# If this option is set to '1', it specifies that when the '--update' option is
# used, then the mirrors file is to be checked for updates as well.
UPDATE_MIRRORS=1
# The MIRRORS_MODE option tells rkhunter which mirrors are to be used when
# the '--update' or '--versioncheck' command-line options are given.
# 0 - use any mirror
MIRRORS_MODE=0
# The following option can be set to a command which rkhunter will use when
# downloading files from the Internet - that is, when the '--update' or
# '--versioncheck' option is used. The command can take options.
WEB_CMD=wget"
Enable weekly updates of the threats database:
[[ -e '/etc/default/rkhunter' ]] \
&& ${cmdProxy} sed -i -e 's/^CRON_DB_UPDATE=.*$/CRON_DB_UPDATE="true"/' '/etc/default/rkhunter'
Files properties
Enable the checking of installed files properties against DPKG packages information:
${cmdProxy} tee '/etc/rkhunter.d/pkgmgr.conf' <<< "#
# The HASH_CMD option can be used to specify the command to use for the file
# properties hash value check.
# NOTE: Whenever this option is changed 'rkhunter --propupd' must be run.
HASH_CMD=SHA256
# The PKGMGR option tells rkhunter to use the specified package manager to
# obtain the file property information.
# NOTE: Whenever this option is changed 'rkhunter --propupd' must be run.
# Running --propupd takes about 4 times longer when it's set to DPKG
PKGMGR=DPKG"
Enable auto update of the files properties database when apt is called:
[[ -e '/etc/default/rkhunter' ]] \
&& ${cmdProxy} sed -i -e 's/^APT_AUTOGEN=.*$/APT_AUTOGEN="true"/' '/etc/default/rkhunter'
System.d networkd
Allow systemd-networkd to listen on network:
[ -x '/lib/systemd/systemd-networkd' ] \
&& ${cmdProxy} tee '/etc/rkhunter.d/systemd-networkd.conf' <<< "#
# Allow systemd-networkd to listen on network.
ALLOWPROCLISTEN=/lib/systemd/systemd-networkd"
Scripts whitelist
Trust “/usr/bin/which” symbolic link to “/bin/which” to be a script:
[ -h '/usr/bin/which' \
-a "$(command ls -l '/usr/bin/which' \
| command cut --delimiter=' ' --fields=13)" = '/bin/which' ] \
&& ${cmdProxy} tee '/etc/rkhunter.d/script-whitelist.conf' <<< "#
# Allow /usr/bin/which symbolic link to /bin/which to be a script.
SCRIPTWHITELIST=/usr/bin/which"
Deleted file usage whitelist
Allow some trusted processes the use of deleted files:
[ ! -e '/etc/rkhunter.d/allow-hidden-dir.conf' ] \
&& ${cmdProxy} tee '/etc/rkhunter.d/allow-hidden-dir.conf' <<< "#
# Allow the specified process to use deleted files. The process name may be
# followed by a colon-separated list of full pathnames (which have been
# deleted). The process will then only be whitelisted if it is using one of
# the given pathnames. For example:
# ALLOWPROCDELFILE=/usr/libexec/gconfd-2:/tmp/abc:/var/tmp/xyz"
while read -a trustedProcess; do
if [ -x "${trustedProcess}" ]; then
command grep --quiet "${trustedProcess}" '/etc/rkhunter.d/allow-hidden-dir.conf' 2>'/dev/null' \
|| ${cmdProxy} tee -a '/etc/rkhunter.d/allow-hidden-dir.conf' \
<<< "ALLOWPROCDELFILE=${trustedProcess}"
fi
done <<< "/lib/systemd/systemd-logind
/lib/systemd/systemd
/usr/sbin/sshd
/usr/bin/ssh
/usr/sbin/cron
/bin/run-parts
/bin/dash
/bin/sleep
/usr/lib/openssh/sftp-server
/usr/bin/python3.7
/usr/sbin/mysqld"
PHP-FPM
Allow PHP-FPM to use deleted ZendSem files:
while read -a version; do
# For each installed PHP-FPM version.
if [ -n "${version}" ]; then
command grep --quiet "php-fpm${version}" '/etc/rkhunter.d/php-fpm.conf' 2>'/dev/null' \
|| ${cmdProxy} tee -a '/etc/rkhunter.d/php-fpm.conf' <<< "
# Whitelist PHP-FPM ${version} usage of deleted ZendSem files.
ALLOWPROCDELFILE=/usr/sbin/php-fpm${version}:/tmp/.ZendSem.*"
fi
done <<< "$(command dpkg-query --show 'php[0-9]*-fpm' 2>'/dev/null' \
| command cut --delimiter=$'\t' --fields=2 \
| command awk 'NF' \
| command cut --delimiter='.' --fields=1-2)"
Allow Apache 2 to use deleted ZendSem files:
if [ -e '/etc/rkhunter.d/php-fpm.conf' -a -x '/usr/sbin/apache2' ]; then
command grep --quiet "/usr/sbin/apache2" '/etc/rkhunter.d/php-fpm.conf' 2>'/dev/null' \
|| ${cmdProxy} tee -a '/etc/rkhunter.d/php-fpm.conf' <<< "
# Allow Apache 2 to use ZendSem deleted files.
ALLOWPROCDELFILE=/usr/sbin/apache2:/tmp/.ZendSem.*"
fi
Allow Apache 2 to use secure System.d tmp directory for PHP:
if [ -e '/etc/rkhunter.d/php-fpm.conf' -a -x '/usr/sbin/apache2' ]; then
command grep --quiet "apache2.service" '/etc/rkhunter.d/php-fpm.conf' 2>'/dev/null' \
|| ${cmdProxy} tee -a '/etc/rkhunter.d/php-fpm.conf' <<< "
# Allow Apache 2 to store PHP related files in secure System.d tmp directory.
ALLOWPROCDELFILE=/usr/sbin/apache2:/tmp/systemd-private-*-apache2.service-*/tmp/php*"
fi
Gunicorn
Allow Gunicorn to use deleted files:
while read -a gunicornRunner; do
if [ -n "${gunicornRunner}" -a -x "${gunicornRunner}" ]; then
command grep --quiet "${gunicornRunner}" '/etc/rkhunter.d/gunicorn.conf' 2>'/dev/null' \
|| ${cmdProxy} tee -a '/etc/rkhunter.d/gunicorn.conf' <<< "
# Allow Gunicorn to use deleted files.
ALLOWPROCDELFILE=${gunicornRunner}:/tmp/wgunicorn-*"
fi
done <<< "$(${cmdProxy} ps ax \
| command grep -v 'grep' | command grep -e 'gunicorn' \
| command cut --delimiter=' ' --fields=2 \
| command xargs -iPID readlink -f '/proc/PID/exe' | uniq)"
Xen ‘xl’ command
Allow for installed xen-utils ‘xl’ command:
while read -a version; do
if [ -n "${version}" ]; then
command grep --quiet "/xen-${version}/" '/etc/rkhunter.d/xen.conf' 2>'/dev/null' \
|| ${cmdProxy} tee -a '/etc/rkhunter.d/xen.conf' <<< "#
# Whitelist xl from xen-utils ${version}.
RTKT_FILE_WHITELIST=/usr/lib/xen-${version}/bin/xl"
fi
done <<< "$(command dpkg-query --show 'xen-utils-[0-9]*' 2>'/dev/null' \
| command cut --delimiter=$'\t' --fields=2 \
| command awk 'NF' \
| command cut --delimiter='.' --fields=1-2)"
Byobu files in ‘/dev/shm’
Allow for byobu running files:
if [[ -n "$(command dpkg-query --show 'byobu' 2>'/dev/null' \
| command cut --delimiter=$'\t' --fields=2 \
| command awk 'NF')" ]]; then
${cmdProxy} tee '/etc/rkhunter.d/byobu.conf' <<< "#
# Whitelist byobu /dev/shm/ files.
ALLOWHIDDENDIR=/dev/shm/byobu-*-*/.last.tmux
ALLOWDEVFILE=/dev/shm/byobu-*-*/width
ALLOWDEVFILE=/dev/shm/byobu-*-*/cache.tmux/updates-available"
declare -a byobuFolders
declare -a byobuFiles
byobuFolders=( 'status.tmux' '.last.tmux' )
byobuFiles=( 'cpu_count' 'cpu_freq' 'disk' 'load_average' 'logo' \
'memory' 'release' 'session' 'uptime' )
for byobuFolder in "${byobuFolders[@]}"; do
for byobuFile in "${byobuFiles[@]}"; do
${cmdProxy} tee -a '/etc/rkhunter.d/byobu.conf' \
<<< "ALLOWDEVFILE=/dev/shm/byobu-*-*/${byobuFolder}/${byobuFile}"
done
done
fi
Allow remote SSH login by root user
Allowing root user to login directly by SSH is a bad idea. If you can not block the root SSH direct login, rkhunter must be configured to ignore this setting.
Disable the warning on allowed SSH login for root user (bad practice !):
if [[ -e '/etc/ssh/sshd_config' ]]; then
allowSshRootUser="$(command grep '^PermitRootLogin' '/etc/ssh/sshd_config' \
| command sed -e 's/^PermitRootLogin[ \t]*\([^ \t]*\)[ \t]*.*$/\1/')"
[[ -z "${allowSshRootUser}" ]] && allowSshRootUser='unset'
${cmdProxy} tee '/etc/rkhunter.d/allow-ssh-root-user.conf' <<< "#
# The following option is checked against the SSH configuration file
# 'PermitRootLogin' option. A warning will be displayed if they do not match.
ALLOW_SSH_ROOT_USER=${allowSshRootUser}"
fi
Finalization
Update the file properties database:
${cmdProxy} rkhunter --propupd
Update the threats database:
${cmdProxy} rkhunter --update
Run rkhunter for the first time to check if undue warnings are reported:
${cmdProxy} rkhunter --configfile '/etc/rkhunter.conf' \
--report-warnings-only --checkall
Enable daily rootkit checks by rkhunter:
[[ -e '/etc/default/rkhunter' ]] \
&& ${cmdProxy} sed -i -e 's/^CRON_DAILY_RUN=.*$/CRON_DAILY_RUN="true"/' '/etc/default/rkhunter'
Thanks
- Thanks to Rootkit Hunter (en) developers.
0 Comments