Quando un file sensibile cambia, la domanda utile non è soltanto “chi lo ha modificato?”. Prima ancora dobbiamo capire se quella modifica fosse prevista, se riguardasse contenuto o permessi, se altri elementi siano cambiati nello stesso intervallo di tempo e soprattutto se gli strumenti che avrebbero dovuto avvisarci fossero ancora vivi.
È da questo problema che nasce l’IR Stack. Non è un singolo programma e non vuole sostituire un SIEM. È piuttosto un insieme relativamente piccolo di componenti Linux già maturi, collegati in modo da coprire alcuni punti ciechi tipici di un server: modifiche agli account, variazioni di privilegi, chiavi SSH, accessi riusciti, alterazioni dello stesso stack di difesa e spegnimento dei servizi che dovrebbero sorvegliarlo.
Prevenzione e rilevamento sono due mestieri diversi
Un firewall può impedire una connessione. I permessi Unix possono impedire a un processo di leggere un file. SSH può rifiutare una password. Ma nessuno di questi strumenti, da solo, ci racconta bene che /etc/sudoers è stato modificato alle 03:14, che contemporaneamente è comparsa una nuova chiave in authorized_keys e che pochi secondi dopo il watcher è stato fermato.
Un sistema di incident response parte quindi da un principio diverso: assumiamo che qualcosa possa comunque cambiare e costruiamo abbastanza telemetria da accorgercene e ricostruirlo. Da qui l’uso contemporaneo di auditd, systemd path/timer, controlli logici sull’identità e watchdog sui guardian.
Perché non basta fare SHA256 di tutto
Il classico File Integrity Monitoring confronta una baseline con lo stato corrente. È utile, ma un hash da solo ci dice soltanto che due contenuti sono diversi. Non ci dice se la modifica sia avvenuta durante un aggiornamento autorizzato, chi abbia eseguito il comando, se il file abbia cambiato solo mode/owner oppure se l’evento faccia parte di una sequenza più ampia.
Nell’IR Stack usiamo quindi livelli differenti. auditd registra operazioni su file e comandi sensibili; systemd.path trasforma alcune modifiche in trigger immediati; un timer ripete comunque i controlli periodicamente; il checker ragiona sulla struttura degli account; il watcher protegge gli stessi script di difesa; il guardian verifica che path, timer e servizi non siano stati spenti.
Architettura dello stack
/etc/passwd, shadow, group, sudoers, sshd_config, authorized_keys
|
+------+------+
| |
auditd systemd.path
| |
+------+------+
|
identity checker
|
incident handler
|
+--------+---------+
| |
mail/log lockdown opzionale
|
rollback firewall
In parallelo:
journal SSH -> alert login riusciti
file stack -> watcher anti-tamper
unità IR -> guardian watchdog
1. auditd: la memoria forense
Auditd lavora a livello kernel e può registrare accessi o modifiche a file sensibili e l’esecuzione di determinati programmi. Le chiavi identity, privilege, sshcfg, sshkeys, user_mgmt e ir_stack permettono poi di isolare rapidamente gli eventi con ausearch.
auditctl -l
ausearch -k identity -ts recent -i
ausearch -k privilege -ts recent -i
ausearch -k ir_stack -ts recent -i
Il vantaggio rispetto a un semplice watcher è il contesto: non vediamo soltanto che il file è cambiato, ma possiamo spesso risalire al processo, all’utente e alla syscall coinvolta.
2. Il checker di identità
Alcune anomalie non sono “file cambiato = incidente”. Un secondo account con UID 0, invece, è quasi sempre qualcosa che merita attenzione. Lo stesso vale per un account di sistema che improvvisamente ottiene una shell interattiva reale. Il checker non si limita quindi agli hash: interpreta /etc/passwd, login.defs, le shell e una piccola whitelist locale per gli account di servizio legittimi.
È importante la whitelist. In un PBX, per esempio, l’utente asterisk può avere caratteristiche differenti da quelle attese da una regola generica. Un buon controllo non deve fingere che tutti i server siano uguali: deve consentire eccezioni documentate e specifiche.
3. Path e timer: immediatezza più ridondanza
systemd.path ci dà reazione quasi immediata: quando cambia uno dei file sorvegliati parte l’handler. Ma basarsi solo sugli eventi è fragile. Per questo esiste anche un timer periodico che ripete il controllo. Se un evento viene perso, se il watcher viene riavviato o se una condizione anomala non dipende da una singola scrittura, il controllo periodico ci offre una seconda possibilità.
4. Alert sugli accessi SSH riusciti
Molti sistemi avvisano sui tentativi falliti e ignorano il dato più interessante: un login riuscito. Lo script SSH conserva il cursor di journald e analizza soltanto le nuove righe Accepted publickey, Accepted password o equivalenti. L’alert contiene utente, IP, metodo e riga originale del log.
Il cursor è importante: senza stato, un parser lanciato periodicamente rischia di inviare più volte la stessa segnalazione. Al primo avvio lo script inizializza il cursor senza notificare eventi storici; da quel momento procede in avanti.
5. Chi sorveglia i sorveglianti?
Se un attaccante ottiene privilegi sufficienti, una delle prime mosse sensate è spegnere gli strumenti che potrebbero denunciarlo. Per questo lo stack controlla anche se stesso. Le modifiche a script, configurazioni e unità systemd generano eventi audit con chiave ir_stack e attivano un watcher dedicato.
Il guardian aggiunge un altro livello: verifica continuamente che path, timer e servizi fondamentali siano attivi. Nella versione produttiva alcuni guardian possono essere autoriparati, mentre servizi esterni importanti possono essere lasciati in modalità alert-only: riavviare automaticamente tutto ciò che cade sarebbe comodo, ma potrebbe anche nascondere la causa reale di un guasto.
6. Maintenance window
Il caso più fastidioso per un sistema del genere è l’aggiornamento legittimo. Un deploy o un upgrade può modificare proprio i file che stiamo proteggendo. La soluzione non è spegnere auditd: durante una maintenance window continuiamo a registrare gli eventi, ma sopprimiamo escalation, mail ripetitive e lockdown. In produzione usiamo un marker temporaneo con una scadenza; se il marker viene dimenticato, scade da solo.
7. Lockdown: separato e disabilitato di default
L’isolamento automatico è potente e pericoloso. Una falsa rilevazione non deve trasformarsi in un server che si taglia fuori dalla rete. L’installer pubblico crea gli strumenti di lockdown e rollback, ma ENABLE_LOCKDOWN parte su no. Prima di abilitarlo bisogna testare indirizzo amministrativo fidato, porta SSH, backup delle regole firewall e procedura di rollback da console.
IR Stack è ora un progetto pubblico su GitHub
La prima versione di questa guida conteneva direttamente l’intero installer Bash. Era utile per mostrare come nasceva lo stack, ma con l’evoluzione del progetto quel modello è diventato poco pratico: uno script di migliaia di righe incorporato in un articolo è difficile da revisionare, aggiornare, confrontare e soprattutto da mantenere sincronizzato con il codice realmente utilizzato.
IR Stack è quindi diventato un progetto autonomo e modulare, pubblicato su GitHub sotto licenza GPL-3.0-or-later:
Repository:
https://github.com/DaSCoS-Dev/Ir-stack
La versione descritta in questa guida è la 0.2.0-rc1, pubblicata dopo una security/code review completa:
Release 0.2.0-rc1:
https://github.com/DaSCoS-Dev/Ir-stack/releases/tag/v0.2.0-rc1
Rispetto alla prima implementazione monolitica, il progetto separa installer, componenti runtime, regole audit, unità systemd e backend firewall. Supporta inoltre configurazione interattiva o unattended, trusted source multiple IPv4/IPv6 e CIDR, maintenance window, baseline delle chiavi SSH, backend nftables/iptables/firewalld, integrazione Fail2Ban e ban remoto tramite OpenWrt.
Il lockdown rimane disabilitato di default: detection e containment sono volutamente separate, perché un falso positivo non deve trasformarsi automaticamente nella perdita dell’accesso amministrativo al server.
Installazione dalla release
Per una nuova installazione è possibile scaricare direttamente l’installer standalone della release:
curl -fLO https://github.com/DaSCoS-Dev/Ir-stack/releases/download/v0.2.0-rc1/install-ir-stack.sh
curl -fLO https://github.com/DaSCoS-Dev/Ir-stack/releases/download/v0.2.0-rc1/SHA256SUMS
sha256sum -c SHA256SUMS
chmod 700 install-ir-stack.sh
sudo ./install-ir-stack.sh
L’installer interattivo richiede e valida i parametri necessari, tra cui modalità di invio degli alert, trusted source, porta SSH, backend firewall e integrazioni opzionali.
Per installazioni automatizzate è disponibile anche la modalità unattended:
sudo ./install-ir-stack.sh \
--non-interactive \
--alert-email soc@example.net \
--mail-mode existing \
--trusted-sources "192.168.10.0/24,10.0.20.15" \
--firewall-backend auto \
--ssh-port 22 \
--enable-lockdown no
In alternativa, la configurazione può essere fornita tramite file:
sudo ./install-ir-stack.sh --config ./install.conf
Il file di configurazione viene trattato come dato, non viene eseguito tramite source o eval.
Architettura della versione attuale
La logica generale descritta nell’articolo rimane valida, ma la versione pubblica aggiunge alcuni livelli:
file/account sensibili
|
auditd + systemd
|
identity / SSH / self-watch
|
handler
|
+----+----------------+
| |
log / alert ir-ban / lockdown
|
+---------+---------+
| |
firewall locale OpenWrt remoto
nftables/iptables/
firewalld
Il guardian controlla inoltre lo stato dei componenti IR Stack. I servizi appartenenti allo stack possono essere autoriparati, mentre dipendenze esterne come auditd, Postfix o Fail2Ban vengono monitorate senza riavviarle automaticamente.
Le regole audit vengono generate in base ai file e ai binari realmente presenti sul sistema e gli authorized_keys hanno una baseline esplicita che non viene sovrascritta automaticamente durante un aggiornamento.
Comandi principali
Dopo l’installazione la gestione ordinaria passa attraverso irctl:
irctl status
irctl check
irctl audit
irctl logs
irctl doctor
irctl mail-test
irctl refresh-audit
irctl ssh-baseline-show
irctl ssh-baseline-accept
Per una manutenzione programmata:
irctl maintenance on 60
irctl maintenance status
irctl maintenance off
Durante la maintenance gli eventi continuano a essere registrati, ma vengono soppresse escalation, email ripetitive e lockdown.
Prima di abilitare il lockdown
Il containment automatico deve essere trattato come una funzione separata e va collaudato esplicitamente.
Prima di impostare ENABLE_LOCKDOWN=yes è necessario verificare almeno:
- trusted IP e reti CIDR amministrative;
- porta SSH realmente utilizzata;
- backend firewall presente sul server;
- accesso console, IPMI, KVM o altro canale out-of-band;
- procedura di rollback.
IR Stack non esegue più un flush globale del firewall: utilizza oggetti e chain dedicate e il rollback rimuove solo ciò che lo stack ha creato.
OpenWrt e Fail2Ban
IR Stack può essere utilizzato anche come backend di ban per Fail2Ban e può inoltrare i ban a un firewall OpenWrt remoto tramite una chiave SSH dedicata e un forced-command limitato alle sole operazioni previste.
Queste integrazioni sono opzionali: il sistema di detection funziona anche senza di esse.
La documentazione aggiornata, gli esempi di configurazione, le note sui firewall backend e i rischi residui sono mantenuti direttamente nel repository GitHub. In questo modo l’articolo può concentrarsi sul modello e sull’architettura, mentre il codice rimane versionato, revisionabile e verificabile.
Verifica dopo l’installazione
irctl status
irctl check
irctl audit
irctl logs
systemctl status ir-stack-identity.path
systemctl status ir-stack-identity.timer
systemctl status ir-stack-ssh-login.timer
systemctl status ir-stack-self-watch.path
systemctl status ir-stack-guardians.timer
auditctl -l
Test senza provocare un incidente vero
Lo stack contiene test espliciti proprio per evitare di “provare” la protezione creando un utente root fasullo o modificando chiavi reali. Possiamo forzare il controllo manuale, il path watcher, il parser SSH, il watcher dello stack e il guardian separatamente.
irctl test-manual
irctl test-path
irctl test-ssh
irctl test-ir
irctl test-watch
Come leggere un alert
Una segnalazione non è una sentenza. La sequenza corretta è: identificare il file o l’account interessato; cercare l’evento audit; verificare processi e utente; controllare se esisteva una manutenzione autorizzata; correlare SSH, sudo, package manager e deploy; solo a quel punto decidere se aggiornare la baseline, ripristinare un file oppure aprire un incidente.
Questo è il punto centrale dell’IR Stack: non cerca di rendere il server magicamente invulnerabile. Cerca di fare in modo che, quando qualcosa cambia, non dobbiamo ricostruire la storia partendo dal buio.
Approfondimenti collegati
- Logging su Linux: journald, rsyslog e log remoto, per conservare gli eventi fuori dalla macchina sorvegliata.
- Apache e log, per correlare eventi filesystem e richieste HTTP.
- Reactive Web Firewall, per reagire in rete a segnali applicativi ad alta confidenza.

