ClamAV su Linux: guida completa a installazione, scansione e monitoraggio in tempo reale
Guida completa a ClamAV su Linux: installazione, verifica dei servizi, scansione con clamdscan e clamscan, monitoraggio in tempo reale con inotifywait, automazione tramite systemd timer e best practice di sicurezza e ottimizzazione delle prestazioni.
Introduzione
ClamAV è una soluzione antivirus open source pensata per ambienti Unix e Linux, ampiamente utilizzata per la scansione di file system, mail server e workstation. A differenza di molti antivirus desktop, ClamAV non integra una protezione in tempo reale "out of the box": è progettato come un toolkit modulare, composto da più componenti indipendenti che collaborano tra loro.
Architettura e componenti principali
ClamAV si basa su tre componenti fondamentali, ciascuno con una responsabilità specifica. Questa separazione dei compiti è coerente con il principio di modularità: ogni processo può essere aggiornato, monitorato o riavviato in modo indipendente.
| Componente | Ruolo |
|---|---|
| clamav-freshclam | Servizio che aggiorna periodicamente il database delle firme virali. |
| clamav-daemon (clamd) | Demone di scansione sempre residente in RAM, garantisce tempi di risposta rapidi. |
| clamdscan | Client leggero che si connette a clamd per richiedere una scansione (veloce). |
| clamscan | Scanner standalone che ricarica il database a ogni esecuzione (più lento). |
La distinzione tra clamdscan e clamscan è cruciale dal punto di vista delle prestazioni: il primo si appoggia al demone già attivo e con il database già caricato in memoria, mentre il secondo carica da zero l'intero database a ogni invocazione, con un overhead che può arrivare a diversi secondi.
Installazione dei pacchetti
L'installazione su distribuzioni basate su Debian/Ubuntu richiede un singolo comando:
sudo apt update && sudo apt install clamav clamav-daemon clamav-freshclam -y
Questo comando installa tre pacchetti distinti, ciascuno con un ruolo preciso:
clamav: fornisce i comandi base, tra cuiclamscaneclamdscan.clamav-daemon: installa il demoneclamde i relativi file di configurazione.clamav-freshclam: installa l'aggiornatore del database e il servizio systemd associato.
Al termine dell'installazione, entrambi i servizi principali (clamav-freshclam e clamav-daemon) dovrebbero avviarsi automaticamente.
Se usi un sistema operativo differente puoi fare riferimento alla documentazione ufficiale: Installing ClamAV
Verifica dei servizi e del database
Stato dei servizi
Per verificare che i servizi siano attivi e in esecuzione, è sufficiente interrogare systemd:
systemctl status clamav-freshclam
systemctl status clamav-daemon
Verifica della versione e del database
Il comando seguente restituisce la versione del software e quella del database delle firme installato:
clamscan --version
Un output tipico ha questa forma:
ClamAV 1.4.4/28026/Tue Jun 9 08:25:31 2026
Il formato è: versione di ClamAV / versione del database / data dell'ultimo aggiornamento del database. Questo comando è particolarmente utile in fase di troubleshooting, poiché una data molto vecchia indica immediatamente un problema con freshclam.
Troubleshooting: notifica di freshclam a clamd
Dopo ogni aggiornamento del database, freshclam invia un segnale a clamd affinché ricarichi le firme senza necessità di riavvio. Se nei log compare il seguente errore:
ERROR: NotifyClamd: Can't find or parse configuration file /etc/clamav/clamd.conf
è necessario innanzitutto verificare che il file /etc/clamav/clamd.conf esista effettivamente. Se il file è presente, il problema è quasi sempre legato a una race condition verificatasi durante l'installazione: riavviando freshclam si forza una nuova notifica.
sudo systemctl restart clamav-freshclam
Per confermare che clamd abbia effettivamente ricevuto la notifica, è possibile consultare i log del demone:
journalctl -u clamav-daemon.service --no-pager -n 10
Nei log dovrebbe apparire un messaggio simile a Received SIGHUP oppure Reloading databases, segno che il database è stato ricaricato correttamente in memoria.
Comandi di scansione
Scansione con clamdscan (raccomandato)
clamdscan è il metodo consigliato per la scansione su sistemi con clamd già attivo: il comando si limita a inviare la richiesta al demone, che esegue la scansione utilizzando il database già caricato in RAM, con un guadagno di prestazioni significativo rispetto allo scanner standalone.
Alcuni esempi di utilizzo comune:
clamdscan file.txt
clamdscan /home/dino/Scaricati --infected --fdpass
clamdscan /home /var --infected --fdpass --multiscan
clamdscan /home /etc /var /tmp --infected --fdpass --log=scansione.txt
clamdscan /percorso --infected --fdpass --quiet
clamdscan /percorso --infected --fdpass --wait
Le opzioni più utilizzate di clamdscan sono riassunte nella tabella seguente:
| Opzione | Effetto |
|---|---|
| --infected / -i | Mostra in output solo i file risultati infetti. |
| --fdpass | Passa il file descriptor a clamd, necessario quando il demone è eseguito con un utente di sistema diverso da quello che avvia la scansione. |
| --multiscan / -m | Distribuisce la scansione su più thread paralleli. |
| --verbose / -v | Restituisce un output dettagliato di ogni file analizzato. |
| --quiet | Mostra solo eventuali errori, utile per l'esecuzione in background. |
| --log=FILE / -l FILE | Salva il report della scansione su file. |
| --wait / -w | Attende che clamd sia disponibile prima di procedere, utile in script di avvio. |
| --remove | Rimuove automaticamente i file infetti (operazione irreversibile). |
| --move=DIR | Sposta i file infetti nella directory di quarantena specificata. |
Scansione completa del sistema
Per una scansione completa del file system è necessario escludere i file system virtuali, che non contengono dati reali e possono causare blocchi o errori durante la scansione:
clamdscan / --infected --fdpass --exclude-dir="^/(proc|sys|dev|run)"
Le directory /proc, /sys, /dev e /run devono sempre essere escluse: rappresentano interfacce verso il kernel e non file da analizzare.
Scansione con clamscan (standalone)
clamscan non dipende da clamd ed è quindi utile in script eseguiti su sistemi dove il demone non è attivo, oppure in contesti containerizzati minimali. Lo svantaggio principale è il tempo di avvio, dovuto al caricamento completo del database a ogni esecuzione.
clamscan -r /home /etc /var /tmp --infected --log=scansione.txt
| Opzione | Effetto |
|---|---|
| -r | Esegue la scansione in modo ricorsivo sulle sottodirectory. |
| --infected | Mostra solo i file risultati infetti. |
| --log=FILE | Salva il report della scansione su file. |
| --move=DIR | Sposta i file infetti nella directory di quarantena specificata. |
| --remove | Rimuove automaticamente i file infetti (operazione irreversibile). |
| --exclude-dir=PATTERN | Esclude le directory che corrispondono al pattern specificato. |
Codici di uscita per l'automazione
Sia clamscan che clamdscan restituiscono un codice di uscita standardizzato, particolarmente utile quando questi comandi vengono integrati in script di automazione o pipeline:
| Codice | Significato |
|---|---|
| 0 | Scansione completata, nessun virus rilevato. |
| 1 | Scansione completata, rilevato almeno un file infetto. |
| 2 | Errore durante l'esecuzione (file non leggibile, problemi di connessione a clamd, ecc.). |
In uno script bash è quindi possibile reagire in modo differenziato ai diversi esiti, ad esempio inviando una notifica solo in caso di rilevamento (codice 1) e loggando separatamente gli errori di sistema (codice 2).
Monitoraggio in tempo reale
ClamAV offre la modalità "On-Access Scan" tramite il binario clamav-clamonacc, che si appoggia all'interfaccia fanotify del kernel Linux per intercettare in tempo reale le operazioni sui file. Si tratta della soluzione più completa, ma comporta un impatto costante sulle prestazioni del sistema, poiché ogni accesso ai file monitorati viene intercettato dal kernel e instradato verso ClamAV.
Per workstation desktop o ambienti con risorse limitate, una soluzione più leggera ed efficiente in termini di consumo di CPU consiste nell'implementare un watchdog basato su inotifywait, che monitora solo gli eventi di scrittura e spostamento file nelle directory di interesse, delegando la scansione effettiva a clamdscan.
Installazione degli strumenti necessari
sudo apt install -y inotify-tools
Creazione dello script di watchdog
mkdir -p ~/.local/bin
nano ~/.local/bin/clamav-watch.sh
Contenuto dello script:
#!/bin/bash
WATCH_DIRS="$HOME/Scaricati $HOME/Scrivania $HOME/Documenti $HOME/Immagini $HOME/Video $HOME/Musica $HOME/Pubblici"
inotifywait -m $WATCH_DIRS -e close_write -e moved_to --format '%w%f' |
while read -r FILE; do
clamdscan --infected --fdpass --quiet "$FILE" 2>&1 | grep -v "OK$" | logger -t clamav-watch
done
Lo script monitora le directory utente più comunemente utilizzate per download e file temporanei, esegue una scansione silenziosa tramite clamdscan a ogni evento e invia al syslog solo gli esiti diversi da "OK", riducendo al minimo il rumore nei log.
Rendere lo script eseguibile:
chmod +x ~/.local/bin/clamav-watch.sh
Creazione del servizio systemd utente
mkdir -p ~/.config/systemd/user
nano ~/.config/systemd/user/clamav-watch.service
Contenuto del file di unità:
[Unit]
Description=ClamAV lightweight file watchdog
After=clamav-daemon.service
[Service]
ExecStart=%h/.local/bin/clamav-watch.sh
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.target
Un errore comune in questa fase è l'utilizzo del nome di sezione errato [Services] al posto di [Service] (forma singolare): systemd non riconosce la sezione e l'avvio del servizio fallisce.
Abilitazione e avvio del servizio
systemctl --user daemon-reload
systemctl --user enable --now clamav-watch.service
systemctl --user status clamav-watch.service
L'output atteso in caso di corretto funzionamento è simile al seguente:
clamav-watch.service - ClamAV lightweight file watchdog
Active: active (running)
Memory: 1.1M (peak: 1.6M)
Il consumo di memoria estremamente contenuto (circa 1 MB) confirma il vantaggio di questo approccio rispetto a una soluzione on-access basata su fanotify, costantemente attiva e con un'impronta sulle risorse decisamente maggiore.
Verifica del funzionamento
echo "test" > ~/Scaricati/prova.txt
clamdscan ~/Scaricati/prova.txt --infected --fdpass
rm ~/Scaricati/prova.txt
Gli eventuali file rilevati come infetti vengono registrati automaticamente nel journal. Per consultarli:
journalctl -t clamav-watch --no-pager
Logica di funzionamento dello script
Il flusso operativo del watchdog può essere schematizzato come segue:
File creato o modificato in una directory monitorata
|
v
inotifywait rileva l'evento (close_write / moved_to)
|
v
clamdscan --infected --fdpass --quiet esegue la scansione
|
v
Se infetto -> logger -t clamav-watch -> syslog/journal
Se pulito -> nessuna azione (filtrato da grep -v "OK$")
Automazione delle scansioni pianificate
Oltre al monitoraggio in tempo reale, è buona prassi pianificare scansioni periodiche complete del sistema, ad esempio in orari di basso utilizzo. Su sistemi Linux moderni, i timer systemd rappresentano un'alternativa più robusta al classico cron, offrendo log centralizzati tramite journald e una gestione più granulare delle dipendenze.
L'automazione richiede la creazione di due file distinti in /etc/systemd/system/:
/etc/systemd/system/clamav-fullscan.service: definisce l'azione da eseguire (la scansione vera e propria)./etc/systemd/system/clamav-fullscan.timer: definisce quando quell'azione deve essere eseguita.
Contenuto di /etc/systemd/system/clamav-fullscan.service:
[Unit]
Description=ClamAV scheduled full scan
[Service]
Type=oneshot
ExecStart=/usr/bin/clamdscan / --infected --fdpass --multiscan --exclude-dir="^/(proc|sys|dev|run)" --log=/var/log/clamav/full-scan.log
Contenuto di /etc/systemd/system/clamav-fullscan.timer, che esegue la scansione ogni notte alle 03:00:
[Unit]
Description=Run ClamAV full scan nightly
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
Per creare i due file è sufficiente un editor di testo come nano:
sudo nano /etc/systemd/system/clamav-fullscan.service
Si incolla il contenuto del servizio, si salva con Ctrl+O, si conferma il nome con Invio e si esce con Ctrl+X. Si ripete poi lo stesso procedimento per il timer:
sudo nano /etc/systemd/system/clamav-fullscan.timer
Dopo aver salvato entrambi i file, è necessario ricaricare la configurazione di systemd e abilitare il timer:
sudo systemctl daemon-reload
sudo systemctl enable --now clamav-fullscan.timer
Per verificare che il timer sia attivo:
systemctl status clamav-fullscan.timer
oppure, per una panoramica di tutti i timer attivi sul sistema:
systemctl list-timers
Risoluzione dei problemi di connessione al socket clamd
Dopo una reinstallazione di ClamAV su un nuovo PC è possibile imbattersi in errori di connessione al socket Unix di clamd, non sempre presenti in un'installazione precedente. Questi errori dipendono principalmente dallo stato del demone, dai permessi del file socket o dal contesto di sicurezza del sistema (SELinux/AppArmor).
Errore: LocalSocket non trovato
ERROR: Could not connect to clamd on LocalSocket /var/run/clamav/clamd.ctl: No such file or directory
Questo errore indica che il demone clamd non è in esecuzione, non ha creato il file socket previsto, oppure il percorso configurato non corrisponde a quello effettivo.
1. Verificare e avviare il servizio
Spesso il demone semplicemente non è attivo:
sudo systemctl status clamav-daemon
sudo systemctl start clamav-daemon
Se il servizio si avvia ma si arresta immediatamente, è utile controllare i log per individuare la causa specifica (ad esempio mancanza di memoria o errori di configurazione):
journalctl -u clamav-daemon
2. Creare manualmente il socket e correggere i permessi
Se la directory o il file socket mancano, è possibile crearli manualmente assegnando la proprietà corretta all'utente clamav:
sudo mkdir -p /var/run/clamav
sudo touch /var/run/clamav/clamd.ctl
sudo chown clamav:clamav /var/run/clamav/clamd.ctl
sudo chmod 660 /var/run/clamav/clamd.ctl
È inoltre necessario assicurarsi che nel file /etc/clamav/clamd.conf la riga LocalSocket sia decommentata e corrisponda esattamente al percorso creato:
LocalSocket /var/run/clamav/clamd.ctl
3. Riconfigurare o reinstallare (soluzione definitiva)
Se il problema persiste, spesso è utile forzare la riconfigurazione del pacchetto, che ricrea i file mancanti con le impostazioni predefinite corrette:
sudo dpkg-reconfigure clamav-daemon
Nei casi più ostinati, una reinstallazione pulita risolve conflitti di permessi o file corrotti:
sudo apt-get purge clamav clamav-daemon
sudo rm -rf /var/run/clamav /etc/clamav
sudo apt-get update
sudo apt-get install clamav clamav-daemon
Dopo l'installazione, è necessario riavviare il servizio ed eseguire l'aggiornamento delle firme virali:
sudo systemctl restart clamav-daemon
sudo freshclam
Errore: Permission denied sul socket
ERROR: Could not connect to clamd on LocalSocket /var/run/clamav/clamd.ctl: Permission denied
Questo errore indica che il processo che tenta di connettersi al socket (ad esempio clamdscan, un server web come Apache o Nginx, oppure un demone di posta) non dispone dei diritti di lettura/scrittura sul file /var/run/clamav/clamd.ctl. Si tratta quasi sempre di un problema legato ai gruppi utente o al contesto di esecuzione (SELinux, AppArmor o container).
1. Aggiungere l'utente al gruppo clamav (soluzione più comune)
Il socket è di proprietà dell'utente e del gruppo clamav. L'utente che esegue il comando o il servizio deve appartenere a questo gruppo:
sudo usermod -aG clamav $USER
Per un servizio web, ad esempio:
sudo usermod -aG clamav www-data
È importante disconnettersi e riconnettersi (oppure riavviare il servizio specifico) affinché le modifiche al gruppo abbiano effetto. È possibile verificare i gruppi attivi con il comando groups.
2. Correggere i permessi del socket
È necessario assicurarsi che il socket abbia i permessi corretti (660, o eventualmente 666 se strettamente necessario, anche se 660 con il gruppo corretto resta la soluzione più sicura). Nel file /etc/clamav/clamd.conf deve essere presente la riga:
LocalSocketMode 660
Dopo la modifica è necessario riavviare il demone:
sudo systemctl restart clamav-daemon
Per verificare i permessi attuali:
ls -l /var/run/clamav/clamd.ctl
L'output atteso è simile a:
srw-rw---- 1 clamav clamav ...
3. Controllare SELinux o AppArmor
Se i permessi risultano corretti ma l'errore persiste, su distribuzioni come CentOS, RHEL o Fedora con SELinux, oppure su Ubuntu con AppArmor, il sistema di sicurezza potrebbe bloccare l'accesso anche in presenza di permessi file corretti.
Per SELinux, è possibile controllare i log e testare temporaneamente la modalità permissiva:
sudo setenforce 0
Attenzione: questa modifica va usata solo a scopo diagnostico temporaneo, non come soluzione permanente.
Per AppArmor, è utile controllare /var/log/syslog alla ricerca di messaggi di rifiuto relativi a clamd, aggiornando il profilo se necessario.
4. Contesto Docker/container
Se l'errore si verifica all'interno di un container Docker, è necessario assicurarsi che il volume del socket sia montato correttamente e che gli UID/GID corrispondano tra host e container, oppure avviare il container con privilegi adeguati (soluzione comunque sconsigliata dal punto di vista della sicurezza).
Best practice di sicurezza e ottimizzazione
L'implementazione di un sistema antivirus efficace non si limita all'installazione dei pacchetti: alcuni accorgimenti aggiuntivi migliorano sensibilmente la sicurezza e l'efficienza complessiva.
- Permessi della directory di quarantena: se si utilizza l'opzione
--move=DIR, la directory di destinazione deve essere accessibile in scrittura dall'utente con cui viene eseguitoclamd, ma non deve essere accessibile in esecuzione, per evitare che file potenzialmente dannosi vengano eseguiti accidentalmente. - Tuning delle prestazioni di clamd: nel file
/etc/clamav/clamd.confè possibile regolare parametri comeMaxThreads(numero massimo di scansioni concorrenti) eMaxScanSize(dimensione massima dei file analizzati). Su server con carico elevato, aumentareMaxThreadspuò migliorare il throughput complessivo, a fronte di un maggiore consumo di CPU e RAM. - Esclusioni mirate: oltre ai file system virtuali, è consigliabile escludere directory che contengono grandi volumi di file non eseguibili e a basso rischio (ad esempio repository di backup già verificati), per ridurre i tempi di scansione senza compromettere la sicurezza complessiva.
- Rotazione dei log: se il watchdog genera un volume significativo di log tramite
logger, è opportuno verificare la configurazione dilogrotateper la voce relativa aclamav-watch, evitando una crescita incontrollata dei file in/var/log. - Gestione dei falsi positivi: prima di applicare
--removein modo automatico, è preferibile testare le regole con--moveverso una quarantena, verificando manualmente i risultati per un periodo iniziale ed evitando la rimozione accidentale di file legittimi.
Cheat sheet dei comandi principali
Per un riferimento rapido durante l'operatività quotidiana:
systemctl status clamav-freshclam
systemctl status clamav-daemon
systemctl --user status clamav-watch
clamdscan ~/Scaricati --infected --fdpass
clamdscan / --infected --fdpass --exclude-dir="^/(proc|sys|dev|run)"
journalctl -t clamav-watch --no-pager
journalctl -u clamav-daemon.service --no-pager -n 20
clamscan --version
ls -l /var/run/clamav/clamd.ctl
groups
Risoluzione dei problemi comuni
| Errore | Causa | Soluzione |
|---|---|---|
| Can't find or parse configuration file /etc/clamav/clamd.conf | Race condition verificatasi durante l'installazione | Riavviare freshclam con sudo systemctl restart clamav-freshclam |
| Status 203/EXEC | Script non eseguibile o shebang errata | Eseguire chmod +x script.sh e verificare la presenza di #!/bin/bash |
| Unknown section 'Services' | Nome di sezione errato nel file di unità systemd | Correggere in [Service], al singolare |
| Could not connect to clamd on LocalSocket: No such file or directory | Il demone clamd non è in esecuzione o non ha creato il socket previsto | Avviare clamav-daemon, ricreare manualmente il socket con i permessi corretti oppure eseguire dpkg-reconfigure clamav-daemon |
| Could not connect to clamd on LocalSocket: Permission denied | L'utente o il processo chiamante non appartiene al gruppo clamav, oppure SELinux/AppArmor blocca l'accesso | Aggiungere l'utente al gruppo clamav con usermod -aG clamav, impostare LocalSocketMode 660 e verificare eventuali blocchi di SELinux/AppArmor |
File e percorsi principali
| File | Ruolo |
|---|---|
| /etc/clamav/clamd.conf | File di configurazione principale del demone clamd. |
| /etc/clamav/freshclam.conf | File di configurazione dell'aggiornatore freshclam. |
| /var/run/clamav/clamd.ctl | File socket Unix utilizzato dai client (clamdscan e altri) per comunicare con clamd. |
| ~/.local/bin/clamav-watch.sh | Script eseguibile del watchdog basato su inotify. |
| ~/.config/systemd/user/clamav-watch.service | Definizione del servizio systemd utente per il watchdog. |
| /etc/systemd/system/clamav-fullscan.service | Definizione del servizio systemd per la scansione completa pianificata. |
| /etc/systemd/system/clamav-fullscan.timer | Timer systemd che pianifica l'esecuzione notturna della scansione completa. |
| /var/lib/clamav/ | Directory contenente il database delle firme virali. |
| /var/log/clamav/ | Directory dei file di log generati da ClamAV. |