LINUX:SELinux-Alertes et Journaux

De WIKI sur Linux (ADB)
Aller à la navigation Aller à la recherche

retour à SELinux


But

Quand une règle est enfreinte, outre que l'accès demandé est refusé, une alerte est déclenchée et un message est envoyé aux journaux. Ce message arrive aux services "auditd.service" et "rsyslog.service". Lorsque cet événement arrive dans le fichier journal d'audit, le service "setroubleshootd.service" s’enclenche automatiquement. D'où l'importance d'activer ces deux services. Ce dernier service sera exploité par l'application Cockpit.


Journaux

Le service "auditd.service" écrit ses messages dans le fichier "/var/log/audit/audit.log" et le service "rsyslog.service" dans le fichier "/var/log/messages".

Voici un extrait de trois messages provenant du fichier "audit.log":


Jul 29 16:31:59 serverdb audit[16758]: AVC avc:  denied  { watch } for  pid=16758 comm="fail2ban-server" path="/var/log/mariadb/mariadb.log" dev="dm-3" ino=1700802 scontext=system_u:system_r:fail2ban_t:s0 tcontext=system_u:object_r:mysqld_log_t:s0 tclass=file permissive=0
Dec 14 16:05:00 serverdb audit[3991714]: AVC avc:  denied  { write } for  pid=3991714 comm="php-fpm" name="www-error.log" dev="dm-4" ino=785036 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_log_t:s0 tclass=file permissive=0
Aug  6 15:59:10 serverdb audit[731396]: AVC avc:  denied  { open } for  pid=731396 comm="BackupPC_Admin" path="/sauvegarde/backuppc/pc/serverbck1.home.dom/LOCK" dev="dm-3" ino=268435555 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:default_t:s0 tclass=file permissive=0

On les repère par la chaine "AVC avc: denied".


Voici un extrait équivalent provenant du fichier "messages":


type=AVC msg=audit(1690544030.649:142): avc:  denied  { watch } for  pid=1020 comm="fail2ban-server" path="/var/log/mariadb/mariadb.log" dev="dm-4" ino=1701672 scontext=system_u:system_r:fail2ban_t:s0 tcontext=system_u:object_r:mysqld_log_t:s0 tclass=file permissive=0
type=AVC msg=audit(1702566300.939:82055): avc:  denied  { write } for  pid=3991714 comm="php-fpm" name="www-error.log" dev="dm-4" ino=785036 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_log_t:s0 tclass=file permissive=0
type=AVC msg=audit(1691485897.697:31328): avc:  denied  { open } for  pid=1339363 comm="BackupPC_Admin" path="/sauvegarde/backuppc/pc/serverbck1.home.dom/LOCK" dev="dm-3" ino=268435555 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:default_t:s0 tclass=file permissive=0

On les repère par la chaîne en début "type=AVC" et la chaîne "avc: denied" un peu plus loin.


Ce message comporte diverses informations sous forme de variables et de sa valeur séparés par le signe égal. En analysant leur contenu, on peut en déduire d'où provient le problème de blocage. Souvenons-nous que sous Unix, tout est représenté au travers de fichiers.

Voici une description de quelques unes de ces variables:

  • pid : le n° du programme lancé
  • comm : le nom du programme concerné
  • path ou name : le chemin ou le nom du fichier concerné qui est utilisé par ce programme
  • scontext : le contexte du fichier source effectuant l'appel au fichier cible
  • tcontext : le contexte du fichier cible
  • tclass : le type d'accès au fichier demandé
  • {...} : la méthode d'accès au fichier demandé (en début de liste)

Par exemple pour la première ligne, le programme serveur Fail2Ban selon le type Selinux "fail2ban_t" essaye d'accéder au fichier "/var/log/mariadb/mariadb.log" ayant le type Selinux "mysqld_log_t"; il veut y accéder selon le type d'accès "file" grâce à la méthode "watch" qui est refusée (denied). Pour régler ce problème, il faudra ajouter par exemple une règle permettant cet accès ou corriger l'utilisation du programme.

Mais toute alerte peut être le symptôme d'une attaque.


Commandes de lignes

Il existe plusieurs commandes de lignes permettant de visionner ces alertes, telles "sealert" ou 'ausearch".

Nous n'allons pas les décrire car nous n'avons pas eu besoin de les utiliser directement. Nous les utiliserons indirectement au travers d'autres outils.


Cockpit

Nous avons ajouté un plugin pour SeLinux dans l'outil Cockpit (voir l'article sur Cockpit). Quand on y rentre, on aperçoit une nouvelle entrée SELinux dans le menu. La partie supérieure reprend les modifications apportées au paramétrage de SELinux et la partie inférieure les nouvelles alertes interceptées par le service "setroubleshootd.service".

Chaque alerte comprend deux onglets: un pour le descriptif de l'alerte et des conseils pour le résoudre et le second qui affiche le message repris dans le journal d'audit.

LINUX:Selinux.cockpit1.png


LINUX:Selinux.cockpit2.png

Remarque: Ne prenez pas les conseils de résolution des problèmes comme argent content. Nous présenterons par la suite une approche personnelle.


Configuration du service SeTroubleshootd

La configuration se trouve dans Le fichier "/etc/setroubleshoot/setroubleshoot.conf".

Nous avons modifié une des options afin de recevoir les alertes par mail:


use_sendmail = True

En complément, il faut ajouter l'adresse Email de réception dans le fichier "/var/lib/setroubleshoot/email_alert_recipients":


adebast@home.dom     filter_type=never

Il existe divers filtres; nous avons choisi celui qui nous renvoie tous les messages.


Voici les messages correspondants aux deux alertes reprises dans l'interface de Cockpit.

LINUX:Selinux.mail1.png


LINUX:Selinux.mail2.png

Remarques:

  • N'activez cette option que lorsque vous aurez résolu la majorité de vos problèmes de mise en route sinon vous serez submergés par les messages. Ne le faites pas également si vous désactivez le mode "DontAudit" (commande: "semodule -DB").
  • Il m'est arrivé une fois que ce service était en erreur. Il suffit de l'arrêter; il redémarrera de lui même lors de l'alerte suivante:
systemctl stop setroubleshootd.service
  • On peut remarquer le fichier "/var/lib/setroubleshoot/setroubleshoot_database.xml" qui s'amende de lui-même. Il est possible d'en nettoyer le contenu ou de l'effacer; il se recréera de lui-même lors du démarrage suivant du service. Il contient les informations sur les alertes retenues. Si vous effectuez un nettoyage via l'interface de Cockpit, ce fichier se nettoie de lui-même.


Script

Autre alternative, on peut créer un script qui extrait les nouvelles alertes des journaux d'audit ("/var/log/audit/audit.log") et des messages ("/var/log/messages") et de les envoyer par messagerie.


Cette approche présente d'autres avantages:

  • Elle peut être exécutée à la demande dans le cas où on provoque une alerte; cet extrait me sert à créer un module spécifique comme on le verra dans un article suivant.
  • Il m'a permis de me rendre compte que le service "setroubleshootd.service" se filtrait de toute une série d'alertes qu'il provoquait lui-même. Ces alertes étaient liées à l'envoi de mails.
  • Il est arrivé, suite à une mise à jour, que le service "auditd.service" ne pouvait démarrer suite à un blocage SELinux. Dans ce cas, le fichier "auditd.service" n'était plus alimenté et donc le service "setroubleshootd.service" ne se déclenchait pas. C'est en extrayant les alertes du fichier "/var/log/messages" grâce à ce script que j'ai pu créer un module correctif. J'ai un autre script qui m'avait averti que le service "auditd.service" n'était pas démarré.


Voici un script qui peut effectuer cette tâche que l'on nommera "avc.bat" et placé dans le répertoire "/cron/selinux":


#!/bin/bash
# ***************************************************************************
# A adapter selon votre configuration
# Répertoire de travail
CHEMIN="/cron/selinux"
# ***************************************************************************
cd $CHEMIN
# Isolation des alertes de l'audit
/usr/bin/mv -f avc.audit.log avc.audit.archi.log
/usr/bin/grep "^type=AVC " /var/log/audit/audit.log > avc.audit.log
/usr/bin/sort avc.messages.log > avc.messages.sort.log
/usr/bin/sort avc.messages.archi.log > avc.messages.archi.sort.log
/usr/bin/comm -23 avc.messages.sort.log avc.messages.archi.sort.log > avc.messages.23
/usr/bin/rm -f avc.messages.sort.log avc.messages.archi.sort.log
# Isolation des alertes et des messages
/usr/bin/mv -f avc.messages.log avc.messages.archi.log
/usr/bin/grep " AVC avc:  denied " /var/log/messages > avc.messages.log
/usr/bin/comm -23 avc.messages.log avc.messages.archi.log > avc.messages.23
# Dénombrement des alertes et des messages
NBSA=`/usr/bin/wc -l avc.audit.23    | /usr/bin/awk '{printf("%s",$1)}'`
NBSM=`/usr/bin/wc -l avc.messages.23 | /usr/bin/awk '{printf("%s",$1)}'`
# En cas d'alertes, on envoie un message
if [ "$NBSA" != "0" ]
then
 TEST=1
 /usr/bin/cp -f avc.audit.23 alerte.txt
else
 if [ "$NBSM" != "0" ]
 then
  TEST=1
  /usr/bin/cp -f avc.messages.23 alerte.txt
 fi
fi
# En cas d'alertes, on envoie un message
if [ "$TEST" = "1" ]
then
  echo "Subject: SELINUX - Problèmes d'accès" >  ${CHEMIN}/sysmail.log
  echo -n "Serveur - "                        >> ${CHEMIN}/sysmail.log
  /usr/bin/hostname                           >> ${CHEMIN}/sysmail.log
  echo " "                                    >> ${CHEMIN}/sysmail.log
  date                                        >> ${CHEMIN}/sysmail.log
  echo " "                                    >> ${CHEMIN}/sysmail.log
  echo "Liste AVC:"                           >> ${CHEMIN}/sysmail.log
  /usr/bin/cat alerte.txt                     >> ${CHEMIN}/sysmail.log
  echo " "                                    >> ${CHEMIN}/sysmail.log
  /sbin/sendmail root < ${CHEMIN}/sysmail.log
  /usr/bin/rm -f ${CHEMIN}/sysmail.log
  /usr/bin/rm -f ${CHEMIN}/alerte.txt
fi


On fait appel à ce script dans le Cron de Linux. On ajoute les lignes suivantes dans le fichier "/etc/crontab":


# Sauvegarde mysql
*/5 * * * * root /cron/selinux/avc.bat > /cron/selinux/avc.log

Ici on y fait appel toutes les 5 minutes.




retour à SELinux