SSD Nodes Learn 🎉 VPS da $5.50/mese
Guide Matt ConnorDi Matt Connor

Come verificare i comandi eseguiti sul server

La cronologia della shell non è un audit trail: confronta sudo, registrazione delle sessioni, hook bash e regole auditd execve, poi invia i log fuori dal server.

Cosa registra realmente i comandi eseguiti dagli utenti sul server

Per verificare quali comandi hanno eseguito gli utenti sul server, serve un registro che l'utente non possa modificare. La cronologia della shell non è quel registro. È un file di servizio, di proprietà dell'account che lo ha scritto, e chiunque possa digitare comandi in quella shell può disattivarlo o eliminarlo.

Quattro livelli consentono di mantenere un registro reale, e ciascuno comporta dei costi. sudo scrive una riga per ogni comando in syslog. La registrazione I/O di sudo acquisisce un'intera sessione per un account. Un hook della shell, come PROMPT_COMMAND, registra ciò che un utente interattivo di bash digita. Il sottosistema di audit del kernel registra direttamente la syscall execve, perciò è l'unico livello che rileva ogni processo. Questa guida procede lungo questi livelli, indica dove si interrompe ciascuno e si conclude con l'aspetto che determina se tutto questo ha davvero valore: trasferire i registri fuori dalla macchina prima che la persona sottoposta ad audit possa raggiungerli.

Un avviso prima di iniziare. Il sottosistema di audit opera nel kernel, quindi nessuno di questi test può essere eseguito in un container che condivide il kernel dell'host. Esegui questi comandi su un VPS KVM il cui kernel sia sotto il tuo controllo.

Perché la cronologia della shell non è un audit trail

~/.bash_history non è una prova attendibile per quattro motivi comuni, e nessuno richiede un attaccante particolarmente abile.

Appartiene all'utente. Il file ha modalità 600 ed è di proprietà di quell'account, quindi rm ~/.bash_history non richiede alcun privilegio. Lo stesso vale per l'apertura del file in un editor e la rimozione delle venti righe rilevanti.

Viene scritto quando la shell termina. Una sessione che termina con kill -9 $$ o con una connessione interrotta non scrive nulla. Anche history -c prima di exit produce lo stesso effetto e può far sembrare che non sia successo nulla.

Si disattiva con una sola parola. unset HISTFILE impedisce la scrittura del file per quella sessione. set +o history interrompe immediatamente la registrazione. HISTCONTROL=ignorespace nasconde ogni comando digitato con uno spazio iniziale. Tutto questo è configurato in man bash, perché la gestione è affidata all'utente.

Registra ciò che è stato digitato, non ciò che è stato eseguito. Un alias o una funzione della shell fanno sì che il testo nel file non corrisponda al programma eseguito dal kernel.

Non sono presenti nemmeno i timestamp, a meno che HISTTIMEFORMAT non fosse impostata mentre la voce veniva scritta, perché bash scrive le proprie righe marcatrici #1755043200 solo quando questa variabile è impostata.

Inoltre, per un accesso condiviso, non consente di sapere chi ha eseguito l'azione. Tre persone che usano un unico account deploy producono un solo file con voci intercalate e associate a un unico uid. Nessun livello di logging può attribuire un'azione a una persona quando due persone condividono lo stesso uid. Questo è il motivo pratico per preferire un account senza privilegi per ogni persona invece di un accesso condiviso.

La cronologia della shell è utile per il suo scopo reale: aiutare a ridigitare il comando del giorno precedente. Usala come indicazione. Non presentarla mai come prova.

Cosa registra sudo e dove si interrompe

sudo invia una riga per ogni comando eseguito alla facility syslog authpriv.

sudo grep 'sudo:' /var/log/auth.log | tail -5
journalctl -t sudo -n 5

Ogni riga indica l'utente, il terminale, la directory di lavoro, l'utente di destinazione e il comando:

sudo:    alice : TTY=pts/0 ; PWD=/home/alice ; USER=root ; COMMAND=/usr/bin/apt update

Se /var/log/auth.log non esiste, rsyslog non è installato su quell'immagine e gli stessi record sono disponibili soltanto nel journal. Verificare che il journal non sia volatile prima di farvi affidamento:

journalctl --list-boots

La presenza del solo boot corrente indica che /var/log/journal non esiste. Il journal risiede quindi in /run e tutte le righe vengono perse al riavvio successivo. Renderlo persistente:

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald

Vediamo ora il limite. sudo registra il comando che gli è stato richiesto di eseguire. Non registra ciò che il comando esegue successivamente. Una sola riga interrompe quindi la traccia:

sudo -i

Il log contiene un unico record relativo alla shell. Ogni comando digitato all'interno di quella shell root è invisibile a sudo, perché sudo non si trova più nel percorso di esecuzione. sudo su -, sudo bash e sudo vim /etc/shadow seguiti da :!bash hanno tutti la stessa struttura. Una regola sudoers che consente l'esecuzione di un programma con una shell escape, ad esempio vim o find, concede di fatto accesso root non registrato. Verificare a quali risorse un account può accedere realmente prima di considerare affidabili le sue righe di log:

sudo -l -U alice

Registrare una sessione completa per un account

Per prima cosa verificare quale implementazione di sudo è installata, perché questa funzione non esiste nella riscrittura in Rust:

sudo --version | head -1

Se l’output indica sudo-rs, saltare questa sezione e usare il sottosistema di audit. La documentazione ufficiale di Ubuntu per le release 25.10 e 26.04 indica la registrazione dell’I/O e sudoreplay come non supportate; questa situazione era ancora invariata ad agosto 2026. È importante perché sudo-rs è il valore predefinito di sudo in queste release. Un aggiornamento può quindi rimuovere un controllo che si pensava di avere. Prima di pianificare la registrazione basata su sudo, consultare l’elenco completo delle modifiche al comportamento di sudo-rs.

Con sudo originale, ancora incluso in Ubuntu 24.04 LTS, attivare la registrazione dell’I/O per un account:

sudo visudo -f /etc/sudoers.d/iolog
Defaults:deploy log_output
Defaults!/usr/bin/sudoreplay !log_output

Usare visudo invece di un editor, perché impedisce di salvare un file con una sintassi non valida. Un file sudoers danneggiato impedisce a tutti di usare sudo. Quindi riprodurre una sessione:

sudo sudoreplay -l user=deploy
sudo sudoreplay 000001

sudoreplay -l elenca le sessioni con i relativi ID e non stampa nulla se log_output non è mai stato applicato a quell’utente. Il costo è il seguente: ogni byte che attraversa il terminale viene memorizzato in /var/log/sudo-io, quindi una sessione verbosa può occupare molto spazio. La seconda riga di sudoers impedisce che una riproduzione venga registrata a sua volta. Il costo principale riguarda i secret, perché un log dell’I/O contiene tutto ciò che è stato digitato e visualizzato, inclusa una password inserita in una richiesta durante la sessione. Deve quindi essere protetto come un archivio di password. Anche la copertura è limitata. Vengono rilevati i comandi eseguiti tramite sudo. Chi accede e lavora sempre con il proprio account non viene registrato.

Hook della shell e modalità precise per aggirarli

La procedura che circola per «registrare ogni comando» consiste nell'inserire un hook PROMPT_COMMAND in /etc/profile.d/:

# /etc/profile.d/00-cmdlog.sh
PROMPT_COMMAND='logger -p local6.info -t cmdlog "$(whoami) $$ $(history 1 | sed "s/^ *[0-9]* *//")"'

bash esegue PROMPT_COMMAND prima di visualizzare ogni prompt. La riga viene quindi inviata a syslog mentre viene digitata, non alla chiusura della shell. logger scrive tramite il demone di log del sistema, quindi i permessi dell'utente sul proprio file non sono rilevanti. Aprire una nuova shell di login e verificare con sudo tail -f /var/log/syslog oppure con journalctl -t cmdlog -f su un'immagine che non contiene rsyslog.

Poi smette di funzionare, in cinque modi che si possono riprodurre singolarmente in un minuto.

  • Le shell non interattive non visualizzano un prompt. ssh you@server 'id' esegue il comando e restituisce il controllo, senza registrare nulla, perché PROMPT_COMMAND non è mai stato valutato.
  • È una variabile. unset PROMPT_COMMAND la disabilita per il resto della sessione e non richiede privilegi.
  • Il file viene letto dalle shell di login. bash --noprofile --norc non esegue mai il file /etc/profile.d/.
  • È specifico di bash. zsh, sh, python3 -c 'import os; os.system("id")' e :!id all'interno di vim eseguono programmi che nessun hook del prompt di bash può intercettare.
  • Registra la riga così come viene digitata. Un alias o una funzione può quindi nascondere il comando eseguito effettivamente.

Usare un hook della shell come comodità. Per gli utenti collaborativi, risponde alla domanda «che cosa ho eseguito martedì scorso». Non lasciare che una checklist lo consideri un controllo.

The kernel audit subsystem sees every execve

The Linux audit subsystem, driven by the auditd daemon, is the only layer here that a user cannot step around, because the record is made inside the kernel at the moment the syscall runs. If a process executes a program, there is an event. The shell, the language and the presence of a terminal make no difference.

sudo apt update && sudo apt install -y auditd audispd-plugins
sudo systemctl enable --now auditd
sudo auditctl -s

auditctl -s prints the daemon state. enabled 1 with a non-zero pid means it is running, and lost 0 means no records have been dropped yet. Remember that lost counter, it comes back later.

auid is the field that makes audit worth the trouble. PAM sets a login uid when a session starts, and the kernel carries it on every child process from then on. Check yours:

cat /proc/self/loginuid

An interactive SSH session prints your uid, because /etc/pam.d/sshd includes pam_loginuid.so. A value of 4294967295 means the loginuid was never set, which is normal for a process started by a system daemon at boot. The important part is that sudo -i does not change it: a root shell opened by alice still carries auid 1000, so every command inside it is attributable to alice. That is exactly the gap sudo leaves open. Changing a loginuid once set needs CAP_AUDIT_CONTROL, which ordinary users do not have, and sudo auditctl --loginuid-immutable closes it for root as well until the next reboot.

Check that /etc/pam.d/sshd, /etc/pam.d/login and /etc/pam.d/cron each include pam_loginuid.so, or events will arrive with nobody attached to them. That is the same file list you touch when hardening SSH access on a VPS, so do the two jobs together.

Regole iniziali per auditd

Le regole si trovano in /etc/audit/rules.d/*.rules. augenrules le concatena in un unico elenco nell’ordine dei nomi dei file, e l’ordine determina il comportamento, perché il kernel si ferma alla prima regola corrispondente. Prima di aggiungere qualcosa, leggere quanto è già presente, perché un -D in un file successivo elimina tutto ciò che è stato caricato prima.

ls /etc/audit/rules.d/
cat /etc/audit/rules.d/audit.rules

Quindi scrivere /etc/audit/rules.d/50-exec.rules:

## Suppressions first: the kernel takes the first matching rule.
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-deb
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-query
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-split
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-trigger

## Every program started by a logged-in human.
-a always,exit -F arch=b64 -S execve,execveat -F auid>=1000 -F auid!=unset -k exec
-a always,exit -F arch=b32 -S execve,execveat -F auid>=1000 -F auid!=unset -k exec

## Changes to who may become root.
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity

## Changes to the audit configuration itself.
-w /etc/audit/ -p wa -k auditconfig

Caricare le regole e verificare:

sudo augenrules --load
sudo auditctl -l

Se auditctl -l ristampa le regole, significa che sono attive. No rules indica che il caricamento non è riuscito, mentre journalctl -u auditd -n 20 identifica il file e la riga rifiutata dal parser. Le versioni precedenti dello userspace di audit non riconoscono la parola chiave unset. Se il loader segnala un errore per quel campo, scrivere invece -F auid!=4294967295, che esprime lo stesso valore in forma estesa.

Ora leggere gli eventi:

sudo ausearch -k exec -ts recent -i | tail -40
sudo ausearch -ul 1000 -ts today -i
sudo aureport -k --summary -i

-i converte uids e numeri di syscall nei relativi nomi e, in pratica, non è facoltativo. -ts recent limita la ricerca agli ultimi dieci minuti. Ogni esecuzione produce un gruppo di record: un record SYSCALL con uid, auid, stato di uscita e chiave, un record EXECVE con l’elenco completo degli argomenti, oltre ai record CWD e PATH per il contesto.

Un limite importante, perché può trarre in inganno. audit registra le syscall, ma un builtin della shell non esegue una syscall propria. cd /root non avvia alcun programma. Anche echo evil >> /etc/passwd, digitato al prompt di bash, non avvia alcun programma, perché sia echo sia il redirect vengono eseguiti all’interno del processo della shell già in esecuzione. Pertanto le regole execve rilevano i programmi, mentre le regole -w rilevano le scritture. Nessuno dei due gruppi è sufficiente da solo.

Infine, bloccare la configurazione:

## /etc/audit/rules.d/99-finalize.rules
-e 2

-e 2 rende immutabile l’insieme di regole fino al successivo riavvio. Dopo il caricamento, auditctl -s restituisce enabled 2 e qualsiasi tentativo di aggiungere o eliminare una regola fallisce con Operation not permitted, anche per root. Aggiungere questo file per ultimo e prevedere un riavvio ogni volta che si desidera modificare una regola. Questo compromesso è essenziale: un insieme di regole che chiunque può disattivare senza lasciare traccia non costituisce una prova.

Un audit log che nessuno legge è un artefatto di conformità

Il problema di auditd non è che non rilevi gli eventi. Il problema è che ne registra così tanti che nessuno li consulta mai. Alla fine, il log esiste per soddisfare una checklist invece di rispondere a una domanda.

Prima di modificare qualsiasi impostazione, calcola il volume sul tuo sistema:

sudo aureport -k --summary -i
sudo du -sh /var/log/audit

Un singolo sudo apt upgrade esegue migliaia di processi di breve durata e ognuno conserva il tuo auid. Un solo aggiornamento dei pacchetti può quindi generare più eventi di un'intera settimana di attività manuale. Per questo le esclusioni precedenti indicano dpkg e i relativi helper. Applica le esclusioni in base all'eseguibile, mai all'utente: un'esclusione per /usr/bin/dpkg è una lacuna che puoi descrivere in una frase, mentre un'esclusione per un account ha esattamente la forma dell'elemento che stavi cercando di rilevare.

La chiave -k presente in ogni regola rende il log ricercabile anche un mese dopo. ausearch -k sudoers è una domanda a cui corrisponde una risposta. ausearch senza filtri è un muro di testo che ti porta a smettere di leggere. Se il tuo collector richiede JSON invece del formato nativo, laurel è un plugin di auditd che riscrive ogni evento come un singolo oggetto JSON con gli argomenti decodificati. Si registra in /etc/audit/plugins.d/ come qualsiasi altro plugin e auditd rileva le modifiche ai plugin su sudo pkill -HUP auditd.

Quanto costa davvero auditd

Ogni syscall corrispondente diventa un record che il kernel formatta e passa allo spazio utente. Il costo si manifesta in due aree, entrambe misurabili sul proprio carico di lavoro invece di essere stimate sulla base di valori pubblicati da altri.

  • CPU e latenza. Una macchina che crea continuamente processi tramite fork, un host di build o un runner CI genera un record per ogni exec. Quando il backlog del kernel si riempie, --backlog_wait_time fa sospendere al kernel il processo che ha generato l'evento finché non si libera spazio. Di conseguenza, audit si manifesta come rallentamento delle build, non come una percentuale di utilizzo della CPU. In condizioni di carico reali, controllare backlog e lost in sudo auditctl -s. Un valore lost in aumento indica che i record sono stati persi. Un log con lacune non segnalate è peggiore dell'assenza di log, perché continuerete comunque a considerarlo affidabile.
  • Disco. Leggere /etc/audit/auditd.conf e decidere esplicitamente cosa deve accadere quando il disco si riempie, perché i valori forniti dal pacchetto riflettono scelte predefinite. max_log_file, num_logs e max_log_file_action controllano la rotazione. space_left_action, admin_space_left_action e disk_full_action controllano la gestione delle emergenze. Alcune azioni disponibili, tra cui halt e single, arrestano la macchina invece di perdere un record.

La riga -f in /etc/audit/rules.d/audit.rules esprime la stessa decisione a livello del kernel: -f 1 segnala un errore di audit a syslog, mentre -f 2 provoca il panic del kernel. Scegliere 2 solo se si preferisce davvero perdere il server anziché un record. Su una VPS che esegue servizi da cui dipendono gli utenti, usare invece la rotazione e spostare il problema dello spazio di archiviazione fuori dalla macchina.

Inviare i log fuori dal server, quasi in tempo reale

È questo che i rapporti sugli incidenti continuano a dimostrare. I log che restano sull'host compromesso possono essere modificati da chi lo ha compromesso. root può riscrivere /var/log/auth.log, eliminare /var/log/audit/audit.log e arrestare il demone. -e 2 impedisce di scaricare le regole. Non protegge da rm. Ogni livello superiore produce prove soltanto se una copia lascia prima la macchina.

Il trasporto integrato di Audit usa il plugin audisp-remote di audispd-plugins. Attivalo in /etc/audit/plugins.d/au-remote.conf:

active = yes
direction = out
path = /usr/sbin/audisp-remote
type = always
format = string

Prima di ricaricare la configurazione, verifica path rispetto a command -v audisp-remote, perché un percorso errato non produce nulla, tranne una riga nel journal. Imposta remote_server e port in /etc/audit/audisp-remote.conf e, sul collector, imposta tcp_listen_port = 60 nel relativo auditd.conf. Ricarica con sudo pkill -HUP auditd. Su molte immagini systemctl restart auditd viene rifiutato perché il file dell'unità imposta RefuseManualStop=yes. Per questo il segnale è il metodo più affidabile.

L'altra opzione inserisce gli eventi di audit nel flusso syslog che già inoltri. /etc/audit/plugins.d/syslog.conf viene fornito con active = no. Impostalo su yes e ricarica la configurazione. Gli eventi di audit verranno così aggiunti alle righe di sudo e a tutto il resto. Inoltra quindi l'intero flusso con rsyslog tramite TLS (transport layer security), che richiede il pacchetto rsyslog-gnutls:

# /etc/rsyslog.d/60-forward.conf
*.* action(type="omfwd"
    target="logs.example.net" port="6514" protocol="tcp"
    StreamDriver="gtls" StreamDriverMode="1"
    StreamDriverAuthMode="x509/name"
    StreamDriverPermittedPeers="logs.example.net"
    action.resumeRetryCount="-1"
    queue.type="linkedList" queue.filename="fwd" queue.saveOnShutdown="on")

La parte più importante riguarda le impostazioni della coda. action.resumeRetryCount="-1" esegue tentativi indefiniti e la coda assistita da disco con queue.saveOnShutdown="on" conserva i record mentre il collector non è raggiungibile, quindi li invia quando torna disponibile. Senza queste due impostazioni, un riavvio del collector crea un vuoto nelle prove e non lascia alcuna indicazione della sua presenza. Applica la configurazione con sudo systemctl restart rsyslog, quindi verifica che i record arrivino effettivamente sul collector prima di considerare affidabile il sistema.

Resta da chiudere un ultimo punto: il collector deve essere una macchina sulla quale le persone sottoposte ad audit non possano accedere. Se lo stesso gruppo di amministratori dispone dell'accesso root al server dei log, hai copiato il file, ma non lo hai protetto. Usa credenziali separate, chiavi separate e, idealmente, un account separato presso il provider. È lo stesso principio per cui un metodo centralizzato per gestire molti server Linux conviene predisporlo prima di averne bisogno. Ed è ciò che determina la differenza tra una prima ora utile e una prima ora inutile quando stai gestendo un VPS compromesso.

Verificare che un utente normale non possa riscrivere il record

Verificate questa proprietà invece di darla per scontata. Da un account ordinario, senza sudo:

echo test >> /var/log/auth.log
cat /var/log/audit/audit.log
auditctl -D
id -nG

In ordine, dovete ottenere: Permission denied, perché auth.log appartiene a syslog, ha come gruppo adm e ha modalità 640; di nuovo Permission denied, perché il log di audit ha modalità 600 ed è di proprietà di root; un errore che impedisce l'esecuzione, perché per modificare le regole di audit è necessario CAP_AUDIT_CONTROL; infine, un elenco dei gruppi che non contiene né admsystemd-journal.

È quest'ultimo controllo a essere spesso trascurato. L'appartenenza a adm concede l'accesso in lettura a /var/log/auth.log, mentre l'appartenenza a systemd-journal concede l'accesso in lettura all'intero journal. Nessuno dei due gruppi concede l'accesso in scrittura, quindi nessuno dei due consente di alterare i dati. Entrambi permettono di leggere ogni riga di autenticazione del server. È una decisione da prendere consapevolmente, non da copiare da una riga usermod -aG trovata in una risposta su un forum.

Infine, verificate che dopo un riavvio rimangano valide entrambe le condizioni necessarie:

sudo auditctl -s
systemctl is-enabled auditd

enabled 2 significa che il set di regole è bloccato fino al riavvio successivo. enabled, restituito dal secondo comando, significa che auditd viene avviato di nuovo dopo quel riavvio. Un set di regole che rimane attivo soltanto fino al successivo aggiornamento del kernel non costituisce una traccia di audit.

FAQ

Come posso visualizzare tutti i comandi eseguiti da un utente specifico?

Individua il suo uid con id -u alice, quindi cerca nel log di audit usando il login uid: sudo ausearch -ul 1000 -ts today -i. Aggiungi -k exec per limitare la ricerca alla regola execve. Il login uid viene impostato al login e resta invariato attraverso su e sudo -i, quindi questa ricerca include i comandi eseguiti all'interno di una shell root aperta da quell'account. Funziona soltanto per i comandi eseguiti dopo il caricamento delle regole, perché audit non conserva la cronologia degli eventi che non era configurato per registrare. sudo aureport -k --summary -i mostra i conteggi per regola, se vuoi esaminare prima la distribuzione dei dati.

Un utente può eliminare la cronologia di bash per nascondere ciò che ha eseguito?

Sì, e non sono necessari privilegi. ~/.bash_history appartiene a quell'utente e ha modalità 600, quindi l'utente può modificarlo, svuotarlo o rimuoverlo. Può anche impedire la scrittura con unset HISTFILE, interrompere la registrazione durante la sessione con set +o history oppure nascondere singoli comandi digitandoli con uno spazio iniziale quando è impostato HISTCONTROL=ignorespace. Bash scrive il file quando la shell termina, quindi una sessione terminata con kill -9 $$ non registra nulla. Considera la cronologia della shell un'indicazione, mai una prova.

sudo registra ciò che accade all'interno di sudo -i?

No. sudo registra il comando che gli è stato chiesto di eseguire, quindi sudo -i produce una riga per la shell e nulla per i comandi successivi. Ogni comando digitato in quella shell root è invisibile a sudo, perché sudo non è più coinvolto. sudo su -, sudo bash e qualsiasi programma autorizzato che permetta di aprire una shell si comportano nello stesso modo. Due misure colmano questa lacuna: regole audit su execve, che registrano ogni programma associandolo al login uid originale, e regole sudoers che non concedono una shell fin dall'inizio.

auditd rallenta il server?

Dipende interamente dal numero di processi avviati dal carico di lavoro, quindi misuralo invece di affidarti a un valore teorico. Un server che risponde soprattutto alle richieste esegue pochi processi e non noterà differenze. Un host di build o un runner CI esegue continuamente nuovi processi e può risentirne molto, perché quando il backlog di audit del kernel si riempie, il processo che ha generato l'evento viene sospeso finché non si libera spazio. Esegui sudo auditctl -s sotto carico reale e monitora backlog e lost. Qualsiasi valore lost superiore a zero indica che alcuni record sono stati persi. È il risultato peggiore, perché il log contiene ora lacune non visibili.

Dove devono essere archiviati i log di audit?

Su un'altra macchina, con un ritardo misurato in secondi. Chiunque ottenga root sull'host sottoposto ad audit può eliminare /var/log/audit/audit.log e modificare /var/log/auth.log, quindi le copie locali permettono di rispondere soltanto alle domande relative a incidenti che nessuno ha cercato di nascondere. Inoltra i log con il plugin audisp-remote a un auditd centrale oppure abilita il plugin syslog di audit e inoltra l'intero flusso syslog con rsyslog tramite TLS. Assegna al collector credenziali proprie e assicurati che gli account sottoposti ad audit non possano accedervi.