Utiliser auditd sur Mac OS X et FreeBSD – 2

Cet article est la suite de Utiliser auditd sur Mac OS X et FreeBSD - 1

Configuration : quid des utilisateurs comme www ?

J'expliquais précédemment que le système d'audit ne peut suivre un utilisateur que si ce dernier se connecte à la machine (par ssh par exemple), et que quelques soient les ruses utilisées (su, sudo...) c'est toujours l'UID réelle de l'utilisateur qui est suivie.

À cause de cela, il est totalement impossible de traquer des évènements appartenant à des utilisateurs qui ne peuvent pas se connecter au système. Ainsi, une ligne comme celle-ci dans audit_user ne permettra de traquer aucun évènement :

# pour freebsd remplacer _www par www
_www:fc,fd,ex:

Il serait pourtant très intéressant de savoir ce que fait Apache dans votre dos, parfois sous la direction de méchants pirates.
De nos jours, La plupart des serveurs utilisent des protocoles comme l'HTTP qui permettent aux utilisateurs d'accéder aux ressources sans être authentifiés au niveau du système. Les utilisateurs en question n'existent d'ailleurs pas au niveau du système. Néanmoins, les applications web permettent de faire énormément de choses via les langages comme le PHP, y compris d'interagir avec le système, en lançant des commandes, en créant des fichiers, etc.

Si on souhaite qu'auditd puisse contrôler les actions de www, il faut recourir à un artifice. Attention tout de même, ce qui suit est plus proche d'un hack que d'une méthode vraiment propre, et je ne peux pas garantir son fonctionnement correct dans un environnement de production.

En premier lieu il faut installer un programme spécifique, qui va permettre de forcer auditd à suivre les actions pour une UID donnée, sans que l'utilisateur correspondant ait besoin de se connecter à la machine.

curl -LO http://www.freebsd.org/~csjp/setaudit.c
cc -o setaudit -lbsm setaudit.c 

Cela vous donne, si tout se passe bien, le binaire setaudit, que l'on va utiliser sous cette forme :

setaudit -a UID_WWW -m FLAGS /programme/de/lancement/d/apache

Pour suivre les évènements d'exécution de commande sous respectivement FreeBSD et Mac OS X, cela donnera :

setaudit -a www -m ex /usr/local/etc/rc.d/apache22 restart
setaudit -a _www -m ex /usr/sbin/apachectl restart

Ainsi, toutes les commandes lancées par Apache (donc sous l'UID www) sont enregistrées par auditd.
Comme le masque des évènements (les flags de l'argument -m) décrit ce que l'on doit suivre, il est même inutile de renseigner le fichier audit_user.

Pour résumer :

  • Si vous souhaitez que l'audit suive les utilisateurs qui se connectent à la machine, vous pouvez régler les classes d'évènements qui seront soumises à l'audit pour l'ensemble des utilisateurs dans le fichier audit_control, et gérer les cas particuliers dans audit_user.
  • Si vous souhaitez que l'audit suive des UID "interne", pour traquer tout signe de compromission sur un serveur web, un serveur de mail, etc. il faudra recourir à setaudit pour activer l'audit au moment du lancement du service correspondant.
  • Faites attention à la liste de flags que vous choisissez. Le volume des logs d'audit peut grossir très rapidement.

Troisième partie de l'article ->

Publié dans Unix | Mots-clefs : , , , , | Laisser un commentaire

Utiliser auditd sur Mac OS X et FreeBSD – 1

FreeBSD et les versions récentes de Mac OS X sont livrées avec un système d'audit intégré, dérivé du Basic Security Module de SUN, et disponible en logiciel libre sous le nom d'OpenBSM. Ce système d'audit se décompose en deux parties : un ensemble d'appels systèmes dédiés et de librairies d'un côté, et des logiciels "utilisateur" de l'autre. Sauf précision contraire, les explications présentées ici sont valables à la fois pour FreeBSD 7 et 8, et Mac OS X 10.6. Dans cette série d'articles je ne vais aborder que l'aspect "utilisateur" du système d'audit : comment l'activer, comment le configurer, comment exploiter les résultats.
Le système d'audit fourni par OpenBSM a pour but la surveillante des actions des utilisateurs. Un certain nombre d'évènements peuvent être mis sous surveillance, pour tout ou partie des utilisateurs. Quand le système d'exploitation détecte qu'un utilisateur sous surveillance génère un des évènements à surveiller, il averti le démon auditd qui se charge de reporter cet évènement dans un fichier de log. Lire le reste de cet article »

Publié dans Unix | Mots-clefs : , , , , | Laisser un commentaire

Rendre des logs anonymes

En tant qu'administrateur système, je gère un certains nombre de serveurs qui voient passer des données personnelles, soit en tant que simple intermédiaire (passerelle de messagerie) soit en tant que destination finale (connexion/authentification des utilisateurs). Ces serveurs stockent alors sous forme de fichier de log des quantités phénoménales de données nominatives comme des identifiants, des adresses email, des adresses IP. Ces données sont bien évidemment confidentielles, et seule une réquisition judiciaire peut m'autoriser à en divulguer tout ou partie. Je suis moi-même autorisé à les exploiter dans le cadre de mon travail, mais uniquement à des fins statistiques, ou pour vérifier le bon fonctionnement des systèmes.
Il peut pourtant arriver qu'on soit tenté de fournir des extraits de log à certaines personnes. Un jour ce sera pour un prestataire ou un support technique, un autre jour ce sera pour alimenter des chercheurs universitaires qui ont besoin de données brutes. Il est alors impératif de faire disparaître toute trace de données personnelles et nominatives de ces fichiers, tout en s'assurant que le destinataire des fichiers sera en mesure de faire son travail.
Les données doivent être anonymes, mais pour autant elles doivent rester intègres et cohérentes. Par exemple, il faut que l'on puisse suivre le trajet d'un message électronique entre le serveur d'entrée, l'antispam, la passerelle interne, et le serveur de stockage final, sans pour autant connaître ni l'adresse IP du serveur de provenance, ni les adresses email de l'expéditeur et des destinataires.
Après quelques recherches infructueuses, j'ai décidé de créer moi-même le script dont j'ai besoin pour rendre des log de serveurs de mails anonymes.
En Perl, le module IP::Anonymous fourni une méthode cryptographique puissante basée sur Crypto-PAN. Cette méthode permet de rendre les adresse IPv4 anonymes tout en préservant une très grande cohérence des données. Voyez cet exemple avec à gauche les IP réelles, et à droite les IP anonymes obtenues par chiffrement :

192.168.0.15 -> 54.42.0.48
192.168.0.20 -> 54.42.0.43
192.168.1.15 -> 54.42.1.56
192.168.1.20 -> 54.42.1.43

En me basant sur un exemple de script Perl utilisant IP::Anonymous, j'ai créé un script qui permet en plus de rendre anonyme les adresses email, les message-IDs, et les noms de machines. Ainsi, et à condition de rester en IPv4, le script final permet de rendre totalement anonyme des logs Postfix :

   1: #!/usr/bin/perl -wT
   2:
   3: # script brodé à partir d'un exemple
   4: # trouvé en ligne sur le forum CPAN
   5: # http://cpanforum.com/posts/1304
   6:
   7: # à utiliser sous la forme :
   8: # logs_anonymes.pl fichier.log > sortie_anonyme.log
   9:
  10: use strict;
  11: $|=1;
  12:
  13: use IP::Anonymous;
  14: use Digest::MD5;
  15:
  16: # 32 integers entre 0 et 255 (jot -r 32 0 255)
  17: my @key = (135,229,13,26,29,84,46,37,231,95,211,
  18:            196,243,11,87,5,23,217,173,214,66,241,
  19:            164,67,132,149,161,151,114,137,238,75);
  20:
  21: my $obj = new IP::Anonymous(@key);
  22: my $md5 = Digest::MD5->new;
  23:
  24: # seed pour le md5
  25: my $seed = '766326241f69b1244792587f556d02b8';
  26:
  27: while(defined(my $line=<>)) {
  28:     chomp $line;
  29:     # les IP
  30:     if($line =~ /\d{1,3}(?:\.\d{1,3}){3}/) {
  31:         $line =~
  32:             s/(\d{1,3}(?:\.\d{1,3}){3})/$obj->anonymize($1)/eg;
  33:     }
  34:     # les adresses email et messageID
  35:     if($line =~ /[=< ][^@ ]*@/) {
  36:         $line =~
  37:             s/([=< ])([^@=< ]*@)/$1.$md5->add($seed)->add($2)->hexdigest."@"/eg;
  38:     }
  39:     # les hostnames
  40:     if($line =~ /([=< @])(([a-zA-Z0-9]***TRONQUÉ***|ZW)/i ) {
  41:         $line =~
  42:             s/([=< @])((?:(?:[a-zA-Z0-9]***TRONQUÉ***|ZW)/$1.$md5->add($seed)->add($2)->hexdigest.".".$3.".".$4/egi;
  43:     }
  44:     # suppression des HELO
  45:     if($line =~ /(helo=<[^>]*>)/i ) {
  46:         $line =~
  47:             s/(helo=<[^>]*>)//gi;
  48:     }
  49:
  50:     print $line."\n";
  51: }

Attention : certaines lignes du script ci-dessus sont tronquées volontairement. Cliquez ici pour obtenir le code du script fonctionnel : logs_anonymes.pl.

Pour utiliser ce script, il vous faudra installer IP::Anonymous, comme ceci par exemple :

$ sudo cpan
cpan[1]> install IP::Anonymous

Il vous faudra aussi personnaliser le contenu de @key (lignes 17 à 19), en utilisant par exemple la commande jot pour générer une liste de 32 entiers aléatoires compris entre 0 et 255 :

$ jot -r -s , 32 0 255

@key doit être gardée secrète, donc votre script devra être lisible seulement par vous.
Pour finir il faudra personnaliser le contenu de $seed (ligne 25), en saisissant la chaîne de caractères qui vous plait.
Aux lignes 40 et 42 figure une liste quasi complète des TLD, obtenue auprès de l'IANA.

Pour utiliser le script, que vous aurez rendu exécutable, il suffit de l'invoquer comme cela :

$ /chemin/de/logs_anonymes.pl fichier.log > sortie_anonyme.log

Testé sous Mac OS X 10.6 et FreeBSD 8.

Enjoy.

Publié dans Unix | Mots-clefs : , | Laisser un commentaire

Collector

Ces mecs ne doutent de rien.

Publié dans Grrr | Mots-clefs : | Laisser un commentaire

Mon ami grep

grep, c'est mon ami. C'est d'ailleurs probablement l'ami de pas mal d'administrateurs système (enfin, les vrais quoi*). De temps en temps, il faut quand même bien vérifier que son ami est au mieux de sa forme, s'enquérir de ses performances, évaluer d'un œil critique si son environnement lui convient bien.

Quand vous avez un millier de chaînes de caractères, dont vous souhaitez retrouver toutes les occurrences dans un gros fichier de 685000 lignes, vous pouvez utiliser grep de deux manières :

  1. vous dites à votre ami grep de chercher toutes les chaînes en même temps dans le gros fichier,
  2. vous utilisez une boucle pour dire à grep de chercher une chaîne dans le fichier, puis de passer à la chaîne suivante, …

La solution 1 semble la plus intéressante. Une seule commande, pas de boucle, on se dit naturellement que c'est plus économique, et donc plus rapide. La solution 2, on se dit qu'elle est moche, complexe, et que les performances vont être mauvaises.

Petit test grandeur nature sur un serveur FreeBSD 7.x virtualisé, 2 CPU, 2Go de RAM :

Méthode 1 :
grep -i -f liste_emails maillog
opération terminée en 370 min environ.
Méthode 2 :
while read email; do grep -i $email maillog ; done<liste_emails
opération terminée en 1 min 32 s.

Bien sûr, le résultat est le même en terme de contenu, la seule différence est l'ordre des lignes. La méthode moche et supposée lente est juste 240 fois plus rapide que la méthode académique. Shame on you grep. Shame on you.

L'environnement est aussi important. On pourrait se dire qu'avec plus de CPU (en puissance, pas en nombre), plus de RAM, tout irait tellement plus vite. Essayons la même chose sur un Mac Pro Xeon quad-core, avec 12 Go de RAM, sous Mac OS X 10.6.

Méthode 1 : 223 min.
Méthode 2 : 35 min 45 s.

Ce qui prouve une fois de plus que Mac OS X est un gros tromblon quand il s'agit de fork. Comprendre que le coût du lancement d'un programme, en terme de ressources système, est beaucoup plus fort que sur d'autres OS, comme FreeBSD par exemple. Ce qui fait de Mac OS X un très mauvais candidat pour les scripts shell utilisant des boucles de manière très intensive.
On voit aussi que la vitesse d'exécution de la méthode 1 est essentiellement liée à la puissance de calcul du CPU, alors que la vitesse de la méthode 2 est essentiellement liée à la capacité du système d'exploitation de créer des process rapidement.

Pour conclure, j'ai fait un petit test avec awk, sur les mêmes fichiers. Moyennant quelques aménagements triviaux pour transformer le fichier liste_emails en programme awk, j'ai pu lancer la commande awk -f liste_emails maillog qui est l'équivalent de la méthode 1 pour grep. Le temps d'exécution est tombé à moins de 15 minutes sur Mac OS X, et moins de 30 minutes sur le FreeBSD.

* ceux qui ont fait 5 ans d'études dans une autre branche, avant de passer à l'informatique, par exemple.

Publié dans Unix | Mots-clefs : , , | Laisser un commentaire

Norwegian Wood

Il y a moins de deux ans, je me suis délecté à la lecture du roman de Murakami (Haruki), La ballade de l'impossible, aussi connu sous le titre Norwegian Wood. Quand une amie japonaise m'a annoncé que le livre allait faire l'objet d'une adaptation cinématographique, j'ai été enchanté. Et j'ai attendu. Longtemps. C'est toujours plus long quand on attend, n'est-ce pas ?
Quand un cinéma de Lyon a programmé le film en avant-première, je me suis tout naturellement précipité. Malheureusement, la déception est à la hauteur de mon attente. Le film est long et ennuyeux. La musique trop forte tombe souvent dans le cliché, tuant du même coup les scènes qu'elle est censée accompagner. Les images sont parfois juste moches, et la quantité de plans ou de séquences qui valent le coup d'œil est négligeable. Bref, on se fait chier. Tant et si bien que certains spectateurs sont sortis avant la fin, que d'autres n'ont pu s'empêcher de rire comme des potaches pendant les dialogues un peu crus… Je ne peux même pas leur en vouloir, et pourtant je ne supporte pas d'être dérangé quand je regarde un film, c'est dire à quel point cette adaptation de Noruwei no mori par Anh Hung Tran est décevante !

edit : On peut lire sur le site de télérama un commentaire assez affligeant :

[le film] troque l'âpreté du livre contre un lyrisme contemplatif

La personne qui a écrit ça n'a pas lu le lire, et sans doute pas vu le film. Le roman est tout sauf âpre. Quant au lyrisme du film, il n'est pas contemplatif, la musique tarte-à-la-crème est bien trop intrusive pour ça.

Publié dans Grrr | Mots-clefs : | Laisser un commentaire

Steam : les bugs

Valve-logo (c) Valve corporationDepuis quelques temps, le très petit monde du jeu sur Mac s'est considérablement élargi avec l'arrivée de la plateforme Steam, et d'une flopée de jeux Valve.
Valve est une société qui développe des jeux, historiquement pour PC, depuis la fin des années 90. En 1998 ils ont sorti leur titre phare "Half Life". Ils ont aussi créé la plateforme Steam, un logiciel de distribution de contenu en ligne, de gestion de droits, et de communication.
Ce logiciel à tout faire est désormais le point de passage obligé quand on veut jouer à des jeux comme Left 4 Dead 2 sur Mac. Contrairement aux versions PC et XBox, on ne peut pas acheter le DVD dans le commerce, et les parutions actuelles suivent ce chemin sur Mac comme sur PC. Désormais, si vous voulez jouer à un jeu Valve (ainsi qu'à certains jeux produits par d'autres), vous devez obligatoirement passer par Steam. Avant de pouvoir acheter un jeu, vous devez créer un compte Steam (donc donner votre adresse email, entre autre), et télécharger le client Steam. Via ce client, vous pouvez alors acheter votre jeu, et télécharger les quelques gigaoctets de données correspondants. Autant dire que sans une connexion haut débit, c'est mort.

Tout ceci ne serait pas un problème si le client Steam n'était pas affreusement mal codé et si le système de gestion de droit était indolore.

Au chapitre des bugs, sur la version Mac du client, voici une liste partielle de problèmes que l'on peut rencontrer avec Steam :

Il est presque impossible d'avoir un bon focus. Vous pensez cliquer sur le bouton OK d'une fenêtre Steam, en fait non, vous ramenez au premier plan la fenêtre qui se trouvait derrière votre cible. Vous lisez une page web dans votre navigateur, et votre souris fait apparaitre de temps en temps des bulles d'info de la fenêtre Steam qui se trouve derrière. Vous tentez de ramener une fenêtre au premier plan, mais elle reste à l'arrière plan en dépit de l'avalanche de clicks que vous lui envoyez. J'en passe. Bref à tous les niveaux de son utilisation, l'application souffre d'énormes problèmes de focus.

Le client Steam est mis à jour automatiquement. Il arrive que cette mise à jour de Steam se passe mal, vous interdisant l'accès à l'ensemble de vos jeux jusqu'à ce que vous parveniez à le faire fonctionner à nouveau. La dernière fois que cela m'est arrivé, j'ai du utiliser le terminal pour déterminer les adresses des fichiers de mise à jour, pour les télécharger, et pour les placer au bon endroit de sorte que Steam les trouve au lancement suivant et achève sa mise à jour. Rendez-vous compte, Steam est un client web, et il n'est pas foutu de télécharger quelques fichiers.

Comme si cela ne suffisait pas, Steam grossit. Chaque mois, la place occupée par le client Steam sur votre disque dur augmente de quelques mégaoctets à quelque dizaines de mégaoctets. Le mien pèse actuellement 256 Mo.

Steam gère mal les téléchargements des mises à jour de votre ludothèque. Les jeux Valve subissent souvent des mises à jour, et chaque fois elles sont téléchargées automatiquement avec plus ou moins de bonheur. Il arrive un peu trop souvent que des téléchargements soient mis en pause sans qu'il soit possible de les réactiver (bien que l'interface propose un bouton pour cela). Parfois aussi la mise à jour d'un jeu reste bloquée à 99% indéfiniment, vous laissant frustrés de ne pas pouvoir rejoindre vos amis dans une partie. À nouveau, la "Méthode Windows" s'impose : on relance le client Steam.

Le système de chat est désastreux. Il n'existe pas de moyen d'enregistrer des conversations, et l'horodatage est digne d'une plaisanterie. Vous tapez du texte dans la fenêtre de chat et rien ne se passe, comme si il était impossible de sélectionner le champ de saisie, il vous faut alors relancer le client Steam (et donc quitter le ou les jeux lancés, sinon Steam ne peut pas être relancé).

Steam n'utilise pas les API de Mac OS X. C'est un portage fait à la va-vite d'une application windows, et donc il ne bénéficie pas de la correction orthographique (pour le chat par exemple), de l'accès au dictionnaire, etc. C'est d'ailleurs sans doute ce qui explique les incessants problèmes de focus.

Bientôt 26 ans que je pratique le Mac, et je n'ai jamais eu l'occasion d'utiliser une application aussi catastrophique. Peut être que les développeurs de Valve ont un robinet dans l'œil qui les empêche de bien faire leur travail.

Publié dans Grrr | Mots-clefs : | Laisser un commentaire

Noter ses photos, de Bridge à Spotlight

De nombreux photographes utilisent à un moment donné de leur flux de traitement un outil de notation pour trier leurs photos. En général, c'est au moment de l'editing que l'on donne une note à ses dernières photos : on rejette les ratées, on note de 0 à 5 les autres pour ne garder que les meilleurs clichés. Avec un logiciel comme Bridge (ou Photoshop LightRoom), c'est très facile. Néanmoins, la note ainsi attribuée ne remonte pas dans les métadonnées Spotlight (Mac OS X). Il est par exemple impossible dans le Finder de créer un dossier intelligent qui regrouperait toutes les photos notées avec 4 ou 5 étoiles.
Pour remédier à cela on peut utiliser un script shell qui recopie la note assignée par Bridge dans les métadonnées du fichier photographique. En partant du principe que Bridge stocke ses propres métadonnées dans un fichier XMP à côté du fichier RAW, voici un exemple de script qui fait ce travail pour vous :

 1: #!/bin/bash
 2: case $1 in
 3: 	[1-9])
 4: 		find_args="-mtime -$1"
 5: 		;;
 6: 	*)
 7: 		find_args=""
 8: 		;;
 9: esac
10:
11: for XML in $(find . $find_args -name "IMG_*xmp"); do
12: 	rating=$(awk '/xap:Rating/ {gsub(/ *<[^>]*>/,"",$0); print $0}' "$XML")
13: 	[ -f "${XML/xmp/CR2}" ] && \
14: 	xattr -w "com.apple.metadata:kMDItemStarRating" $rating "${XML/xmp/CR2}"
15: done

Téléchargez le script push_img_ratings.sh (Mac OS X uniquement).

Lignes 2 à 9, on teste le premier argument du script, si c'est un chiffre entre 1 et 9 il sera utilisé pour limiter la plage de recherche. Le seul but de cette première partie, est de pouvoir limiter l'impact du script aux photos récemment notées. Cela permet de ne pas re-noter l'intégralité de sa collection de photos, ce qui peut être assez long si vous avez des disques durs lents et de très nombreux fichiers.
À la ligne 11, on crée une boucle qui utilisera comme argument la liste des fichiers retournée par la commande find. Il s'agit ici de trouver tous les fichiers du répertoire courant et des répertoires inclus, dont le nom commence par "IMG_" et termine par "xmp", et dont la date de modification est dans les $1 dernières 24 heures si $1 est entre 1 et 9.
Pour chaque fichier trouvé, on extrait la note de la photo (ligne 12), et si le fichier RAW correspondant au fichier XMP existe, alors on écrit dans ses métadonnées la note extraite (lignes 13 et 14).
Ce script est aisément modifiable pour fonctionner avec des fichiers RAW d'autres appareils (NEF pour Nikon par exemple). Il nécessite par contre que Bridge soit configuré pour stocker les métadonnées dans un fichier indépendant, et non dans le fichier RAW lui-même.

Il vous suffit ensuite de lancer ce script sur l'ensemble de votre photothèque pour propager votre notation "Bridge" dans les métadonnées Spotlight. Si vous souhaitez recopier les notes attribuées dans les dernières 24h uniquement, lancez le script avec comme seul argument le chiffre 1 :

$ cd Pictures/2011_03_16
$ push_img_rating.sh 1

Vous pouvez aussi bien lancer push_img_rating.sh 1 tous les jours automatiquement grâce à launchd, sous réserve de préciser le chemin de recherche pour la commande find (ligne 11).

Publié dans Photo, Unix | Mots-clefs : , , , | Laisser un commentaire