La piste d'audit ne peut pas grossir jusqu'au déclenchement d'une action d'arrêt
Un hôte peut être configuré pour s'arrêter lorsque sa partition d'audit se remplit, et recevoir par ailleurs une piste d'audit qui grossit sans borne. Chaque réglage est conforme isolément, et ensemble ils ne protègent pas l'hôte : ils programment son extinction. Ce contrôle natif pavois de la famille growth-* mesure la combinaison. Dès qu'admin_space_left_action ou disk_full_action peut arrêter la machine, la piste doit être bornée : max_log_file_action = rotate avec num_logs > 1 et un max_log_file non nul, ou suspend avec un max_log_file non nul, qui arrête la journalisation plutôt que la machine.
Vérifié sur l’état résolu en cours d’exécution (ex. sshd -T, sysctl, systemctl show), attrape les drop-ins et Include qu’une lecture de fichier raterait. Réserve : runtime ≠ persistance ; une valeur correcte maintenant peut ne pas survivre à un redémarrage.
Pavois vérifie la configuration effective, l’état résolu et réellement appliqué, pas un fichier. Les scanners basés fichier (OVAL/SCAP, Lynis) ratent les Include, drop-ins et défauts runtime ; ce check voit ce qui est réellement en vigueur.
Un mapping est une référence croisée vers l’endroit où chaque norme situe cette exigence, ancrée et recoupée, pas une affirmation d’équivalence. Un check réussi est une preuve vers ces références, comment le lire.
Pourquoi cette règle
Une action d'arrêt sur le sous-système d'audit n'est un filet de sécurité que si l'événement qu'elle rattrape reste rare. Face à une piste non bornée, ce n'est plus un filet mais un compte à rebours : la piste grossit au rythme où l'hôte est audité, atteint le seuil, et l'action se déclenche. Aucune directive n'est fautive lue isolément, et c'est précisément pourquoi la vérification doit porter sur le couple. Les normes formulent la même exigence des deux côtés, AU-4 demandant que le stockage d'audit soit dimensionné pour la rétention attendue et le STIG de la DISA demandant que l'hôte s'arrête plutôt que de ne plus auditer, si bien qu'un hôte peut satisfaire les deux textes et se révéler incapable de rester allumé.
Ce que vérifie Pavois
Pavois lit /etc/audit/auditd.conf et retient la dernière occurrence de chaque directive, c'est-à-dire la valeur qu'auditd charge au démarrage et au rechargement. Lire un fichier est précisément ce que pavois refuse de faire pour un service, car un Include ou un drop-in rendrait le fichier menteur. auditd.conf fait exception pour une raison : contrairement aux règles d'audit (/etc/audit/rules.d/), il n'a ni répertoire de drop-ins ni étape d'agrégation, donc ce fichier unique est la configuration effective, et le démon n'offre aucun équivalent de -T auquel la confronter.
Cinq directives sont lues, et le verdict est une décision, pas un seuil :
- si ni
admin_space_left_actionnidisk_full_actionne peut arrêter l'hôte (halt,single), le contrôle passe et le dit : il n'y a aucune combinaison à arbitrer. - sinon la piste doit être bornée, par
rotateavecnum_logs > 1etmax_log_file > 0(pire casnum_logs × max_log_fileMio), ou parsuspendavecmax_log_file > 0. - une directive absente vaut la valeur par défaut documentée d'auditd (
max_log_file 0,num_logs 0, actionignore), ce qui n'est pas la même chose qu'une valeur illisible : une taille ou un compte non numérique renvoieunknownet échoue. Ce contrôle ne passe jamais sur une preuve qu'il n'a pas recueillie.
Une limite, délibérée et annoncée plutôt que masquée : la vérification ne lit qu'auditd.conf. Une piste bornée à num_logs × max_log_file sur une partition plus petite que cette borne reste une panne en attente, et n'est pas détectée, car trancher exigerait df, du et cinq fois le code de la plus longue vérification de cette base.
describe command('sh -c \'v() { grep -iE "^[[:space:]]*$1[[:space:]]*=" /etc/audit/auditd.conf 2>/dev/null | tail -1 | sed -E "s/^[^=]*=[[:space:]]*//; s/[[:space:]]*(#.*)?$//" | tr A-Z a-z; }; a=$(v admin_space_left_action); f=$(v disk_full_action); m=$(v max_log_file_action); n=$(v num_logs); s=$(v max_log_file); case "$a$f" in *halt*|*single*) ;; *) echo "ok no stopping action"; exit 0;; esac; n=${n:-0}; s=${s:-0}; case "$n$s" in *[!0-9]*) echo "unknown num_logs or max_log_file not numeric"; exit 0;; esac; if [ "$m" = rotate ] && [ "$n" -gt 1 ] && [ "$s" -gt 0 ]; then echo "ok bounded at $((n * s)) MiB"; elif [ "$m" = suspend ] && [ "$s" -gt 0 ]; then echo "ok bounded at $s MiB"; else echo "ko UNBOUNDED trail (max_log_file_action=${m:-ignore} num_logs=$n max_log_file=$s) with a stopping action (admin_space_left_action=${a:-ignore} disk_full_action=${f:-ignore})"; fi\'') do
its('stdout') { should match(/^ok /) }
endComment vérifier qu’elle est appliquée
Lisez les cinq directives qui décident, puis l'espace dans lequel elles doivent tenir :
grep -iE '^[[:space:]]*(admin_space_left_action|disk_full_action|max_log_file_action|num_logs|max_log_file)[[:space:]]*=' /etc/audit/auditd.conf
df -h /var/log/audit
Un hôte borné répond par exemple :
admin_space_left_action = HALT
disk_full_action = HALT
max_log_file_action = ROTATE
num_logs = 5
max_log_file = 8
Cela se lit d'une traite : l'hôte s'arrête quand l'espace d'audit manque, et la piste ne peut jamais réclamer plus de 5 × 8 = 40 Mio, qui doivent tenir dans ce que df annonce pour /var/log/audit. La même sortie avec max_log_file_action = keep_logs, ou avec num_logs = 0, décrit un hôte qui finira par s'arrêter tout seul.
Inspecter et investiguer
journalctl -u auditd enregistre le franchissement des seuils d'espace et l'action prise par auditd, tandis qu'ls -1 /var/log/audit/audit.log* et du -sh /var/log/audit disent quelle part de la partition la piste occupe déjà.
La panne que ce contrôle évite possède une signature qu'il vaut mieux connaître, car elle vous prive du système vivant : un hôte qui s'éteint quelques secondes après chaque démarrage. auditd démarre, trouve la partition pleine, applique l'action d'arrêt, et la machine disparaît avant que quiconque ait pu se connecter. La preuve se trouve dans le démarrage précédent : lisez journalctl -b -1 -u auditd depuis une console ou un mode de secours plutôt que d'essayer de l'attraper en direct.
Remédiation
La remédiation est manuelle par conception, et c'est le cas rare où pavois refuse de choisir à la place de l'exploitant. Sur un hôte soumis au STIG de la DISA, halt est la valeur exigée : la réécrire silencieusement échangerait un incident de disponibilité contre un écart de conformité que personne n'a demandé. Quatre issues satisfont ce contrôle, et ce sont des décisions de politique :
- Borner la piste :
max_log_file_action = rotate,num_logs > 1,max_log_filedimensionné pour quenum_logs × max_log_filetienne dans la partition. Les enregistrements les plus anciens sont supprimés : ne retenez cette option que si l'exigence de rétention l'autorise, ou si la piste est exportée ailleurs. - Agrandir
/var/log/audit, ce qui achète un délai proportionnel à l'agrandissement sans changer le mode de défaillance. - Exporter la piste hors de l'hôte (greffon distant d'
audispd, ou un collecteur), seule option qui conserve à la fois une rétention non bornée et un hôte qui reste allumé. - Retenir une action que la norme applicable accepte encore, par exemple
suspendousysloglorsque le référentiel le permet.
Notez ce que la remédiation n'exige pas : ni auditd-admin-space-left-action, ni auditd-disk-full-action, ni auditd-max-log-file-action n'a besoin de devenir non conforme. Le contrôle mesure une combinaison, il se lève donc en changeant la combinaison, jamais en désarmant une protection.
Pavois applique ceci avec son propre moteur harden, le plan ci-dessous, pas un script shell :
| reason | The operator chooses: bound the trail (max_log_file_action = rotate with num_logs > 1 and a max_log_file), enlarge /var/log/audit, ship the journal off the host, or set an action the applicable norm still accepts. Pavois will not pick for them: on a STIG host halt is the REQUIRED value, so silently rewriting it would trade an availability incident for a compliance deviation the operator did not ask for. |
|---|---|
| resource | manual |
pavois harden plan localoù la cible est local, un alias SSH user@hôte, ou un conteneur , Docs
Impact & précautions
La famille growth-* est née d'une panne réelle, et ce contrôle est celui qui l'aurait attrapée. Un hôte durci par pavois s'éteignait tout seul six secondes après chaque démarrage : max_log_file_action = keep_logs (auditd ne supprime jamais un journal), une partition /var/log/audit séparée créée par la recette de pavois, et admin_space_left_action = halt. Le système de fichiers a été mesuré à 738 fichiers, 5,8 Go, 100 % plein, et tous les contrôles étaient au vert, car chacun des trois était conforme isolément.
L'arbitrage diffère selon l'issue retenue. Borner la piste supprime les enregistrements les plus anciens, perte bien réelle sur un hôte dont c'est la raison d'être de les conserver, et c'est d'ailleurs ce qui rend keep_logs séduisant. Agrandir la partition ne fait que déplacer la date. suspend garde l'hôte allumé mais cesse d'enregistrer, ce qui constitue pour la plupart des référentiels un écart à part entière plutôt qu'un correctif.
Précaution avant toute modification : l'hôte qui échoue à ce contrôle est peut-être déjà proche du seuil. Vérifiez d'abord df -h /var/log/audit et récupérez ou archivez de l'espace avant de recharger auditd, car un rechargement sur une partition presque pleine peut déclencher l'action même que vous cherchez à rendre inatteignable.
Mapping des normes
| Norme | Référence | Type | Version | Confiance |
|---|---|---|---|---|
| NIST | AU-4 | support | 800-53 Rev 5 · 800-171 Rev 2 (pinned) | moyenne |
Chaque référence est une référence croisée ancrée dans le benchmark amont et recoupée avec le SCAP Security Guide et ansible-lockdown, pas une affirmation d’équivalence. Direct = une exigence prescriptive au niveau de la ligne ; support = une famille de contrôle abstraite (NIST) vers laquelle le check apporte une preuve. Comment lire un mapping.