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 clamd mantiene 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:

ComponentePaqueteFunción
freshclamclamav-freshclamDescarga y actualiza la base de firmas. Funciona como servicio.
clamscanclamavEscáner independiente. Carga las firmas en cada ejecución, así que es lento para uso frecuente.
clamdclamav-daemonDemonio que mantiene las firmas en memoria y escanea bajo petición.
clamdscanclamav-daemonCliente 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ódigoSignificado
0No se ha encontrado nada
1Se ha encontrado al menos un archivo infectado
2Se 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-daemon no arranca después de instalar: aún no hay firmas en /var/lib/clamav/. Espera a que clamav-freshclam termine la primera descarga (revisa /var/log/clamav/freshclam.log) y ejecuta sudo systemctl start clamav-daemon.
  • Can't connect to clamd al usar clamdscan: el demonio sigue cargando las firmas o se ha detenido. Comprueba sudo systemctl status clamav-daemon y sudo journalctl -u clamav-daemon -n 30.
  • El demonio muere por falta de memoria al recargar firmas: por defecto, clamd carga la base nueva antes de liberar la antigua. En servidores con poca RAM, añade la línea ConcurrentDatabaseReload no al final de /etc/clamav/clamd.conf y reinicia con sudo systemctl restart clamav-daemon. El escaneo quedará bloqueado unos segundos durante cada recarga, a cambio de no duplicar la memoria.
  • freshclam devuelve errores de descarga o de límite de peticiones: no lances freshclam a 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 clamd con 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.