Cómo proteger un servidor Linux de Malware con Maldet y ClamAV

Actualizada:

A pesar de lo que pueda parecer, tenemos que tomar ciertas medidas en un servidor Linux para protegerlo del Malware o de virus, o más bien para proteger a nuestros usuarios de estos programas malintencionados, sobre todo si están usando PC con Windows.

Esto quiere decir, que realmente no tenemos que proteger nuestro servidor Linux de Virus: estamos ayudando a no pasar archivos peligrosos a nuestros usuarios. Otra cosa es evitar el malware que te pueda entrar a través de WordPress u otros programas creados mediante PHP.

¿Qué hay que hacer? Pues tenemos que instalar dos cosas, el antivirus ClamAV y Maldet (Linux Malware Detect).

¡Ojo! Presupongo que ya tienes en marcha tu servidor con Rocky Linux, alma Linux u otro sistema basado en RHEL.

  • ClamAV: es un antivirus Open Source que ofrece varias funciones para proteger a tu servidor de ataques de malware y virus. Utiliza freshclam para actualizar su base de datos todos los días. Es un programa que se usa mucho cuando gestionas un servidor de correo, para filtrar los adjuntos que puedan contener amenazas.
  • Maldet: en una app para servidores que nos permite vigilar en tiempo real las amenazas. Gracias a inotify podemos controlar todos los cambios que suceden en nuestro servidor. Maldet dispone de una base de datos de malware (más de 10.000 firmas), bastante centrada en PHP y Perl. ¿Queremos que todo vaya más rápido? Podemos hacerlo funcionar junto con la base de datos de ClamAV o con su daemon. Si Maldet detecta que tenemos instalado ClamAV, usara su motor para funcionar de manera más rápida y efectiva. Si Maldet detecta un archivo de Malware, te avisará, lo puede poner en cuarentena e incluso puede intentar limpiar el archivo.

¡Ojo! Tanto Maldet como ClamAV, usan muchos recursos dle servidor. Ahora mismo ClamAV está usando un 10 % de la memoria total de mi sistema, aproximadamente 1 GB de RAM. Tenlo en cuenta si tienes poca memoria RAM en tu servidor. Deberías configurar una buena partición SWAP. En mi servidor tengo 16 GB de RAM y tiene 6 núcleos.

Instalamos ClamAV

ClamAV en Virtualmin

¡Ojo! Si tienes en tu servidor instalado Virtualmin, vas a tener instalado por defecto ClamAV, y solo tienes que activarlo en Virtualmin > Email Settings > Spam and Virus Scanning.

Para poder instalar ClamAV en Rocky Linux, vas a tener que configurar el repositorio EPEL. ¡Ojo! Puede que tengas que ejecutar los comandos con Sudo.

dnf update
dnf install dnf-utils
dnf install epel-release

Ahora ya podemos instalar ClamAV y todos sus componentes:

dnf install clamav clamd clamav-update

Si usas SElinux, se lo tienes que contar:

setsebool -P antivirus_can_scan_system 1

Ahora podemos actualizar la base de datos de malware:

freshclam

Ahora activamos el servicio clamav-freshclam.service que activa la actualización automática de las definiciones de virus y [email protected] que activa el daemon que está corriendo siempre en memoria de tu servidor.

systemctl enable clamav-freshclam
systemctl start clamav-freshclam

systemctl enable clamd@scan
systemctl start clamd@scan

Probablemente, clamav-freshclam este activado por defecto, pero no está de más comprobarlo.

Ahora ya tienes instalado ClamAV, y puedes correr el antivirus por el servidor con el comando:

clamscan -r /home/tuusuario/public_html/

Pero tienes que configurar un poco el archivo de configuración para evitar escanear determinados directorios. Vas a /ect/clamd.d/scan.conf y lo editas. Te pongo en negrita algunas cosas importantes a configurar.

Lo crucial, es configurar los logs, y evitar que se escaneen directorios como /proc/
/sys/ o /dev/
. Si instalas Maldetect, no es necesario escanear el disco con ClamAV ni de forma manual ni en forma de trabajo cron. ¡Ojo! Nada de usar ClamAV con el usuario root. Lo mejor es utilizar un usuario específico para correr el programa (User clamscan).

Parte del archivo de configuración de ClamAV en servidor con Rocky Linux.

En un archivo de configuración de ClamAV en tu servidor encontrarás más parámetros a configurar, pero estos son los que me parecen más importantes. Los demás los puedes dejar con sus valores por defecto. Hay muchos en yes (sí). Puedes revisarlos. Parte de las alertas heurísticas no están activadas por defecto. Tengo sentimientos encontrados sobre si activarlas o no.

##
## Example config file for the Clam AV daemon
## Please read the clamd.conf(5) manual before editing this file.
##

# Comment or remove the line below.
#Example

# Uncomment this option to enable logging.
# LogFile must be writable for the user running daemon.
# A full path is required.
# Default: disabled
LogFile /var/log/clamd.scan

# Maximum size of the log file.
# Value of 0 disables the limit.
# You may use 'M' or 'm' for megabytes (1M = 1m = 1048576 bytes)
# and 'K' or 'k' for kilobytes (1K = 1k = 1024 bytes). To specify the size
# in bytes just don't use modifiers. If LogFileMaxSize is enabled, log
# rotation (the LogRotate option) will always be enabled.
# Default: 1M
LogFileMaxSize 2M

# Log time with each message.
# Default: no
LogTime yes

# Use system logger (can work together with LogFile).
# Default: no
LogSyslog yes

# Enable verbose logging.
# Default: no
LogVerbose yes

# Enable log rotation. Always enabled when LogFileMaxSize is enabled.
# Default: no
LogRotate yes

# Log additional information about the infected file, such as its
# size and hash, together with the virus name.
ExtendedDetectionInfo yes

# Path to a local socket file the daemon will listen on.
# Default: disabled (must be specified by a user)
LocalSocket /run/clamd.scan/clamd.sock

# Sets the permissions on the unix socket to the specified mode.
# Default: disabled (socket is world accessible)
#LocalSocketMode 660
LocalSocketMode 666

# Remove stale socket after unclean shutdown.
# Default: yes
FixStaleSocket yes

# Don't scan files and directories matching regex
# This directive can be used multiple times
# Default: scan all
ExcludePath ^/proc/
ExcludePath ^/sys/
ExcludePath ^/dev/

# Maximum depth directories are scanned at.
# Default: 15
MaxDirectoryRecursion 15

# Follow directory symlinks.
# Default: no
FollowDirectorySymlinks no

# Follow regular file symlinks.
# Default: no
FollowFileSymlinks no

# Execute a command when virus is found.
# Use the following environment variables to identify the file and virus names:
# - $CLAM_VIRUSEVENT_FILENAME
# - $CLAM_VIRUSEVENT_VIRUSNAME
# In the command string, '%v' will also be replaced with the virus name.
# Note: The '%f' filename format character has been disabled and will no longer
# be replaced with the file name, due to command injection security concerns.
# Use the 'CLAM_VIRUSEVENT_FILENAME' environment variable instead.
# For the same reason, you should NOT use the environment variables in the
# command directly, but should use it carefully from your executed script.
# Default: no
VirusEvent /opt/send_virus_alert.sh

# Run as another user (clamd must be started by root for this option to work)
# Default: don't drop privileges
User clamscan

# Enable internal e-mail scanner.
# If you turn off this option, the original files will still be scanned, but
# without parsing individual messages/attachments.
# Default: yes
ScanMail yes

# ClamAV can scan within archives and compressed files.
# If you turn off this option, the original files will still be scanned, but
# without unpacking and additional processing.
# Default: yes
ScanArchive yes

Ahora debes crear el script para que te llegue un aviso por email cada vez que Clamd encuentre un virus cuando sea usado con Maldet. Lo creas en /opt/send_virus_alert.sh (vi /opt/send_virus_alert.sh):

#!/bin/bash

# Obtener información del entorno proporcionada por ClamAV
FILENAME="$CLAM_VIRUSEVENT_FILENAME"
VIRUSNAME="$CLAM_VIRUSEVENT_VIRUSNAME"

# Obtener la fecha y hora actuales
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")

# Enviar alerta por correo electrónico
EMAIL_SUBJECT="Alerta de virus - $VIRUSNAME detectado"
EMAIL_BODY="Fecha y hora: $TIMESTAMP
Virus detectado: $VIRUSNAME
Archivo infectado: $FILENAME
"

echo "$EMAIL_BODY" | mail -s "$EMAIL_SUBJECT" [email protected]

El script debe ser ejecutable:

sudo chmod +x /opt/send_virus_alert.sh

Y reinicias el servicio de clamd. Cada vez que se encuentre malware o virus en tu sistema, te llegara un email al correo seleccionado en este archivo.

En /etc/logrotate.d/clamd.scan creas este archivo para que el log de ClamAV vaya rotando y no te llene el disco duro:

/var/log/clamd.scan {
	weekly
	rotate 4
	compress
	missingok
	notifempty
	postrotate
	/bin/systemctl reload [email protected] > /dev/null
	endscript
}

El servicio clamav-freshclam no consume muchos recursos. clamd@scan si consume muchos recursos, sobre todo RAM (se quedan en memoria todas las firmas de los virus y malware).

¿Quieres usar las bases de datos de Maldet directamente en ClamAV? Tienes que editar el archivo /etc/freshclam.conf y poner lo siguiente (solo, si no vas a usar Maldet):

DatabaseCustomURL http://www.rfxn.com/downloads/rfxn.ndb
DatabaseCustomURL http://www.rfxn.com/downloads/rfxn.hdb
DatabaseCustomURL http://www.rfxn.com/downloads/rfxn.yara

Evidentemente, puedes ir añadiendo otras fuentes de «signatures» de terceros. Puedes probar las de https://sanesecurity.com/usage/signatures/, y colocarlas de este tipo de URL cambiando el nombre de la base de datos (vía https://forum.opnsense.org/index.php?topic=14024.0). No pongas todas al mismo tiempo, vete probando. El listado completo en https://ftp.swin.edu.au/sanesecurity/:

DatabaseCustomURL https://ftp.swin.edu.au/sanesecurity/junk.ndb

En este archivo también puedes activar el log de freshclam, que te va a servir para comprobar que las actualizaciones de la base de datos de virus están al día: /var/log/freshclam.log. O puedes cambiar el parámetro Checks, que por defecto está en 12 (comprobaciones cada dos horas).

Llegados a este punto tienes que decidir si Maldet va a funcionar solo con las actualizaciones de clamav-freshclam o si va a usar también clamd@scan. O si solo quieres usar ClamAV:

  1. Exclusivamente usando Maldet sin ClamAV: Maldet utiliza sus propias firmas para detectar malware. No necesitas ni freshclam ni clamd. Pero pierdes en rendimiento y la enorme base de datos de virus de Clamav.
  2. Usando Maldet con las firmas de ClamAV: Si quieres que Maldet utilice las firmas de ClamAV para mejorar la detección de malware, necesitas tener freshclam activo para actualizar las firmas. En este caso, Maldet puede realizar los escaneos sin necesidad de clamd. Los escaneos no son en tiempo real.
  3. Usando Maldet y delegando los escaneos a ClamAV: Necesitas tener tanto freshclam como clamd activos. Maldet puede ser configurado para utilizar el motor de ClamAV para ser más eficiente. Escaneos en tiempo real a costa de usar más memoria RAM.
  4. Solamente vas a usar ClamAV con las bases de datos de Maldet: puede configurar ClamAV para que use las bbdd de Maldet y ganar en detección d epeligros para PHP (algo que viene bien para WordPress).

Instalamos Maldet en el servidor

Ahora necesitamos instalar Maldet en el servidor, y en este caso, el programa no está disponible en ningún repositorio de Rocky Linux, ni de ninguna otra distribución Linux. Puedes instalarlo directamente desde su web o descargarlo de GitHub. La versión más actual en estos momentos es de abril de 2023 (1.6.5). ¿Qué tiene de especial Maldet? Nos ofrece protección extra contra malware PHP y PERL, y tiene tres bases de datos con amenazas:

  • http://www.rfxn.com/downloads/rfxn.ndb
  • http://www.rfxn.com/downloads/rfxn.hdb
  • http://www.rfxn.com/downloads/rfxn.yara

Primero instalamos algunas dependencias que vas a necesitar:

dnf install wget tar perl inotify-tools -y
cd /usr/local/src
wget http://www.rfxn.com/downloads/maldetect-current.tar.gz
tar xzvf maldetect-current.tar.gz
cd maldetect-1.6.5
./install.sh

Este programa de instalación lo va a poner en marcha todo, e incluso actualizará las últimas versiones de su base de datos de malware. Pero luego puedes hacerlo tú mismo con estos comandos:

#Actualiza el propio programa
maldet -d

#Actualiza la bbdd de virus y malware
maldet -u

¿Tenemos que cambiar cosas en su archivo de configuración? Efectivamente.

Vamos a /usr/local/maldetect/conf.maldet y cambiamos varias cosas, pero lo más importante a cambiar es:

Parte de archivo de  configuración de Maldet en un servidor con Rocky Linux 9
  • email_alert: Si quieres recibir alertas por correo electrónico, entonces debes poner en 1
  • email_addr: Pon tu dirección de correo electrónico para recibir alertas de malware.
  • autoupdate_signatures y autoupdate_version en 1 para que todo se actualice forma automática.
  • cron_daily_scan: ponlo en 1 para que se realicen análisis automáticos todos los días de los directorios seleccionados.
  • scan_clamscan: lo ponemos en 1 para que Maldet se conecte a ClamAV.
  • scan_ignore_root: si lo tienes en 1, Maldet va a ignorar los archivos y directorios creados por root. Mejora el rendimiento, pero presupone que tu usuario root es seguro.
  • quarantine_hits: La acción de cuarentena predeterminada. Si pones 1 la activas. Los archivos afectados se trasladarán a la cuarentena. Yo lo tengo en 0 para que solo me avise de las alertas.
  • quarantine_clean: ¿quieres limpiar el malware de forma automática? Pon 1. Yo lo tengo en 0 para revisarlo yo a mano.
  • default_monitor_mode: lo ponemos en «users» para que con la orden siguiente tenga en cuenta los directorios home/tusuaurio/public_html
  • inotify_docroot: El directorio web. De forma predeterminada, está establecido en public_html.

¡Dato! Puedes cambiar default_monitor_mode=»users» a default_monitor_mode=»/usr/local/maldetect/monitor_paths» y poner en el archivo monitor_paths las rutas a las carpetas que quieres vigilar.

##
# Linux Malware Detect v1.6.5
#             (C) 2002-2023, R-fx Networks <[email protected]>
#             (C) 2023, Ryan MacDonald <[email protected]>
# This program may be freely redistributed under the terms of the GNU GPL v2
##
#
##
# [ General Options ]
##

# Enable or disable e-mail alerts, this includes application version
# alerts as well as automated/manual scan reports. On-demand reports
# can still be sent using '--report SCANID [email protected]'.
# [0 = disabled, 1 = enabled]
email_alert="1"

# The destination e-mail addresses for automated/manual scan reports
# and application version alerts.
# [ multiple addresses comma (,) spaced ]
email_addr="[email protected]"

# This controls the daily automatic updates of LMD signature files
# and cleaner rules. The signature update process preserves any
# custom signature or cleaner files. It is highly recommended that this
# be enabled as new signatures a released multiple times per-week.
# [0 = disabled, 1 = enabled]
autoupdate_signatures="1"

# This controls the daily automatic updates of the LMD installation.
# The installation update process preserves all configuration options
# along with custom signature and cleaner files. It is recommended that
# this be enabled to ensure the latest version, features and bug fixes
# are always available.
# [0 = disabled, 1 = enabled]
autoupdate_version="1"

# This controls validating the LMD executable MD5 hash with known
# good upstream hash value. This allows LMD to replace the the
# executable / force a reinstallation in the event the LMD executable
# is tampered with or corrupted. If you intend to make customizations
# to the LMD executable, you should disable this feature.
# [0 = disabled, 1 = enabled]
autoupdate_version_hashed="1"

# The retention period, in days, which quarantine, temporary files and stale
# session information should be retained. Data older than this value is deleted
# with the daily cron execution.
cron_prune_days="21"

# This controls whether or not daily automatic scanning of standard web
# directories is performed via cron.
# [0 = disabled, 1 = enabled]
cron_daily_scan="1"

# The expiry interval for refreshing the local cached version of the imported
# configuration file. The default is every 12h (43200 sec) which should be ok
# for most setups.
import_config_expire="43200"

# When defined, the import_custsigs_*_url options allow for the custom signature
# files to be downloaded from a remote URL. THIS WILL OVERWRITE ANY LOCAL CUSTOM
# SIGNATURE FILES! It is recommended for large-scale deployments to define these
# variables within a import_config_url file.
import_custsigs_md5_url=""
import_custsigs_hex_url=""

##
# [ SCAN OPTIONS ]
##

# The maximum directory depth that the scanner will search, a value
# of 10-15 is recommended.
# [ changing this may have an impact on scan performance ]
scan_max_depth="15"

# The minimum file size in bytes for a file to be included in LMD scans.
# [ changing this may have an impact on scan performance ]
scan_min_filesize="24"

# The maximum file size for a file to be included in LMD scans. Accepted
# value formats are b, k, M. When using the clamscan engine, the max_filesize
# will be dynamically set based on the largest known filesize from the MD5
# hash signature file.
# [ changing this may have an impact on scan performance ]
scan_max_filesize="2048k"

# The maximum byte depth that the scanner will search into a files content.
# The default signature rules expect a depth size of at least 65536 bytes.
# [ changing this may have an impact on scan performance ]
scan_hexdepth="65536"

# Use named pipe (FIFO) for passing file contents hex data instead of stdin
# default; improved performance and greater scanning depth. This is highly
# recommended and works on most systems. The hexfifo will be disabled
# automatically if for any reason it can not be successfully utilized.
# [ 0 = disabled, 1 = enabled ]
scan_hexfifo="1"

# The maximum byte depth that the scanner will search into a files content
#s when using named pipe (FIFO). Improved performance allows for greater
# scan depth over default scan_hexdepth value.
# [ changing this may have an impact on scan performance ]
scan_hexfifo_depth="524288"

# If installed, use ClamAV clamscan binary as default scan engine which
# provides improved scan performance on large file sets. The clamscan
# engine is used in conjunction with native ClamAV signatures updated
# through freshclam along with LMD signatures providing additional
# detection capabilities.
# [ 0 = disabled, 1 = enabled ]
scan_clamscan="1"

# Include the scanning of known temporary world-writable paths for
# -a|--al and -r|--recent scan types.
scan_tmpdir_paths="/tmp /var/tmp /dev/shm /var/fcgi_ipc"

# Allows non-root users to perform scans. This must be enabled when
# using mod_security2 upload scanning or if you want to allow users
# to perform scans. When enabled, this will populate 'pub/' with user
# owned quarantine, session and temporary paths to facilitate scans.
# [ 0 = disabled, 1 = enabled, disabled by default ]
scan_user_access="0"

# Process CPU scheduling (nice) priority level for scan operations.
# [ -19 = high prio , 19 = low prio, default = 19 ]
scan_cpunice="19"

# Process IO scheduling (ionice) priority levels for scan operations.
# (uses cbq best-effort scheduling class [-c2])
# [ 0 = most favorable IO, 7 = least favorable IO ]
scan_ionice="6"

# Set hard limit on CPU usage for find and clam(d)scan processes. This
# requires the 'cpulimit' binary to be available on the server. The values
# are expressed as relative percentage * N cores on system. An 8 CPU core
# server would accept values from 0 - 800, 12 cores 0 - 1200 etc...
scan_cpulimit="0"

# As a design and common use case, LMD typically only scans user space paths
# and as such it makes sense to ignore files that are root owned. It is
# recommended to leave this enabled for best performance.
# [ 0 = disabled, 1 = enabled ]
scan_ignore_root="1"

# This allows for specific user or groups to be ignored entirely from scan
# file lists. This option should be used with care and is not ideal for
# ignoring false positives. Instead, you should use one of the ignore files,
# such as ignore_paths, to exclude a specific file name or path from scans.
# [ comma or white spaced list of user and group names ]
scan_ignore_user=""
scan_ignore_group=""

# The maximum amount of time, in seconds, that the 'find' file list generation
# will run before it is terminated. All 'find' results up to the point of
# termination will be fully scanned. If performing a full scan of all user paths
# on a large server, it is reasonable to expect the find operation may take a
# long time to complete and as such this feature may interfere. In such cases,
# this feature can be disabled/modified on a per-scan basis using the
# '-co|--config-option' CLI option, such as:
# "maldet -co scan_find_timeout=0 -a /home/?/public_html".
# [ 0 = disabled, 14400 = 4hr recommended timeout ]
scan_find_timeout="0"

# The '-r|--recent' 'find' operation performed by LMD detects recently created/modifed
# user files. This 'find' operation can be especially resource intensive and it may
# be desirable to persist the file list results so that other applications/tasks
# may make use of the results. When scan_export_filelist is set enabled, the most
# recent result set will be saved to '/usr/local/maldetect/tmp/find_results.last'
# [ 0 = disabled, 1 = enabled ]
scan_export_filelist="0"

##
# [ QUARANTINE OPTIONS ]
##
# The default quarantine action for malware hits
# [0 = alert only, 1 = move to quarantine & alert]
quarantine_hits="0"

# Try to clean string based malware injections
# [NOTE: quarantine_hits=1 required]
# [0 = disabled, 1 = clean]
quarantine_clean="0"

# The default suspend action for users wih hits
# Cpanel suspend or set shell /bin/false on non-Cpanel
# [NOTE: quarantine_hits=1 required]
# [0 = disabled, 1 = suspend account]
quarantine_suspend_user="0"

# The minimum userid value that can be suspended
# [ default = 500 ]
quarantine_suspend_user_minuid="500"

# When using an external scan engine, such as ClamAV, should files be
# quarantined if an error from the scanner engine is received?
# This is defaulted to 1, always quarantine, as ClamAV generates an
# error exit code for trivial errors such as file not found. As such, a
# large percentage of scans will have ClamAV exiting with error code 2.
# [ 0 = do not quarantine, 1 = always quarantine ]
quarantine_on_error="1"

##
# [ MONITORING OPTIONS ]
##
# The default startup option for monitor mode, either 'users' or path to line
# spaced file containing local paths to monitor.
#
# This option is optional for the init based startup script, maldet.sh. This
# value is ignored when '/etc/sysconfig/maldet' or '/etc/default/maldet' is
# present with a defined value for $MONITOR_MODE.
#
# This option is REQUIRED for the systemd maldet.service script. That script
# only checks for the value of $default_monitor_mode. The service will fail to
# start if a value is not provided.
default_monitor_mode="users"
# default_monitor_mode="/usr/local/maldetect/monitor_paths"

# The base number of files that can be watched under a path,
# this ends up being a relative value per-user in user mode.
# [ maximum file watches = inotify_base_watches*users ]
inotify_base_watches="16384"

# The sleep time in seconds between monitor runs to scan files
# that have been created/modified/moved.
inotify_sleep="15"

# The interval in seconds that inotify will reload configuration
# data, including remote configuration imports and user signatures.
inotify_reloadtime="3600"

# The minimum userid that will be added to path monitoring when
# the USERS option is specified.
inotify_minuid="500"

# This is the html/web root for users relative to homedir, when
# this option is set, users will only have the webdir monitored
# [ comma spaced list, clear option to default monitor user homedir ]
inotify_docroot="public_html,public_ftp"

# Process CPU scheduling (nice) priority level for scan operations.
# [ -19 = high prio , 19 = low prio, default = 19 ]
inotify_cpunice="18"

# Process IO scheduling (ionice) priority levels for scan operations.
# (uses cbq best-effort scheduling class [-c2])
# [ 0 = most favorable IO, 7 = least favorable IO ]
inotify_ionice="6"

# Set hard limit on CPU usage for inotify monitoring processes. This requires
# the 'cpulimit' binary to be available on the server. The values are expressed
# as relative percentage * N cores on system. An 8 CPU core system would accept
# values from 0 - 800, a 12 cores system would accept 0 - 1200 etc...
inotify_cpulimit="0"

# Log every file scanned by inotify monitoring mode; this is not recommended
# and will drown out your 'event_log' file, intended only for debugging purposes.
inotify_verbose="0"

# Remote clamd support
# If you're running a dedicated clamd server, you can instruct clamdscan to use
# it instead of the local daemon (which doesn't even need to run). To use
# this you need to create a 'clamd.remote.conf' with:
#
# TCPSocket 3310
# TCPAddr clamd.example.com
#
# Enable connecting to a remote clamd service to conduct all file scanning
# offload from local system. This requires that clamdscan binary be available
# to the local system.
#
# Files being scanned are effectively piped to remote daemon, this can be very
# bandwidth intensive.
# [ 0 = disabled, 1 = enabled ]
scan_clamd_remote="0"

# To instruct maldetect to use that config, enter the path to that file:
remote_clamd_config="/etc/clamd.d/clamd.remote.conf"

# If remote clamd doesn't respond properly, how many times should we retry
# the same file
remote_clamd_max_retry="5"

# How many seconds to sleep between retrys
remote_clamd_retry_sleep="3"

Ahora puedes incluir los logs de Maldet en logrotate para que no se hagan muy pesados con el tiempo. Creas un archivo en /etc/logrotate.d/maldet (yo lo he hecho con Webmin/virtualmin):

Ahora puedes incluir los logs de Maldet en logrotate
/usr/local/maldetect/logs/event_log {
	rotate 7
	size 100M
	missingok
	notifempty
	nocompress
}

/usr/local/maldetect/logs/clamscan_log /usr/local/maldetect/logs/inotify_log {
	rotate 7
	size 100M
	missingok
	notifempty
	nocompress
	postrotate
	/bin/systemctl reload maldet.service > /dev/null 2>/dev/null || true
	endscript
}

Ahora solo tenemos que poner en marcha Maldet:

systemctl start maldet

Puedes consultar todos los logs de Maldet en:

  • /usr/local/maldetect/logs/event_log
  • /usr/local/maldetect/logs/clamscan_log
  • /usr/local/maldetect/logs/inotify_log

Y es importante hacerlo, porque vamos a descubrir unas cuantas cosas interesantes sobre el funcionamiento dle programa, incluidos los archivos y directorios a los que no puede acceder Maldet (ClamAV).

¿Has activado Maldet y no tienes el daemon activo de ClamAV? Te aparecerá un mensaje como este: warning clamd service not running; force-set monitor mode file scanning to every 120s. En este caso, Maldet no va a monitorear en tiempo real tus directorios, solo lo va a hacer cada 120 segundos. Si tienes activo clamd@scan (el daemon), el análisis es en tiempo real, y la única pega es que va a consumir algo de memoria RAM (como 1 GB aproximadamente). Tú decides que quieres hacer. Probablemente, si eres tu el único usuario del servidor, no te haga falta clamd@scan. Pero si tienes una web que permite subidas de archivos o un foro, es posible que tener activo clamd@scan sea imprescindible.

Deberías de tener en tu Cron varios trabajos creados por Maldet para realizar varias acciones:

*/5 * * * * /usr/local/maldetect/maldet --mkpubpaths >> /dev/null 2>&1

El comando anterior se utiliza para actualizar cada 5 minutos las rutas monitorizadas por maldet: las rutas de acceso que se van a escanear en busca de malware.

Pero también uno en /etc/cron.daily/maldet, que se debe ejecutar diariamente gracias a /etc/anacrontab en rocky Linux (1 5 cron.daily nice run-parts /etc/cron.daily):

#!/usr/bin/env bash
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
export LMDCRON=1
inspath='/usr/local/maldetect'
intcnf="$inspath/internals/internals.conf"

if [ -f "$intcnf" ]; then
	source $intcnf
else
	echo "\$intcnf not found."
	exit 1
fi
if [ -f "$cnf" ]; then
	source $cnf
	if [ -f "$compatcnf" ]; then
	        source $compatcnf
	fi
else
	echo "could not find \$cnf, fatal error, bye."
	exit 1
fi

if [ -f "/etc/sysconfig/maldet" ]; then
	. /etc/sysconfig/maldet
elif [ -f "/etc/default/maldet" ]; then
	. /etc/default/maldet
fi

if [ -f "$cron_custom_conf" ]; then
	. $cron_custom_conf
fi

if [ -z "$scan_days" ]; then
	scan_days=1
fi

if [ -z "$cron_prune_days" ]; then
	cron_prune_days=21
fi

if [ "$find" ]; then
	# prune any quarantine/session/tmp data older than 7 days
	tmpdirs="$tmpdir $varlibpath/sess $varlibpath/quarantine $varlibpath/pub"
	for dir in $tmpdirs; do
	 if [ -d "$dir" ]; then
	  $find $dir -type f -mtime +${cron_prune_days} -print0 | xargs -0 rm -f >> /dev/null 2>&1
	 fi
	done
fi

if [ "$autoupdate_version" == "1" ] || [ "$autoupdate_signatures" == "1" ]; then
	# sleep for random 1-999s interval to better distribute upstream load
	sleep $(echo $RANDOM | cut -c1-3) >> /dev/null 2>&1
fi

if [ "$autoupdate_version" == "1" ]; then
	# check for new release version
	$inspath/maldet -d >> /dev/null 2>&1
fi

if [ "$autoupdate_signatures" == "1" ]; then
	# check for new definition set
	$inspath/maldet -u >> /dev/null 2>&1
fi

# if we're running inotify monitoring, send daily hit summary
if [ "$(ps -A --user root -o "cmd" | grep -E maldetect | grep -E inotifywait)" ]; then
        $inspath/maldet --monitor-report >> /dev/null 2>&1
elif [ "$cron_daily_scan" == "1" ]; then
	if [ -d "/home/virtual" ] && [ -d "/usr/lib/opcenter" ]; then
		# ensim
	        $inspath/maldet -b -r /home/virtual/?/fst/var/www/html/,/home/virtual/?/fst/home/?/public_html/ $scan_days >> /dev/null 2>&1
	elif [ -d "/etc/psa" ] && [ -d "/var/lib/psa" ]; then
		# psa
		$inspath/maldet -b -r /var/www/vhosts/?/ $scan_days >> /dev/null 2>&1
        elif [ -d "/usr/local/directadmin" ]; then
                # DirectAdmin
                $inspath/maldet -b -r /home?/?/domains/?/public_html/,/var/www/html/?/ $scan_days >> /dev/null 2>&1
	elif [ -d "/var/www/clients" ]; then
		# ISPConfig
                $inspath/maldet -b -r /var/www/clients/?/web?/web,/var/www/clients/?/web?/subdomains,/var/www $scan_days >> /dev/null 2>&1
	elif [ -d "/etc/webmin/virtual-server" ]; then
		# Virtualmin
                $inspath/maldet -b -r /home/?/public_html/,/home/?/domains/?/public_html/ $scan_days >> /dev/null 2>&1
	elif [ -d "/usr/local/ispmgr" ] || [ -d "/usr/local/mgr5" ]; then
		# ISPmanager
		$inspath/maldet -b -r /var/www/?/data/,/home/?/data/ $scan_days >> /dev/null 2>&1
	elif [ -d "/var/customers/webs" ]; then
		# froxlor
		$inspath/maldet -b -r /var/customers/webs/ $scan_days >> /dev/null 2>&1
        elif [ -d "/usr/local/vesta" ] || [ -d "/usr/local/hestia" ]; then
                # VestaCP or HestiaCP
                $inspath/maldet -b -r /home/?/web/?/public_html/,/home/?/web/?/public_shtml/,/home/?/tmp/,/home/?/web/?/private/ $scan_days >> /dev/null 2>&1
        elif [ -d "/usr/share/dtc" ]; then
                # DTC
                if [ -f /var/lib/dtc/saved_install_config ]; then
                    . /var/lib/dtc/saved_install_config
                fi
                $inspath/maldet -b -r ${conf_hosting_path:-/var/www/sites}/?/?/subdomains/?/html/ $scan_days >> /dev/null 2>&1
	else
		# cpanel, interworx and other standard home/user/public_html setups
	        $inspath/maldet -b -r /home?/?/public_html/,/var/www/,/usr/local/apache/htdocs/ $scan_days >> /dev/null 2>&1
	fi
fi

if [ -f "$cron_custom_exec" ]; then
	. $cron_custom_exec
fi

Deberías comprobar que las rutas están ajustadas para tu sistema operativo o para el panel de control que uses (en mi caso Virtualmin/Webmin). Este cron también se va a encargar de tener actualizado Maldet y de limpiar los datos antiguos en cuarentena. Y hará un escaneo diario.

Pero yo he creado unos cuantos más:

Para actualizar Maldet (por si las moscas):

55 0 * * * (/usr/local/maldetect/maldet -d && /usr/local/maldetect/maldet -u) 2>&1 | mail -s 'UPDATE MALDET' [email protected]

Para analizar todos los días los directorios home (si tienes activado el escaneo en tiempo real no es muy necesario o el cron de Maldet en Cron Daily):

5 2 * * * /usr/local/maldetect/maldet -r /home/?/public_html 2>&1 | mail -s 'Informe MALDET' [email protected]

Excluimos determinadas rutas del escaneo de Maldet

Pues es bastante importante, porque si no, vas a tener los logs llenos de cosas que no quieres escanear. Debes evitar escanear archivos temporales creados por WordPress (su cache), en tu instalación de un foro (como Flarum) o archivos temporales de Matomo (estadísticas) o de tu base de datos MariaDB o MySQL.

Para ello tienes varios archivos que puedes utilizar en la instalación de Maldet:

  • /usr/local/maldetect/ignore_inotify
  • /usr/local/maldetect/ignore_paths
  • /usr/local/maldetect/ignore_file_ext

Como funcionan con Regex, puedes ir creando tus patrones. Aquí tienes unos cuantos ejemplos:

Para Matomo Analytics en /usr/local/maldetect/ignore_inotify:

^/home/tuusuario/public_html/matomo/tmp/.*$

Para WordPress en /usr/local/maldetect/ignore_inotify:

^/home/.*/public_html/wp-content/cache/.*$

Para bases de datos MySQL o MariaDB en /usr/local/maldetect/ignore_inotify:

^/var/tmp/systemd.*/tmp/#sql-.*\.MAD$
^/var/tmp/systemd.*/tmp/#sql-.*\.MAI$

Para el foro Flarum en /usr/local/maldetect/ignore_inotify:

^/home/tuusuario/public_html/storage/cache/.*$
^/home/tuusuario/public_html/storage/sessions/.*$
^/home/tuusuario/public_html/storage/views/.*$
^/home/tuusuario/public_html/storage/tmp/.*$

Recuerda que ya hemos quitado unos cuantos directorios del escaneo en ClamAV.

Pero puedes ir repasando los logs de vez en cuando y ver qué archivos te dan problemas. Repito: deberías de excluir el escaneo de archivos temporales, cachés y demás para mejorar el rendimiento de ClamAV y Maldet.

En /usr/local/maldetect/logs/clamscan_log vas a ver mensajes del tipo: ERROR: Can’t access file, lo que indica que ClamAV y Maldet no han podido acceder a esos archivos. Normalmente, suelen ser archivos temporales que puede omitir en el escaneo.

Otras veces, lo que sucede, es que al estar corriendo ClamAV con su propio usuario, no tiene permisos para acceder a esos archivos. Por ejemplo, el servidor web (httpd) tiene la variable «PrivateTmp=yes» en sus archivos .service de Systemd, lo que impide que otros servicios (como clamd) accedan a los archivos que ponen dentro en la carpeta /tmp/.

¡Ojo! Recuerda reiniciar Maldet cada vez que cambies algo en su configuración.

systemctl stop maldet.service
systemctl start maldet.service

¿Último truco? Pon el siguiente comando en el terminal:

status de Maldet en el servidor con el comando: systemctl status maldet.service
systemctl status maldet.service
  • Vas a poder comprobar el estado de Maldet y sobre todo, qué directorios estás vigilando en tu servidor. Y cuanta memoria está usando Maldet, en mi caso, unos 500 MB.

Si vas a /usr/local/maldetect/sess/ y buscas los archivos inotify.paths. Vas a poder comprobar qué directorios están bajo los escaneos con inotify.

Comandos que puedes usar en Maldet para escanear archivos de forma manual

Tienes unos cuantos, y a lo mejor te interesa leerte su página de manual o meterte en help (maldet –help):

Crea una lista de archivos en ese directorio y luego las escanea. Luego te da un reporte.

#un solo directorio
maldet --scan-all /home/tuusuario/public_html/

#Todos los directorios public_html
maldet --scan-all /home/?/public_html/

#Escanea solo los archivos que hayan sido creados o cambiados los últimos 7 días
maldet --scan-recent /home/tuusuario/public_html/ 7

Si no tienes activa la opción de meter en cuarentena, puedes hacer que esos archivos vayan a cuarentena e incluso limpiarlos (cambias SCAN ID por el número que te haya salido en el paso anterior). ¿Falso positivo y tienes activa la cuarentena? Restauras el archivo con el tercer comando:

maldet –quarantine SCAN ID
maldet –clean SCAN ID
maldet –restore NOMBRE ARCHIVO

Puedes listar todos los reportes:

 maldet -e list

Y un comando muy útil para tener contenidos los datos del programa (Borrar registros, cuarentena, sesiones y datos temporales):

maldet -p

Probamos que Maldet funciona y que está bien configurado

¿Cómo podemos probar su funcionamiento? Solo tenemos que descargar un archivo de prueba de European Institute for Computer Antivirus Research (EICAR). Te vas a descargar un archivo inofensivo, pero que tiene en su interior un patrón que puedes encontrar en muchos archivos de malware.

Lo tienes que descargar en uno de los directorios que vigiles con Maldet (tienes varias opciones de descargar, incluidos archivos .zip, yo he elegido el .txt):

wget https://secure.eicar.org/eicar.com.txt

El problema que puedes encontrar al descargar esto, es que lo descargues con tu usuario root… ¡Y Maldet pase de este archivo porque en tu configuración has puesto que ignore los archivos de root! Tenlo en cuenta.

Si ejecutas maldet –scan-all /home/tuusurio/public_html/prueba, vas a obtener un informe como este:

Prueba de Maldet en Rocky Linux

En el resultado, incluso te da la opción de poner en cuarentena el archivo con el comando: maldet -q 240724-0703.61936 (es el número del informe generado).

En cuanto pasen unos segundos, vas a recibir un mensaje diciéndote que tienes un archivo de malware. Si tienes activa la cuarentena, el archivo pasará a /usr/local/maldetect/quarantine.

Conclusión

No es tan difícil poner en marcha la instalación de Maldet y ClamAV para luchar contra el malware en nuestros servidores, pero tienes que tener en cuenta que vas a pagar un tributo en forma de memoria RAM utilizada.

Tienes que decidir como quieres usar Maldet junto con ClamAV. Si tienes poca RAM, desactiva el daemon clamd, pero deja las actualizaciones de freshclam. Si puedes, deja todo activo y corriendo en tiempo real.

¿Comentarios? ¿Preguntas? Déjame un comentario en la siguiente sección 🙂

Referencias:


Descubre más desde algoentremanos.com

Suscríbete y recibe las últimas entradas en tu correo electrónico.

Foto del autor

Ivan Benito

Apasionado de la lectura y los viajes, experto en tecnología e informática y fan de la privacidad online. Desde el año 2007 me he dedicado al SEO, a escribir y a crear páginas web con WordPress sobre todo tipo de temáticas. Si tienes alguna duda y necesitas ayuda... ¡Pregúntame!

Si tienes preguntas, quieres que hagamos una review de una app, programa o producto, simplemente mándanos un e-mail mediante nuestro formulario de contacto. Te contestaremos en el menor tiempo posible. ¡Muchas gracias y salU2! Algoentremanos realiza reviews de manera profesional y en muchas ocasiones recibimos compensación de las compañías cuyos productos revisamos. Probamos cada producto a fondo y otorgamos altas calificaciones solo a los mejores. La propiedad de Algoentremanos.com es independiente y las opiniones expresadas aquí son solo nuestras. Algunos enlaces del artículo son afiliados: pueden generar un beneficio a algoentremanos.com. Saber más.

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.