ClamAV es un antivirus de código abierto pensado para servidores: detecta malware en archivos subidos por usuarios, adjuntos de correo, webshells en directorios web y binarios sospechosos, tanto de Linux como de Windows. En este tutorial instalarás ClamAV en Ubuntu 24.04, comprobarás que las firmas se actualizan solas, escanearás archivos con el demonio clamd y programarás un análisis diario con un timer de systemd.
Requisitos previos
Para seguir esta guía necesitas:
- Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath.
- Un usuario no root con privilegios
sudo. - Al menos 2 GB de RAM. El demonio
clamdmantiene todas las firmas cargadas en memoria, lo que ocupa más de 1 GB, y durante la recarga de firmas el consumo puede duplicarse brevemente. - Acceso de salida a Internet por HTTPS para descargar las firmas.
Componentes de ClamAV
ClamAV se compone de varias piezas, y conviene saber cuál usar en cada caso:
| Componente | Paquete | Función |
|---|---|---|
freshclam | clamav-freshclam | Descarga y actualiza la base de firmas. Funciona como servicio. |
clamscan | clamav | Escáner independiente. Carga las firmas en cada ejecución, así que es lento para uso frecuente. |
clamd | clamav-daemon | Demonio que mantiene las firmas en memoria y escanea bajo petición. |
clamdscan | clamav-daemon | Cliente que envía archivos a clamd. Rápido, ideal para escaneos programados. |
Paso 1: Instalar ClamAV
Instala el escáner y el demonio desde los repositorios de Ubuntu. El paquete clamav-freshclam se instala como dependencia:
sudo apt update
sudo apt install clamav clamav-daemon
Comprueba la versión instalada:
clamscan --version
ClamAV 1.0.9
Mientras no se hayan descargado las firmas, la versión aparece sola. Cuando ya estén en disco, verás también el número de la base de firmas y su fecha.
Paso 2: Comprobar la descarga de firmas
Nada más instalarse, el servicio clamav-freshclam empieza a descargar la base de firmas y después comprueba si hay actualizaciones varias veces al día. Verifica que está activo:
sudo systemctl status clamav-freshclam --no-pager
● clamav-freshclam.service - ClamAV virus database updater
Loaded: loaded (/usr/lib/systemd/system/clamav-freshclam.service; enabled; preset: enabled)
Active: active (running) since Thu 2026-09-24 11:05:20 UTC; 2min ago
La primera descarga ocupa unos 300 MB y puede tardar unos minutos. Sigue su progreso en el log de freshclam:
sudo tail -f /var/log/clamav/freshclam.log
Cuando termine, pulsa Ctrl+C y comprueba que están los tres archivos de firmas principales:
ls -lh /var/lib/clamav/
-rw-r--r-- 1 clamav clamav 276K Sep 24 11:06 bytecode.cvd
-rw-r--r-- 1 clamav clamav 59M Sep 24 11:06 daily.cvd
-rw-r--r-- 1 clamav clamav 163M Sep 24 11:07 main.cvd
Si alguna vez necesitas forzar una actualización manual, detén antes el servicio, porque ambos no pueden escribir a la vez en la base de datos:
sudo systemctl stop clamav-freshclam
sudo freshclam
sudo systemctl start clamav-freshclam
Paso 3: Arrancar el demonio clamd
El servicio clamav-daemon no arranca hasta que existen las firmas, así que es probable que tras la instalación esté detenido. Ahora que ya están descargadas, arráncalo:
sudo systemctl enable --now clamav-daemon
Cargar las firmas en memoria tarda entre medio minuto y un minuto. Comprueba el estado:
sudo systemctl status clamav-daemon --no-pager
● clamav-daemon.service - Clam AntiVirus userspace daemon
Loaded: loaded (/usr/lib/systemd/system/clamav-daemon.service; enabled; preset: enabled)
Active: active (running) since Thu 2026-09-24 11:09:02 UTC; 45s ago
Main PID: 3120 (clamd)
Memory: 1.3G
El valor de Memory confirma que las firmas están cargadas. clamd escucha en el socket local /var/run/clamav/clamd.ctl, que solo es accesible desde el propio servidor.
Paso 4: Probar la detección con EICAR
Para comprobar que ClamAV detecta malware sin usar malware real, existe el archivo de prueba EICAR: una cadena de texto inofensiva que todos los antivirus reconocen como amenaza. Créalo en tu directorio personal:
printf '%s' 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*' > ~/eicar.txt
Escanéalo primero con clamscan, el escáner independiente:
clamscan ~/eicar.txt
/home/your_user/eicar.txt: Win.Test.EICAR_HDB-1 FOUND
----------- SCAN SUMMARY -----------
Known viruses: 8712345
Engine version: 1.0.9
Scanned directories: 0
Scanned files: 1
Infected files: 1
Data scanned: 0.00 MB
Data read: 0.00 MB (ratio 0.00:1)
Time: 21.402 sec (0 m 21 s)
Fíjate en el tiempo: más de 20 segundos para un archivo de 68 bytes, porque clamscan carga todas las firmas en cada ejecución. Ahora escanea el mismo archivo con clamdscan, que usa el demonio:
clamdscan --fdpass ~/eicar.txt
/home/your_user/eicar.txt: Win.Test.EICAR_HDB-1 FOUND
----------- SCAN SUMMARY -----------
Infected files: 1
Time: 0.012 sec (0 m 0 s)
La opción --fdpass hace que clamdscan abra el archivo con tus permisos y pase el descriptor a clamd. Sin ella, clamd, que se ejecuta como usuario clamav, no podría leer archivos de otros usuarios y devolvería Permission denied.
Cuando termines, borra el archivo de prueba:
rm ~/eicar.txt
Paso 5: Escanear directorios bajo demanda
Para analizar un directorio de forma recursiva con el demonio, pasa la ruta a clamdscan. La opción --infected muestra solo los archivos infectados, para que la salida no se llene con cada archivo limpio:
sudo clamdscan --fdpass --infected /var/www
clamdscan recorre los subdirectorios por defecto. Su código de salida indica el resultado, lo que facilita usarlo en scripts:
| Código | Significado |
|---|---|
0 | No se ha encontrado nada |
1 | Se ha encontrado al menos un archivo infectado |
2 | Se ha producido algún error (ruta inexistente, sin permisos...) |
Si prefieres no mantener el demonio en memoria, puedes usar clamscan con -r para escanear de forma recursiva. Es más lento, pero no necesita clamd:
sudo clamscan -r --infected /home
Ninguno de los dos comandos borra ni mueve nada por defecto. Así puedes revisar primero cada detección, ya que puede haber falsos positivos, y decidir tú qué hacer con el archivo.
Paso 6: Programar un escaneo diario
Un escaneo diario de los directorios donde los usuarios o las aplicaciones escriben archivos (subidas, /home, /var/www) detecta a tiempo webshells y archivos maliciosos. Usarás un servicio de systemd de tipo oneshot y un timer que lo lanza cada noche.
Crea el servicio:
sudo nano /etc/systemd/system/clamav-scan.service
[Unit]
Description=Escaneo ClamAV de directorios de datos
Requires=clamav-daemon.service
After=clamav-daemon.service
[Service]
Type=oneshot
Nice=19
IOSchedulingClass=idle
ExecStart=/usr/bin/clamdscan --fdpass --infected --log=/var/log/clamav/scan.log /home /var/www
Ajusta las rutas del final de ExecStart a los directorios que existan en tu servidor: si indicas uno que no existe, clamdscan terminará con error. Nice=19 e IOSchedulingClass=idle hacen que el escaneo ceda CPU y disco al resto de servicios.
Crea el timer, que lo ejecuta cada día a las 03:30 con un margen aleatorio de hasta 30 minutos:
sudo nano /etc/systemd/system/clamav-scan.timer
[Unit]
Description=Escaneo diario con ClamAV
[Timer]
OnCalendar=*-*-* 03:30:00
RandomizedDelaySec=30m
Persistent=true
[Install]
WantedBy=timers.target
Persistent=true hace que, si el servidor estaba apagado a esa hora, el escaneo se ejecute al volver a arrancar. Recarga systemd, lanza el escaneo una vez a mano para probarlo y activa el timer:
sudo systemctl daemon-reload
sudo systemctl start clamav-scan.service
sudo systemctl enable --now clamav-scan.timer
El primer comando start espera a que termine el escaneo, lo que puede tardar varios minutos si los directorios son grandes. Revisa el resultado en el log:
sudo tail -n 12 /var/log/clamav/scan.log
-------------------------------------------------------------------------------
----------- SCAN SUMMARY -----------
Infected files: 0
Time: 94.215 sec (1 m 34 s)
Start Date: 2026:09:24 11:32:10
End Date: 2026:09:24 11:33:44
Y confirma que el timer está programado:
systemctl list-timers clamav-scan.timer
NEXT LEFT LAST PASSED UNIT ACTIVATES
Fri 2026-09-25 03:41:17 UTC 15h left Thu 2026-09-24 11:33:44 UTC 2min ago clamav-scan.timer clamav-scan.service
Como clamdscan sale con código 1 cuando encuentra algo, el servicio quedará en estado failed si detecta una amenaza. Puedes verlo con systemctl --failed o, mejor, añadir un aviso automático con la directiva OnFailure= de systemd, tal como se explica en la guía de monitorización de servicios con systemd.
Solución de problemas
clamav-daemonno arranca después de instalar: aún no hay firmas en/var/lib/clamav/. Espera a queclamav-freshclamtermine la primera descarga (revisa/var/log/clamav/freshclam.log) y ejecutasudo systemctl start clamav-daemon.Can't connect to clamdal usarclamdscan: el demonio sigue cargando las firmas o se ha detenido. Compruebasudo systemctl status clamav-daemonysudo journalctl -u clamav-daemon -n 30.- El demonio muere por falta de memoria al recargar firmas: por defecto,
clamdcarga la base nueva antes de liberar la antigua. En servidores con poca RAM, añade la líneaConcurrentDatabaseReload noal final de/etc/clamav/clamd.confy reinicia consudo systemctl restart clamav-daemon. El escaneo quedará bloqueado unos segundos durante cada recarga, a cambio de no duplicar la memoria. freshclamdevuelve errores de descarga o de límite de peticiones: no lancesfreshclama mano repetidamente. El servicio ya comprueba actualizaciones de forma periódica y los servidores de firmas limitan a quien hace demasiadas peticiones.
Conclusión
ClamAV está instalado en tu servidor Ubuntu 24.04 con las firmas actualizándose solas, el demonio clamd listo para escaneos rápidos con clamdscan y un análisis diario programado con systemd que deja constancia en /var/log/clamav/scan.log.
Como siguientes pasos puedes:
- Añadir un aviso con
OnFailure=al servicio de escaneo para enterarte en cuanto se detecte una amenaza. - Integrar
clamdcon tu servidor de correo o con la aplicación que recibe subidas de archivos para escanearlos al vuelo. - Complementar el antivirus con medidas de hardening del servidor, porque detectar malware no sustituye a evitar que llegue.
