URL: https://linuxfr.org/news/exploiter-inotify-c-est-simple Title: Exploiter inotify, c’est simple Authors: Denis Dordoigne Davy Defaud, palm123, NeoX, Bruno Michel, ZeroHeure et Benoît Sibaud Date: 2014年11月23日T12:23:03+01:00 License: CC By-SA Tags: modification, notifications, supervision, action, système_de_fichiers, firefox et surveillance Score: 93 Intégré à partir de [Linux 2.6.13](https://linuxfr.org/news/sortie-du-noyau-linux-2613), le mécanisme [[inotify]] permet de mettre en place des actions associées à l’évolution de l’état du système de fichiers. À l’occasion des 10 ans de ce projet, cette dépêche va vous donner des pistes pour exploiter ce mécanisme qui pourra vous simplifier bien des tâches d’administration. ---- [Page Wikipédia inotify](http://fr.wikipedia.org/wiki/Inotify) [Documentation de incron](http://inotify.aiken.cz/?section=incron&page=doc&lang=en) [Projet lsyncd](https://code.google.com/p/lsyncd/) [Projet iwatch](http://iwatch.sourceforge.net/index.html) [inotify-tools](https://github.com/rvoicilas/inotify-tools/wiki/) ---- #Description du fonctionnement Le mécanisme _inotify_ permet de positionner un _watch descriptor_ sur un fichier, qui enverra des notifications au système lorsque des événements affecteront le fichier suivi. Pour rappel, dans le monde UNIX, un fichier peut aussi bien représenter un fichier simple qu’un répertoire, un périphérique, un lien, etc. Les principaux événements qui peuvent être suivis sont : - **IN_ACCESS** : le fichier est accédé en lecture ; - **IN_MODIFY** : le fichier est modifié ; - **IN_ATTRIB** : les [attributs](http://en.wikipedia.org/wiki/File_attribute) du fichiers sont modifiés ; - **IN_OPEN** : le fichier est ouvert ; - **IN_CLOSE_WRITE** : le fichier est fermé après avoir été ouvert en écriture ; - **IN_CLOSE_NOWRITE** : le fichier est fermé après avoir été ouvert en lecture ; - **IN_MOVED_FROM** / **IN_MOVED_TO** : le fichier a été déplacé ou renommé ; - **IN_DELETE_SELF** : le fichier a été supprimé ; - **IN_DELETE** : un fichier a été supprimé dans le répertoire surveillé ; - **IN_CREATE** : un fichier a été créé dans le répertoire surveillé. Dans le mécanisme standard de inotify, il n’y a pas de notion de récursivité : un événement dans `/home/georgette/.ssh` ne sera pas remonté par un _watch descriptor_ surveillant `/home` ; cependant, les outils implémentant _inotify_ gèrent en général eux‐mêmes cette récursivité (en positionnant des _watch descriptors_ dans toute l’arborescence, et en ajoutant dynamiquement des _watch descriptors_ à chaque fois qu’un événement _IN_CREATE_ survient). # Incron : mieux que des tâches planifiées, des tâches instantanées # ## Principe ## Les administrateurs de systèmes GNU/Linux connaissent tous le gestionnaire de tâche planifié _[[cron]]_, qui permet de lancer des tâches selon une planification cyclique (par exemple tous les dimanches à 14 h) définie dans une _crontab_, c’est‐à‐dire un fichier indiquant la tâche à exécuter et l’heure à laquelle elle doit être exécutée. Le logiciel _incron_ reprend ce principe, mais, plutôt que de se baser sur des événements temporels, il se base sur des événements _inotify_. ## Installation ## Le logiciel _incron_ est empaqueté par la plupart des distributions, il suffit donc de l’installer à l’aide de votre gestionnaire de paquets préféré : ```sh # pour Debian, Ubuntu, etc. $ apt-get install incron # pour Red Hat, CentOS etc. $ yum install incron ``` Une fois installé, il faut insérer les utilisateurs autorisés à utiliser _incron_ dans le fichier `/etc/incron.allow` : ```sh $ cat /etc/incron.allow httpadm nagios georgette ``` ## Utilisation ## Pour créer une tâche dans la « _incrontab_ », lancer la commande `incrontab -e`, et y déclarer l’événement et la commande associée. Par exemple, on peut demander à lancer automatiquement la commande `postalias` lorsque le fichier `/etc/aliases` est modifié : /etc/aliases IN_MODIFY postalias _Note : incron fait partie des logiciels qui n’implémentent pas la récursivité._ # lsyncd : vers un système de fichiers distribué # ## Principe ## Mettre en place un [[système de fichiers distribué]] peut s’avérer compliqué, puisque cela implique en général une phase de migration des données existantes dans un nouveau système de fichiers qu’il faut avoir installé sur de nouveaux disques, voire de nouveaux serveurs. Le logiciel _lsyncd_ permet de simuler un système de fichiers distribué en synchronisant simplement les fichiers d’une arborescence, en utilisant _[[rsync]]_. L’avantage de _lsyncd_ est que la synchronisation est faite à chaque modification, et dès que celle‐ci intervient : cela simule presque parfaitement un système de fichiers distribué synchrone ## Mise en place ## _lsyncd_ est empaqueté pour la plupart des distributions GNU/Linux, il suffit donc de l’installer via votre gestionnaire de paquets habituel. La configuration se fait à l’aide de scripts en langage [[Lua]]. Si vous n’êtes pas habitué à utiliser ce langage, vous pouvez suivre les exemples donnés dans la documentation. Ici, on va synchroniser `/var/www/mon_site` : ```sh # cat /etc/lsyncd.conf.lua -- configuration de lsyncd settings{ statusFile = "/tmp/lsyncd.stat", statusInterval = 1, insist = 1, inotifyMode = "CloseWrite or Modify", } -- liste des serveurs vers lesquels synchroniser targetlist = { "web01::mon_site", "web02::mon_site", "web03::mon_site" } -- configuration de la synchronisation for _, server in ipairs(targetlist) do sync{ default.rsync, source="/var/www/mon_site", target=server } end ``` Pour que la synchronisation fonctionne, il faudra bien évidemment configurer _[[rsync]]_ sur les serveurs web01, web02 et web03 pour que la destination __mon_site__ pointe vers `/var/www/mon_site`. # iwatch : ceci n’est pas une montre # Le logiciel _iwatch_ permet de déclencher une action suite à un événement _inotify_. Il s’agit d’un logiciel destiné à l’origine à la surveillance, on s’en sert donc habituellement pour envoyer un courriel lorsqu’un fichier est modifié. Par exemple, pour prévenir Georgette de chaque modification de `/etc/shadow` : iwatch -m georgette@example.com /etc/shadow Contrairement à _incron_, _iwatch_ gère la récursivité (avec l’option `-r`) et les exclusions (avec l’option `-x` pour un chemin, et `-X` pour une [[expression rationnelle]]), par exemple pour lancer l’antivirus pour chaque modification dans `/var/www/upload` (ou un de ses sous‐répertoires) sauf des fichiers `.png` : iwatch -r -X '\.png$' -c "clamscan %f" /var/www/upload Ici, _%f_ pointe vers le fichier ayant déclenché l’événement. # inotify-tools : mettez de l’inotify dans votre ligne de commande # Les _inotify-tools_ permettent de faire des appels _inotify_ directement en ligne de commande, quel que soit le shell utilisé. ## inotifywait ## La première commande fournie est _inotifywait_, qui permet d’attendre un événement avant de continuer une exécution, par exemple pour éviter qu’une commande ayant un fichier en prérequis tombe en erreur : inotifywait -e close_write /var/run/jboss.pid && supervision_jboss.sh L’option `-t` (_timeout_) permet de mettre en place un délai d’expiration en secondes pour, par exemple, sortir en erreur si un événement est trop long à arriver : sauvegarde.sh & ; inotifywait -e close_write -t 10000 rapport_sauvegarde || killall sauvegarde.sh ## inotifywatch ## La commande _inotifywatch_ permet de faire un rapport d’activité des événements concernant les répertoires surveillés : ```sh $ inotifywatch /var/cache/apt/archives & [1] 18607 root@kamoulix:~# Establishing watches... Finished establishing watches, now collecting statistics. root@kamoulix:~# apt-get autoclean root@kamoulix:~# kill %1 total access close_write close_nowrite open delete filename 1919 7 1 2 3 1906 /var/cache/apt/archives/ ``` Par défaut, _inotifywatch_ s’arrêtera après avoir un reçu un signal d’interruption. On peut aussi le faire tourner juste pour un certain nombre de secondes avec l'option `-t`, par exemple pour voir l’activité du répertoire _home_ de l’utilisateur _georgette_ pendant une minute : ```sh $ inotifywatch -r /home/georgette/ -t 20 Establishing watches... Finished establishing watches, now collecting statistics. total access modify close_write close_nowrite open moved_from moved_to create filename 16 3 3 2 0 2 2 2 2 /home/georgette/.mozilla/firefox/e3lq4lm3.default/ 13 11 0 0 1 1 0 0 0 /home/georgette/.cache/myapp/mycache/ ``` # Codez avec inotify # Les principaux langages de programmation proposent une bibliothèque pour travailler avec _inotify_, en voici une liste non exhaustive : - en Perl : [_Linux::Inotify_](http://search.cpan.org/~twerner/Linux-Inotify-0.05/lib/Linux/Inotify.pm), [Linux::Inotify2](http://search.cpan.org/~mlehmann/Linux-Inotify2-1.22/Inotify2.pm), [POEx::Inotify](http://search.cpan.org/~gwyn/POEx-Inotify-0.0201/lib/POEx/Inotify.pm), [etc.](http://search.cpan.org/search?query=inotify&mode=module) ; - en Python : [_pyinotify_](https://github.com/seb-m/pyinotify), [inotifyx](https://launchpad.net/inotifyx/), [pollinotify](http://pythonhosted.org//pollinotify/), [etc.](https://pypi.python.org/pypi?%3Aaction=search&term=inotify&submit=search) ; - en Ruby : [_rb-inotify_](https://github.com/nex3/rb-inotify), [inotify](https://rubygems.org/gems/inotify), [ruby-inotify](http://dinhe.net/~aredridel/projects/ruby/ruby-inotify), [etc.](https://rubygems.org/search?utf8=%E2%9C%93&query=inotify) ; - en PHP : l’extension PECL [_inotify_](http://php.net/manual/en/book.inotify.php) ; - en Java : [_JNotify_](http://jnotify.sourceforge.net/) pour faire simple, ou [développer sa propre classe](http://markusjais.com/file-system-events-with-java-7/).