Auditer les commandes exécutées sur votre serveur
L’historique shell n’est pas une preuve. Comparez sudo, l’enregistrement de session, les hooks shell et auditd execve, puis exportez les logs hors du serveur.
Ce qui enregistre réellement les commandes exécutées par les utilisateurs sur votre serveur
Pour auditer les commandes exécutées par les utilisateurs sur votre serveur, vous avez besoin d’un enregistrement que l’utilisateur ne peut pas modifier. L’historique du shell ne convient pas. Il s’agit d’un fichier pratique, appartenant au compte qui l’a écrit. Toute personne pouvant saisir des commandes dans ce shell peut le désactiver ou le supprimer.
Quatre niveaux permettent de conserver un véritable enregistrement, et chacun a un coût. sudo écrit une ligne par commande dans syslog. La journalisation des entrées-sorties de sudo capture toute une session pour un compte. Un hook du shell tel que PROMPT_COMMAND journalise ce qu’un utilisateur de bash interactif saisit. Le sous-système d’audit du kernel enregistre directement l’appel système execve. C’est pourquoi il s’agit du seul niveau qui voit tous les processus. Ce guide présente ces niveaux dans l’ordre, précise les limites de chacun et termine par le point qui détermine leur réelle utilité : transférer les enregistrements hors de la machine avant que la personne auditée puisse y accéder.
Un avertissement avant de commencer. Le sous-système d’audit dépend du kernel. Vous ne pouvez donc pas tester ces fonctionnalités dans un conteneur qui partage le kernel de l’hôte. Exécutez ces commandes sur un VPS KVM dont vous contrôlez le kernel.
Pourquoi l’historique du shell n’est pas une trace d’audit
~/.bash_history ne constitue pas une preuve pour quatre raisons courantes. Aucune ne nécessite un attaquant particulièrement compétent.
Il appartient à l’utilisateur. Le fichier est en mode 600 et appartient à ce compte. rm ~/.bash_history ne nécessite donc aucun privilège. Il suffit également de l’ouvrir dans un éditeur et de supprimer les vingt lignes importantes.
Il est écrit à la fermeture du shell. Une session qui se termine avec kill -9 $$, ou avec une connexion interrompue, n’écrit rien. history -c avant exit produit le même effet et donne l’impression que rien ne s’est passé.
Il suffit d’un mot pour le désactiver. unset HISTFILE empêche l’écriture du fichier pour cette session. set +o history arrête immédiatement l’enregistrement. HISTCONTROL=ignorespace masque toutes les commandes saisies avec une espace initiale. Tout cela se trouve dans man bash, car ce fichier est conçu pour être contrôlé par l’utilisateur.
Il enregistre ce qui a été saisi, pas ce qui a été exécuté. Un alias ou une fonction shell signifie que le texte du fichier ne correspond pas au programme exécuté par le kernel.
Il n’y a pas non plus d’horodatage, sauf si HISTTIMEFORMAT était défini lors de l’écriture de l’entrée, car bash n’écrit ses lignes de marqueur #1755043200 que lorsque cette variable est définie.
Sur un login partagé, il ne peut pas non plus vous indiquer qui a effectué l’action. Trois personnes utilisant un compte deploy produisent un seul fichier entrelacé sous un seul uid. Aucune couche de journalisation ne peut attribuer une action à une personne lorsque deux personnes partagent un uid. C’est l’argument pratique en faveur de un compte non privilégié par personne plutôt qu’un login partagé.
L’historique du shell remplit correctement sa fonction réelle : vous aider à retaper la commande d’hier. Utilisez-le comme indication. Ne le présentez jamais comme une preuve.
Ce que sudo journalise et où s’arrête la trace
sudo envoie une ligne pour chaque commande qu’il exécute à la facility syslog authpriv.
sudo grep 'sudo:' /var/log/auth.log | tail -5
journalctl -t sudo -n 5Chaque ligne indique l’utilisateur, le terminal, le répertoire de travail, l’utilisateur cible et la commande :
sudo: alice : TTY=pts/0 ; PWD=/home/alice ; USER=root ; COMMAND=/usr/bin/apt updateSi /var/log/auth.log n’existe pas, rsyslog n’est pas installé sur cette image et les mêmes enregistrements se trouvent uniquement dans le journal. Vérifiez que le journal n’est pas volatile avant de vous y fier :
journalctl --list-bootsLa présence du boot courant uniquement signifie que /var/log/journal n’existe pas. Le journal est donc stocké dans /run et chaque ligne est perdue au redémarrage suivant. Rendez-le persistant :
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journaldVoici la limite. sudo journalise la commande qu’on lui demande d’exécuter. Il ne journalise pas ce que cette commande fait ensuite. Une seule ligne suffit donc à interrompre la trace :
sudo -iLe journal contient un seul enregistrement pour le shell. Chaque commande saisie dans ce shell root est invisible pour sudo, car sudo n’est plus dans le chemin d’exécution. sudo su -, sudo bash et sudo vim /etc/shadow suivis de :!bash présentent tous la même structure. Une règle sudoers qui autorise un programme avec une sortie vers un shell, comme vim ou find, accorde un accès root non journalisé. Vérifiez ce qu’un compte peut réellement atteindre avant de faire confiance à ses lignes de journal :
sudo -l -U aliceEnregistrer une session complète pour un compte
Commencez par vérifier quelle version de sudo est installée, car cette fonctionnalité n’existe pas dans la réécriture Rust :
sudo --version | head -1Si la sortie mentionne sudo-rs, ignorez cette section et utilisez le sous-système d’audit. La documentation officielle d’Ubuntu pour les versions 25.10 et 26.04 indique que la journalisation des entrées-sorties et sudoreplay ne sont pas pris en charge. C’était toujours le cas en août 2026. Ce point est important, car sudo-rs est le sudo par défaut dans ces versions. Une mise à niveau peut donc supprimer un contrôle que vous pensiez avoir. La liste complète des changements de comportement de sudo-rs mérite d’être consultée avant de prévoir une journalisation basée sur sudo.
Avec sudo classique, toujours fourni par Ubuntu 24.04 LTS, activez la journalisation des entrées-sorties pour un compte :
sudo visudo -f /etc/sudoers.d/iologDefaults:deploy log_output
Defaults!/usr/bin/sudoreplay !log_outputUtilisez visudo plutôt qu’un éditeur, car cette commande refuse d’enregistrer un fichier dont la syntaxe est invalide. Un fichier sudoers incorrect empêche tout le monde d’utiliser sudo. Relancez ensuite une session :
sudo sudoreplay -l user=deploy
sudo sudoreplay 000001sudoreplay -l liste les sessions avec leurs identifiants et n’affiche rien si log_output ne s’est jamais appliqué à cet utilisateur. Le coût : chaque octet qui transite par le terminal est stocké sous /var/log/sudo-io. Une session verbeuse peut donc occuper beaucoup d’espace. La deuxième ligne sudoers empêche une relecture de session d’être enregistrée elle-même. Le vrai risque concerne les secrets : un journal d’entrées-sorties contient tout ce qui a été saisi et affiché, notamment un mot de passe saisi à une invite au cours de la session. Il doit donc bénéficier de la même protection qu’un gestionnaire de mots de passe. La couverture reste limitée. Le système observe les commandes exécutées avec sudo. Une personne qui se connecte et travaille entièrement avec son propre compte n’est pas enregistrée.
Hooks de shell, et comment les contourner exactement
La recette qui circule pour « journaliser chaque commande » consiste à ajouter un hook PROMPT_COMMAND dans /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 exécute PROMPT_COMMAND avant d’afficher chaque invite. La ligne est donc envoyée à syslog dès sa saisie, et non à la fermeture du shell. logger écrit via le daemon de journalisation système. Les permissions du fichier de l’utilisateur n’interviennent donc pas. Ouvrez un nouveau shell de connexion et vérifiez avec sudo tail -f /var/log/syslog, ou avec journalctl -t cmdlog -f sur une image sans rsyslog.
Puis cette méthode cesse de fonctionner, de cinq façons que vous pouvez chacune reproduire en une minute.
- Les shells non interactifs n’affichent jamais d’invite.
ssh you@server 'id'exécute la commande puis se termine, et rien n’est journalisé, carPROMPT_COMMANDn’a jamais été évalué. - Il s’agit d’une variable.
unset PROMPT_COMMANDla désactive pour le reste de la session et ne nécessite aucun privilège. - Le fichier est lu par les shells de connexion.
bash --noprofile --norcne source jamais/etc/profile.d/. - Cette méthode est spécifique à bash.
zsh,sh,python3 -c 'import os; os.system("id")'et:!iddansvimexécutent tous des programmes qu’aucun hook d’invite bash ne pourra voir. - La ligne est journalisée telle qu’elle a été saisie. Un alias ou une fonction peut donc toujours masquer la commande réellement exécutée.
Utilisez un hook de shell comme aide pratique. Il permet de répondre à la question « qu’ai-je exécuté mardi dernier ? » pour les utilisateurs coopératifs. Ne le présentez pas comme un contrôle dans une checklist.
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 -sauditctl -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/loginuidAn 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.
Jeu de règles initial pour auditd
Les règles se trouvent dans /etc/audit/rules.d/*.rules. augenrules les concatène dans l’ordre des noms de fichiers pour former une seule liste. L’ordre détermine le comportement, car le noyau s’arrête à la première règle correspondante. Consultez le contenu existant avant d’ajouter quoi que ce soit, car un -D dans un fichier ultérieur supprime tout ce qui a été chargé auparavant.
ls /etc/audit/rules.d/
cat /etc/audit/rules.d/audit.rulesÉcrivez ensuite /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 auditconfigChargez les règles et vérifiez le résultat :
sudo augenrules --load
sudo auditctl -lLe fait que auditctl -l réaffiche vos règles signifie qu’elles sont actives. No rules signifie que le chargement a échoué, et journalctl -u auditd -n 20 indique le fichier et la ligne rejetés par l’analyseur. Les anciennes versions de l’espace utilisateur d’audit ne comprennent pas le mot-clé unset. Si le chargeur signale un problème avec ce champ, utilisez plutôt -F auid!=4294967295, qui exprime la même valeur en toutes lettres.
Lisez maintenant les événements :
sudo ausearch -k exec -ts recent -i | tail -40
sudo ausearch -ul 1000 -ts today -i
sudo aureport -k --summary -i-i convertit les UID et les numéros d’appels système en noms. En pratique, cette option est indispensable. -ts recent couvre les dix dernières minutes. Chaque exécution produit un groupe d’enregistrements : un enregistrement SYSCALL contenant l’UID, l’AUID, le code de sortie et la clé, un enregistrement EXECVE contenant la liste complète des arguments, ainsi que des enregistrements CWD et PATH fournissant le contexte.
Une limite importante, car elle est souvent oubliée. audit enregistre les appels système, mais un builtin du shell n’effectue aucun appel système qui lui soit propre. cd /root n’exécute aucun programme. echo evil >> /etc/passwd saisi à l’invite bash n’exécute pas non plus de programme, car echo et la redirection sont traités dans le processus du shell déjà en cours d’exécution. Les règles execve voient donc les programmes, tandis que les règles -w voient les écritures. Aucune des deux catégories ne suffit seule.
Enfin, verrouillez la configuration :
## /etc/audit/rules.d/99-finalize.rules
-e 2-e 2 rend le jeu de règles immuable jusqu’au prochain redémarrage. Après son chargement, auditctl -s affiche enabled 2, et toute tentative d’ajouter ou de supprimer une règle échoue avec Operation not permitted, y compris pour root. Ajoutez ce fichier en dernier et prévoyez un redémarrage chaque fois que vous devez modifier une règle. C’est précisément l’objectif de ce compromis : un jeu de règles que n’importe qui peut désactiver discrètement ne constitue pas une preuve.
Un journal d’audit que personne ne consulte est un artefact de conformité
Le problème d’auditd n’est pas qu’il laisse passer des événements. Il enregistre tellement de choses que personne ne consulte jamais les journaux. Le journal finit alors par exister uniquement pour cocher une case de conformité, au lieu de répondre à une question.
Faites le calcul sur votre propre serveur avant de modifier la configuration :
sudo aureport -k --summary -i
sudo du -sh /var/log/auditUn seul sudo apt upgrade lance des milliers de processus de courte durée. Chacun porte votre auid. Une seule mise à jour de paquet peut donc produire plus d’événements qu’une semaine de saisie manuelle. C’est pourquoi les exclusions ci-dessus ciblent dpkg et ses helpers. Excluez les exécutables, jamais les utilisateurs : une exclusion pour /usr/bin/dpkg est une faille que vous pouvez décrire en une phrase, tandis qu’une exclusion pour un compte a exactement la forme de l’élément que vous essayiez de détecter.
La clé -k présente dans chaque règle permet de rechercher les événements dans les journaux un mois plus tard. ausearch -k sudoers est une question qui apporte une réponse. ausearch sans filtre est un mur de texte qui vous habitue à ne plus lire les journaux. Si votre collecteur attend du JSON au lieu du format natif, laurel est un plugin auditd qui réécrit chaque événement sous la forme d’un objet JSON contenant les arguments décodés. Il s’enregistre dans /etc/audit/plugins.d/ comme n’importe quel autre plugin, et auditd prend en compte les modifications des plugins sur sudo pkill -HUP auditd.
Le coût réel d’auditd
Chaque syscall correspondant à une règle devient un enregistrement que le kernel formate et transmet à l’espace utilisateur. Le coût se répartit sur deux points, et vous pouvez le mesurer sur votre propre charge plutôt que de vous fier à un chiffre publié pour une autre machine.
- CPU et latence. Une machine qui crée constamment des processus avec
fork, un serveur de build ou un runner CI produit un enregistrement par exécution. Lorsque le backlog du kernel est plein,--backlog_wait_timeforce le kernel à suspendre le processus à l’origine de l’événement jusqu’à ce qu’une place se libère. Auditd se manifeste alors par des builds plus lents, et non par un pourcentage de CPU. Surveillezbacklogetlostdanssudo auditctl -spendant une charge réelle. Une valeurlosten hausse signifie que des enregistrements ont été perdus. Un journal comportant des trous silencieux est pire qu’une absence de journal, car vous continuerez à lui faire confiance. - Disque. Lisez
/etc/audit/auditd.confet décidez explicitement du comportement à adopter lorsque le disque est plein, car les valeurs fournies par défaut reflètent des choix.max_log_file,num_logsetmax_log_file_actioncontrôlent la rotation.space_left_action,admin_space_left_actionetdisk_full_actioncontrôlent le comportement d’urgence, et certaines actions disponibles, notammenthaltetsingle, arrêtent la machine plutôt que de perdre un enregistrement.
La ligne -f dans /etc/audit/rules.d/audit.rules correspond à cette même décision au niveau du kernel : -f 1 signale un échec d’audit à syslog, tandis que -f 2 provoque un panic du kernel. Choisissez 2 uniquement si vous préférez réellement perdre le serveur plutôt que perdre un enregistrement. Sur un VPS qui héberge un service dont des utilisateurs dépendent, préférez la rotation et déplacez le stockage hors de la machine.
Transférer les journaux hors du serveur, presque en temps réel
C’est ce que les comptes rendus d’incident ne cessent de confirmer. Les journaux qui restent sur l’hôte compromis peuvent être modifiés par l’attaquant. root peut réécrire /var/log/auth.log, supprimer /var/log/audit/audit.log et arrêter le daemon. -e 2 empêche le déchargement des règles. Il ne protège pas rm. Toutes les couches supérieures ne produisent des preuves que si une copie quitte d’abord la machine.
Le transport intégré à audit repose sur le plugin audisp-remote de audispd-plugins. Activez-le dans /etc/audit/plugins.d/au-remote.conf :
active = yes
direction = out
path = /usr/sbin/audisp-remote
type = always
format = stringVérifiez path par rapport à command -v audisp-remote avant de recharger, car un chemin incorrect ne produit rien, à part une ligne dans le journal. Définissez remote_server et port dans /etc/audit/audisp-remote.conf, puis définissez tcp_listen_port = 60 sur le collecteur, dans son propre auditd.conf. Rechargez avec sudo pkill -HUP auditd. Sur de nombreuses images, systemctl restart auditd est refusé, car le fichier d’unité définit RefuseManualStop=yes. Le signal reste donc la méthode fiable.
L’autre option envoie audit dans le flux syslog que vous transmettez déjà. /etc/audit/plugins.d/syslog.conf est fourni avec active = no. Définissez-le sur yes, rechargez, puis les événements audit rejoindront les lignes de sudo et le reste des journaux. Transmettez ensuite l’ensemble avec rsyslog via TLS (transport layer security). Cette méthode nécessite le paquet 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")Les paramètres de queue sont les plus importants. action.resumeRetryCount="-1" effectue des tentatives indéfiniment. La queue assistée par disque avec queue.saveOnShutdown="on" conserve les enregistrements lorsque le collecteur est inaccessible, puis les envoie lorsqu’il redevient disponible. Sans ces deux paramètres, un redémarrage du collecteur crée un trou dans vos preuves, sans aucun moyen de vous signaler ce trou. Appliquez la configuration avec sudo systemctl restart rsyslog, puis vérifiez que les enregistrements arrivent réellement sur le collecteur avant de vous y fier.
Il reste une dernière boucle à fermer : le collecteur doit être une machine sur laquelle les personnes auditées ne peuvent pas se connecter. Si le même groupe d’administrateurs possède root sur le serveur de journaux, vous avez copié le fichier, mais vous ne l’avez pas protégé. Utilisez des identifiants distincts, des clés distinctes et, idéalement, un compte fournisseur distinct. C’est le même raisonnement qui justifie la mise en place de centraliser la gestion de nombreux serveurs Linux avant d’en avoir besoin. C’est aussi ce qui fait la différence entre une première heure utile et une première heure inutile lorsque vous gérez un VPS compromis.
Vérifier qu’un utilisateur normal ne peut pas réécrire l’enregistrement
Testez cette affirmation au lieu de la supposer. Depuis un compte ordinaire, sans sudo :
echo test >> /var/log/auth.log
cat /var/log/audit/audit.log
auditctl -D
id -nGAttendez-vous, dans cet ordre, à : Permission denied, car auth.log appartient à syslog, avec le groupe adm et le mode 640 ; Permission denied à nouveau, car le journal d’audit est en mode 600 et appartient à root ; une erreur indiquant que l’exécution est refusée, car la modification des règles d’audit nécessite CAP_AUDIT_CONTROL ; et une liste de groupes ne contenant ni adm ni systemd-journal.
C’est cette dernière vérification qui pose problème. L’appartenance à adm donne un accès en lecture à /var/log/auth.log, et l’appartenance à systemd-journal donne un accès en lecture à l’ensemble du journal. Aucune des deux ne donne un accès en écriture et ne permet donc de falsifier les enregistrements. Les deux permettent de lire chaque ligne d’authentification du serveur. Il faut donc prendre cette décision volontairement, plutôt que de copier une ligne usermod -aG depuis une réponse de forum.
Enfin, vérifiez les deux éléments qui doivent survivre à un redémarrage :
sudo auditctl -s
systemctl is-enabled auditdenabled 2 signifie que le jeu de règles est verrouillé jusqu’au prochain démarrage. enabled dans la deuxième commande signifie qu’auditd redémarre après ce démarrage. Un jeu de règles qui ne reste en place que jusqu’à la prochaine mise à jour du noyau ne constitue pas non plus une piste d’audit.
FAQ
Comment voir toutes les commandes exécutées par un utilisateur donné ?
Trouvez son uid avec id -u alice, puis recherchez cet uid de connexion dans le journal d’audit avec sudo ausearch -ul 1000 -ts today -i. Ajoutez -k exec pour limiter la recherche à la règle execve. L’uid de connexion est défini à l’ouverture de session et reste inchangé malgré su et sudo -i. Cette méthode capture donc les commandes exécutées dans un shell root ouvert par ce compte. Elle ne fonctionne que pour les commandes exécutées après le chargement des règles, car audit ne conserve aucun historique des événements qu’il n’était pas configuré pour enregistrer. sudo aureport -k --summary -i affiche le nombre d’événements par règle si vous voulez d’abord voir la structure des données.
Un utilisateur peut-il supprimer son historique bash pour dissimuler ses commandes ?
Oui, sans privilèges particuliers. ~/.bash_history appartient à cet utilisateur et possède le mode 600. Il peut donc le modifier, le tronquer ou le supprimer. Il peut aussi empêcher son écriture avec unset HISTFILE, arrêter l’enregistrement en cours de session avec set +o history ou masquer des commandes individuelles en les saisissant avec une espace initiale lorsque HISTCONTROL=ignorespace est défini. Bash écrit le fichier à la fermeture du shell. Une session arrêtée avec kill -9 $$ n’enregistre donc rien. Considérez l’historique du shell comme un indice, jamais comme une preuve.
sudo journalise-t-il ce qui se passe dans sudo -i ?
Non. sudo journalise la commande qu’on lui demande d’exécuter. Ainsi, sudo -i produit une seule ligne pour le shell, puis plus rien. Toutes les commandes saisies dans ce shell root sont invisibles pour sudo, car sudo n’intervient plus. sudo su -, sudo bash et tout programme autorisé qui permet d’ouvrir un shell se comportent de la même manière. Deux mesures permettent de combler cette lacune : des règles audit sur execve, qui enregistrent chaque programme avec l’uid de connexion d’origine, et des règles sudoers qui n’accordent pas de shell au départ.
auditd ralentira-t-il mon serveur ?
Cela dépend entièrement du nombre de processus lancés par votre charge de travail. Mesurez donc l’impact au lieu de vous fier à une valeur théorique. Un serveur qui répond principalement à des requêtes exécute peu de processus et ne remarquera aucune différence. Un hôte de build ou un runner CI exécute constamment des processus et peut subir un ralentissement important. Lorsque le backlog d’audit du noyau est plein, le processus qui a généré l’événement est suspendu jusqu’à ce qu’une place se libère. Exécutez sudo auditctl -s sous une charge réelle et surveillez backlog et lost. Toute valeur lost supérieure à zéro signifie que des enregistrements ont été perdus. C’est le pire résultat, car le journal contient alors des lacunes invisibles.
Où stocker les journaux d’audit ?
Sur une autre machine, avec un délai de transmission mesuré en secondes. Toute personne qui obtient root sur l’hôte audité peut supprimer /var/log/audit/audit.log et réécrire /var/log/auth.log. Les copies locales ne permettent donc de répondre qu’aux questions concernant des incidents que personne n’a tenté de dissimuler. Transférez les événements avec le plugin audisp-remote vers un auditd centralisé, ou activez le plugin syslog d’audit et transférez l’ensemble du flux syslog avec rsyslog sur TLS. Attribuez au collecteur des identifiants qui lui sont propres et vérifiez que les comptes audités n’y ont pas accès.