technique:old:auditd:howto

Journaliser les commandes

Nous avons étudié plusieurs solutions permettant de journaliser les commandes exécutées sur le système, le but étant de pouvoir remonter à la cause d’un éventuel problème sur l’infrastructure.

auditd est actuellement la solution la plus adaptée aux besoins de Picasoft : il est largement supporté, s’intègre bien avec SELinux si besoin, permet de centraliser les logs et d’effectuer leur rotation, permet de journaliser en détail de nombreux événements sur le système et est hautement configurable.

  • journalisation de nombreux événements sur le système (appels systèmes, modification du système de fichiers, etc.)
  • contrôle granulaire sur les événements journalisés et les conditions de leur journalisation
  • bonne intégration à d’autres systèmes tels que selinux, kerberos ou rsyslog
  • rotation automatique des journaux

La configuration d’auditd se fait en deux parties : celle des règles d’audit et celle du démon en lui-même.

Les règles se trouvent dans /etc/audit/rules.d/audit.rules, qui ne doit pas être édité manuellement. Il est automatiquement consitué par aggrégation de celles contenues dans les fichiers de /etc/audit/rules.d/. Il contient une succession d’options qui peuvent être directement passées au démon en appelant la commande auditctl. Les options inscrites dans ce fichier sont passés à auditd lorsqu’il est lancé. Ces options sont documentées dans auditctl(8) et audit.rules(7).

Parmi elles, celles commençant par -w permettent de journaliser les accès aux fichiers en lecture, écriture, exécution ou modification d’attributs. auditd se charge de déterminer ces accès en fonction de certains appels système pertinents. Par exemple, un appel à write(2) ne suffit pas à déterminer accès en écriture car ceux-ci sont trop courants. auditd a (notamment) besoin de l’associer à un appel à open(2) pour considérer une écriture de fichier.

Les règles contenant -S permettent de journaliser les appels système. L’option -F, pouvant apparaître plusieurs fois, spécifie un filtre et l’option -a spécifie au moteur de correspondance du noyau dans quel cas un événement est pris en compte. Un événement générant généralement plusieurs enregistrement, une règle peut soit concerner soit tout un événement, soit juste un enregistrement. Par exemple :

-a never,exit -F exe=/usr/sbin/runc

supprime tous les événements liés à runc alors que :

-a always,exclude -F msgtype=CWD

élimine les enregistrements CWD de tous les événements mais journalise encore les autres enregistrements leur étant associé (sous condition évidente que les autres règles le permettent).

L’option -k permet d’associer un label à une règle. Chaque événement journalisé par celle-ci sera alors portera alors ce label, ce qui est utile pour l’analyse postérieure des journaux.

Il est à noter que l’ordre des règles dans le fichier importe : elles sont évaluées les unes à la suite des autres. Ainsi, si une règle exclut un événement, il ne sera journalisé, peu importe ce que stipulent d’autres règles situées plus loin dans le fichier de configuration.

Une configuration disponible sur Github présente de bonnes pratiques concernant les règles auditd et permet de rapidement se familiariser avec des nombreuses options proposées par son système de règles.

Voici la configuration des règles dans /etc/audit/rules.d/audit.rules que nous avons déployée sur tous les hôtes dans le cadre de la TX :

# First rule - delete all
-D

# Increase the buffers to survive stress events.
# Make this bigger for busy systems
-b 8192

# This determine how long to wait in burst of events
--backlog_wait_time 0

# Set failure mode to syslog
-f 1




# don't log verbose container commands events
-a never,exit -F exe=/usr/sbin/runc
-a never,exit -F exe=/usr/bin/docker-runc
-a never,exit -F exe=/usr/bin/containerd



# don't log CWD records
-a always,exclude -F msgtype=CWD

# don't log SELinux AVC records
-a always,exclude -F msgtype=AVC



# log all 32/54bit execve calls from root, docker and others
-a exit,always -F arch=b64 -F euid=root -S execve -k execve_root
-a exit,always -F arch=b32 -F euid=root -S execve -k execve_root

-a exit,always -F arch=b64 -F egid=docker -S execve -k execve_docker
-a exit,always -F arch=b32 -F egid=docker -S execve -k execve_docker

-a exit,always -F arch=b64 -S execve -k execve_others
-a exit,always -F arch=b32 -S execve -k execve_others

# monitor writes and file attribute changes on /etc and /lib
-w /etc -p wa -k etc_modification
-w /lib -p wa -k lib_modification

Le démon auditd en lui-même est configuré dans le fichier /etc/audit/auditd.conf. Il s’organise en paires clef = valeur séparées par des retours à la ligne. On peut y configurer les journaux, de leur localisation (/var/log/audit/audit.log par défaut) à leur format et à l’espace qu’ils peuvent prendre au maximum, la centralisation des journaux avec Kerberos et les paramètres réseau d’auditd.

La configuration de base proposée par Debian est pertinente. Nous insisterons toutefois sur les options suivantes :

  • dispatcher = /sbin/audispd : on souhaite que la centralisation des logs soit faite par le plugin syslog d’audispd
  • action_mail_acct = root : les mails envoyés par auditd sont par défaut à destination de root. On pourra plus tard mettre en place une centralisation des mails en configurant le service de mail en réseau
  • max_log_file = 8 et max_log_file_action = ROTATE : dès qu’un fichier de log atteint une taille de 8M, on effectue une rotation
  • space_left = 75 et space_left_action = SYSLOG : lorsque la partition contenant les journaux descend en-dessous des 75M de libres, on émet un avertissement avec syslog
  • admin_space_left et admin_space_left_action : lorsque la partition contenant les journaux descend en-dessous des 75M de libres, on suspend l’activité d’auditd
  • disk_full_action = SUSPEND et disk_error_action = SUSPEND : lorsque la partition contenant les journaux est pleine, on suspend l’activité d’auditd

Au-delà de la configuration d’auditd en lui-même, il est conseillé de passer audit=1 comme paramètre au noyau afin de pouvoir auditer les processus éventuellent lancés avant auditd lui-même.

Les informations relative à la centralisation des logs peuvent être retrouvées ici.

Une fois configuré, auditd ne fait que journaliser les événements pertinents dans /var/log/audit/audit.log (ou ailleurs selon la configuration). On peut alors utiliser différentes méthodes pour retrouver ceux nous intéressant. On peut notamment utiliser ausearch et aureport, des outils propres à auditd, journalctl venant avec systemd, ou simplement chercher manuellement à travers les journaux.

aureport(8) produit des résumés des journaux produits par auditd. Ces résumés peuvent être basés sur différents critères décrits dans le manuel, comme par exemple les labels (définis dans les règles de configuration), le groupe de l’utilisateur ayant généré l’événement ou le pid du processus. Il est aussi possible d’obtenir certains événements courants comme ceux concernant par exemple les modifications de configuration ou les actions sur fichiers et/ou sockets. Dans ces cas, auditd gère lui-même les cas correspondant au besoin exprimé.

ausearch(8) est un autre outil fourni par auditd offrant des fonctionnalités plus bas niveau. Ses arguments sont très similaires à ceux de aureport mais plutôt que d’afficher des résumés des événements, il les affiche directement tels qu’ils sont contenus dans les journaux. Il s’agit donc en un sens d’un “grep contextuel intelligent” pour auditd.

Il est également possible de directement manipuler les journaux avec les outils présents sur le système, ce qui peut être plus rapide (selon la familiarité de l’utilisateur) pour explorer les événements sans savoir exactement ce que l’on cherche ou pour au contraire trouver quelque chose de particulier qu’on sait pouvoir facilement trouver avec grep ou less.

Finalement, journalctl permet aussi d’accéder aux journaux d’auditd, bien que ce ne soit pas une façon recommandée de les traiter.

auditd permet de tracer les utilisateurs responsables des commandes journalisés. En particulier, on peut savoir qui a exécuté une commande avec sudo. Cependant, on perd l’information d’utilisateur lorsque celui-ci devient root avec su.

On peut continuer à le traçant en utilisant les identifiants de session que conserve auditd. Ainsi, les enregistrements SYSCALL contiennent un champ ses. À partir de celui-ci, il suffit de remonter dans les journaux et de trouver l’appel (par exemple) à su ayant le même identifiant de session et qui comportera l’UID original de l’utilisateur.

  • technique/old/auditd/howto.txt
  • de qduchemi