RootGuard è un livello di enforcement e telemetria, non una nuova radice di fiducia. Un attaccante che controlla completamente il kernel può tentare di rimuovere i link BPF, falsificare le letture VFS o modificare direttamente le mappe. La VM di collaudo dovrebbe quindi separare tre livelli.
1. Prevenzione della modifica del kernel
- avvio verificato con Secure Boot quando disponibile;
- kernel lockdown in modalità integrity o confidentiality;
- verifica obbligatoria delle firme dei moduli;
- disabilitazione definitiva del caricamento moduli soltanto su immagini in cui tutti i driver necessari sono già caricati;
- BPF non privilegiato disabilitato.
Verifiche non invasive:
cat /sys/kernel/security/lockdown 2>/dev/null || true
cat /proc/sys/kernel/unprivileged_bpf_disabled 2>/dev/null || true
cat /proc/sys/kernel/module_sig_enforce 2>/dev/null || true
cat /sys/module/module/parameters/sig_enforce 2>/dev/null || true
2. Integrità di file e metadati
RootGuard protegge gli inode mentre il sistema è in esecuzione. Per aggiungere una radice crittografica:
- IMA appraisal verifica contenuto o firma dei file secondo policy;
- EVM protegge i metadati di sicurezza, inclusi gli xattr coperti dalla policy;
- fs-verity è adatto a file immutabili verificati individualmente;
- dm-verity è adatto a immagini o filesystem di sola lettura.
L'attivazione di IMA/EVM non va improvvisata su una macchina reale: policy, chiavi, initramfs e xattr devono essere preparati prima, altrimenti il sistema può non avviarsi. Il primo collaudo va svolto in una VM con snapshot.
3. RootGuard
RootGuard aggiunge:
- controllo delle transizioni verso EUID 0;
- sentinel di provenienza consultata da capable, inode_permission, file_open e dagli hook di modifica dei metadati;
- blocco delle modifiche a mode, owner, ACL e xattr di sicurezza sugli inode protetti;
- policy separata per bloccare globalmente aggiunte setuid/setgid, cambi di owner verso root e security.capability;
- blocco di unlink, rename e hardlink sugli inode protetti, con espansione ricorsiva opzionale delle directory senza seguire symlink;
- confronto periodico della baseline dal daemon, utile per rilevare drift ancora visibile anche quando il percorso LSM è stato aggirato;
- caricamento della policy da un unico file descriptor O_NOFOLLOW, con controllo ownership/mode e verifica che il file non cambi durante la lettura.
La combinazione è intenzionalmente ridondante: un singolo bypass non deve eliminare ogni segnale.