LINUX:SELinux-Méthode de première mise en route

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

retour à SELinux


But

Je ne conseille pas de suivre aveuglément les conseils données par Cockpit ou les messages du service "setroubleshootd.service". Je présente ici l'approche que j'ai utilisée. Au premier démarrage de SELinux, on est submergé d'alertes. On va procéder par débroussaillage successif.


Préliminaire

Il faut procéder à une configuration préliminaire:

  • Désactiver l'envoi de messages électroniques du service "setroubleshootd.service" en mettant en commentaire (ligne préfixée par le caractère "#") les adresses email de sa configuration
  • Placer SELinux en mode permissif
  • Redémarrer de système avec l'option de relabélisation du "Context" de tous les fichiers du système (voir le paragraphe sur la Première activation)
  • Lors de la découverte de SELinux, travailler sur un système si possible non en production afin de gêner un minimum de personnes.


Fcontext

J'ai l'habitude de placer les données d'applications dans un répertoire personnalisé. Cette configuration me permet de faciliter les sauvegardes, de ne pas être limité par l'espace disque et de pouvoir les déplacer comme on veut. Le fait de ne pas les laisser à l'emplacement défini par défaut, habituellement sous l'arborescence "/var", engendre une foule d'alertes dès que les applications concernées veulent accéder aux données. Il faut bien sûr connaitre son système et les changements auxquels on a procédé.


Voici un premier exemple:

Normalement, les sites Web utilisés par le service Httpd, se trouvent sous l'arborescence "/var/www" qui a le Context de Type "httpd_sys_content_t".

On peut le vérifier par la commande:

matchpathcon /var/www

qui donne:


/var/www        system_u:object_r:httpd_sys_content_t:s0

ou par

ls -Z1 /var | grep www

qui donne:


system_u:object_r:httpd_sys_content_t:s0 www


Pour ma part, je les place sous le répertoire "/application/web". Il faut donc que je procède à une relabélisation de cet espace.

On exécute les deux commandes suivantes:

semanage fcontext -a -t httpd_sys_content_t '/application/web(/.*)?'
restorecon -RFv /application/web/

De même, les images et autres documents par exemple PDF, prennent beaucoup de place. Nous les avons placés dans un espace à part "/disk1/documents" qu'il faut aussi adapter:

semanage fcontext -a -t httpd_sys_content_t '/disk1/documents(/.*)?'
restorecon -RFv /disk1/documents/


Autres exemples:

  • L'application GeneWeb comporte deux exécutables lancés sous le contexte de Httpd. On a procédé à la relabélisation suivante:
semanage fcontext -a -t httpd_exec_t '/application/web/geneweb/gw/gwd'
semanage fcontext -a -t httpd_exec_t '/application/web/geneweb/gw/gwsetup'
restorecon -RFv /application/web/geneweb/gw/
  • On utilise BackupPC pour nos sauvegardes. L'espace de sauvegarde se trouve par défaut sous l'arborescence "/var/lib/BackupPC" avec un Context de Type "httpd_var_lib_t". Or on le place dans le répertoire "/disk2/backuppc". On adapte:
semanage fcontext -a -t httpd_var_lib_t '/disk2/backuppc(/.*)?'
restorecon -RFv /disk2/backuppc/
  • On utilise le gestionnaire de base de données MariaDB (équivalent à MySQL). La base de données est placée par défaut dans le répertoire "/var/lib/mysql" avec un Context de Type "mysqld_db_t". Or on la place dans le répertoire "/application/mysql" et le dump dans le répertoire "/application/mysql.dump". On adapte:
semanage fcontext -a -t mysqld_db_t '/application/mysql(/.*)?'
restorecon -RFv /application/mysql/
semanage fcontext -a -t mysqld_db_t '/application/mysql.dump(/.*)?'
restorecon -RFv /application/mysql.dump/
  • Pour le PostOffice au format "maildir" géré par Dovecot, les boîtes de messages électroniques des utilisateurs sur le serveur sont placées sous le répertoire "/application/vmail". En analysant les Fcontext repris dans les fichiers du répertoire "/etc/selinux//targeted/contexts/files", spécialement le fichier "file_contexts.homedirs", on recherche les répertoires contenant "maildir" ou "Maildir", on y trouve systématiquement le Context de Type "mail_home_rw_t". On l'adapte en conséquence:
semanage fcontext -a -t mail_home_rw_t '/application/vmail(/.*)?'
restorecon -RFv /application/vmail/
  • Nous avons développé plusieurs scripts qui sont exploités par le service "crond.service" au travers du fichier "/etc/crontab". Ils utilisent des fichiers de données locaux. Nous les avons regroupés sous le répertoire "/application/cron", un répertoire par application. Je n'avais de piste précise; après exploration, j'ai opté pour le Type "system_cron_spool_t" qui est celui du répertoire "/etc/cron.d"; un autre est peut-être plus adapté:
semanage fcontext -a -t system_cron_spool_t '/application/cron(/.*)?'
restorecon -RFv /application/cron/
  • Pour l'utilisation de Nagios, nous avons développé quelques scripts qui sont utilisés par le service "nrpe.service". Nous les avons placés sous le répertoire "/application/nrpe". Or les "plugins" de Nagios se situent dans le répertoire "/usr/lib64/nagios/plugins" qui ont le Context de Type "nagios_unconfined_plugin_exec_t". On s'adapte:
semanage fcontext -a -t nagios_unconfined_plugin_exec_t '/application/nrpe(/.*)?'
restorecon -Rv /application/nrpe/


Maintenant que le gros des problèmes sont résolus, on nettoie toutes les alertes reprises dans l'interface de SELINUX sous Cockpit avant de passer à la suite. Et on peut réactiver d'envoi de mails via le service "setroubleshootd.service".


Boolean

Cet aspect est a considérer en parallèle avec le suivant car il peut résoudre de nombreux problèmes que l'on résoudrait grâce à une foule de règles.

La seconde étape consiste à analyser l'impact des différents Boolean. Nous activons ceux qui nous semblent pertinents. Par après, quand tous les problèmes sont résolus, peut tester leur nécessité en les désactivant. Il est encore temps, dans le cas contraire, de les réactiver. Cette action est immédiat. De même si certains Boolean sont activés et que manifestement on n'utilise pas cette fonctionnalité, on peut les désactiver.


Voici quelques exemples désactivés:

  • virt_sandbox_use_all_caps: Non utilisé
  • virt_use_nfs: NFS n'est pas utilisé
  • httpd_can_network_connect: Au départ je l'ai activé mais dans les faits, le daemon HTTPD n'effectuait aucune connexion TCP (HTTP) vers d'autres machines
  • mysql_connect_any: De même, il a été activé mais au final, il s'est avéré inutile. Le daemon MariaDB n'a pas besoin d'effectuer des connexions TCP.
  • mysql_connect_http: De même, il a été activé mais au final, il s'est avéré inutile. Le daemon MariaDB n'a pas besoin d'effectuer des connexions TCP (HTTP).

Il y en a bien d'autres qu'il faut désactiver et qui le sont par défaut.

Voici quelques exemples que j'ai dû activer:

  • samba_enable_home_dirs: J'utilise Samba et la facilité des espaces Home des utilisateurs.
  • use_samba_home_dirs: Idem que le précédent
  • samba_export_all_ro: Nécessaire pour lire les fichiers via Samba
  • samba_export_all_rw: Nécessaire pour écrire dans les fichiers via Samba
  • nis_enabled: J'utilise le fichier "/etc/hosts" en plus du DNS pour la résolution de nom de machines. Il s'est avéré nécessaire.
  • domain_can_mmap_files: Ce Boolean semble utile car il revient fréquemment dans les conseils prodigués lors de la création de modules. Je ne l'ai pas activé par sécurité.
  • rsync_export_all_ro et rsync_full_access: J'utilise Rsyncd au travers de Backuppc et des sauvegardes.
  • httpd_unified: Il permet de se simplifier la vie au niveau des types de permissions d'accès de chaque fichier des sites Web.
  • httpd_can_sendmail: Nombre de sites ont possède la possibilité d'envoyer des mails.


Module

Nous arrivons à la dernière phase.

On passe en revue chaque application ou partie majeure en revue à tour de rôle. On traite seulement des alertes déclenchées en regard de cette application. Quand toutes les alertes d'une application ont été résolue via la création et l'installation d'un module spécifique, on passe à l'application suivante.

Pour y arriver, on suit la méthode exposée dans l'article sur Création de sources; on compile et ensuite on installe le module.

Au final, on n'a plus d'alerte courantes. Mais plusieurs applications ne s'exécutent que périodiquement. C'est le cas des applications s'activant via le service "crond.service" tel "logwatch" et aussi des services de Systemd du "timers.target" tel "logrotate". Il faut donc laisser le système tourner quelques jours, au moins une semaine et repérer les alertes éventuelles. Certaines applications ne sont lancées que tous les mois ou plus. Dans la mesure du possible, on essaie de raccourcir cet intervalle à une journée. On le remet à sa valeur d'origine par après.


Même pour un système qui semble stable depuis longtemps en mode SELinux actif, une alerte de temps en temps arrive suite par exemple à une mise à jour d'un logiciel ou suite à une action rare. On la règle de la même façon.


Activation

Quand votre système ne présente plus d'alerte après une semaine ou plus, on peut passer à la phase d'activation de SELinux. On modifie le fichier "/etc/selinux/config"; on y remplace la valeur "permissive" par "enforcing" pour l'option "SELINUX". On peut ensuite exécuter la commande:

setenforce 1

si on ne veut pas redémarrer la machine.


Vérification

Lors des trois derniers points, il faut vérifier en profondeur que chaque application fonctionne correctement.

Il faut noter qu'il existe des règles qui annulent l'apparition d'alertes: "dontaudit". Dans ce cas, elles se manifestent indirectement par des blocages sans alerte pour l'application concernée quand le système SELinux est activé en mode renforcé. D'où la nécessité de vérifier leur bon fonctionnement après activation de SELinux. Ceci m'est arrivé lors de la création d'un module SELinux pour une application personnelle mais jamais pour les applications provenant de paquets inclus dans la distribution.


Une solution de dernier recours consiste à désactiver globalement ces règles "dontaudit" par la commande:

semodule -DB


Mais ATTENTION, il faut prendre quelques précautions. En effet, dès ce moment, vous serez submergé d'alertes.

  • Avant de passer à cette état, désactivez l'envoi de mail via le service "setroubleshootd.service". Si vous ne le faites pas vous recevrez en peu de temps des milliers de mails. L'arrêt du serveur de messagerie ne sert à rien; ce problème ne sera que reporté à plus tard.
  • Travaillez si possible sur une machine de test ou une machine n'ayant que peu d'impact pour l'ensemble de votre réseau et sur vos utilisateurs.
  • Lancez cette commande ("semodule -DB") et après quelques minutes revenez à l'état d'origine ("semodule -B")
  • Analysez les alertes générées pendant ce laps de temps et essayer de repérer les services souvent concernés.
  • Arrêtez temporairement ces services s'ils ne concernent pas le blocage. Le nombre d'alertes en sera fortement diminué.

A ce stade, vous pouvez déactiver globalement les clauses de "dontaudit" et travailler sur votre application ayant des blocages à votre aise. Le nombre de messages d'alertes sera nettement plus réduit et vous aurez facile pour repérer les alertes qui vous intéressent et donc pour résoudre votre problème.


Le problème résolu, revenez à l'état normal avec la commande:

semodule -B

Et revenez à votre configuration normale.


Exemples

Voici quelques exemples de fichiers de ".te". Ils sont souvent très réduits ou à la structure répétitive.


Auditd

Suite à une mise à jour du logiciel Audit, le service "auditd.service" ne pouvait plus démarrer.


module my-auditd 1.0;
 
require {
       type rpm_script_t;
       type auditd_t;
       class dir { read search };
}
#============= auditd_t ==============
allow auditd_t rpm_script_t:dir { read search };


Logrotate et Wazuh

J'avais ajouté la rotation des journaux "active-responses" de Wazuh via le service Logrotate.


module my-logrotate-wazuh 1.0;
 
require {
       type var_t;
       type logrotate_t;
       class file { create getattr open read rename setattr unlink write };
       class dir { add_name read remove_name write };
}
#============= logrotate_t ==============
allow logrotate_t var_t:dir { add_name read remove_name write };
allow logrotate_t var_t:file { create open read rename setattr write getattr unlink };


SETroubleshootd

Si on demande au service "setroubleshootd.service" d'envoyer par mail les alertes SELinux, toute une autre série d'alertes sont générées.


module my-setroubleshootd 1.0;
 
require {
       type setroubleshootd_t;
       type sendmail_exec_t;
       type postfix_postdrop_exec_t;
       type postfix_etc_t;
       type postfix_public_t;
       type postfix_master_t;
       type postfix_spool_t;
       class file { execute execute_no_trans };
       class file { create map open read rename setattr write };
       class dir { add_name remove_name write };
       class process setrlimit;
       class sock_file write;
       class unix_stream_socket connectto;
}
#============= setroubleshootd_t ==============
allow setroubleshootd_t sendmail_exec_t:file { execute execute_no_trans };
allow setroubleshootd_t sendmail_exec_t:file map;
allow setroubleshootd_t postfix_etc_t:file { open read };
allow setroubleshootd_t postfix_postdrop_exec_t:file { execute execute_no_trans };
allow setroubleshootd_t postfix_postdrop_exec_t:file map;
allow setroubleshootd_t postfix_master_t:unix_stream_socket connectto;
allow setroubleshootd_t postfix_public_t:sock_file write;
allow setroubleshootd_t postfix_spool_t:dir { add_name remove_name write };
allow setroubleshootd_t postfix_spool_t:file { create open read rename setattr write };
allow setroubleshootd_t self:process setrlimit;


Nagios et Plugins

Nagios a la possibilité d'exécuter directement les plugins sans passer par le service Nrpe.


module my-sh-nagios 1.0;
 
require {
       type nagios_exec_t;
       type httpd_t;
       class file { open read };
}
#============= httpd_t ==============
allow httpd_t nagios_exec_t:file { open read };


NRPE

Il concerne le service Nrpe pour pouvoir écrire son fichier journal dans le répertoire "/var/log/nrpe".


module my-nrpe 1.0;
 
require {
       type var_log_t;
       type nrpe_t;
       class dir { add_name write };
       class file { create open read };
}
#============= nrpe_t ==============
allow nrpe_t var_log_t:dir { add_name write };
allow nrpe_t var_log_t:file { create open read };


Cron

Depuis longtemps j'avais pris l'habitude de transmettre des mails personnalisés dans le cas d'alertes générées par le Cron mais ce n'est pas prévu car maintenant ce qui est envoyé en sortie, est transmis par mail.


module my-cron-sendmail 1.0;
 
require {
       type system_cron_spool_t;
       type system_mail_t;
       class file { write append };
}
#============= system_mail_t ==============
allow system_mail_t system_cron_spool_t:file { write append };





retour à SELinux