Skip to content

Linux Attitude

Le libre est un état d'esprit

Archive

Archive for January, 2009

Niveau :      
Résumé : getfacl ; setfacl

ACL

Faire des groupes c'est bien, mais après quelques expériences, gérer plusieurs groupes d'utilisateurs sur une machine peut rapidement devenir un cauchemar.

Tant qu'il n'y a qu'une seule équipe, tout est jouable, on fait des groupes en fonction des droits dans cette équipe, et on attribue aux éventuels démons (apache, ftpd ... ) les groupes correspondants.

Dès qu'on se retrouve avec plusieurs équipes, une bonne gestion de la sécurité devient impossible. Supposons que vous vouliez donner accès à un fichier au groupe A et au groupe B, dans ce cas il faut faire un troisième groupe contenant les membres de A et de B. Il faut faire intervenir l'administrateur et ça devient rapidement l'horreur à maintenir.

C'est pourquoi on a inventé les ACL sur les systèmes de fichier. Grâce aux ACL, vous pourrez :

  • définir plusieurs utilisateurs et groupes ayant des accès différents à un fichier donné (plus de bidouille des membres de groupes)
  • définir les droits qui seront positionnés lors de la création d'un fichier dans un répertoire (plus de bidouille avec le bit suid, ni d'umask)

Les ACL c'est la fin de la bidouille dans la gestion des droits sur les fichiers !

Recette

Pour que les ACL fonctionnent chez vous, il vous faut :

  • le paquet ACL qui fournit les commande setfacl et getfacl
  • le support des ACL dans le système de fichier qui vous intéresse : ext2, ext3, ext4, reiserfs, jfs, xfs, nfs
  • le support compilé dans le noyau : en option pour chacun des système de fichier
  • le préciser lors du montage de la partition : mount -o acl ou defaults,acl dans fstab

Action

Les ACL se lisent et se modifient assez facilement : Lecture avec getfacl :

$ getfacl fichier

Modification avec setfacl :

$ setfacl -m u::rwx fichier

Il ne reste plus qu'à connaître le format des ACL, très simple : [default:]<type>:<nom>:<droits>

  • type a plusieurs valeurs possibles :
    • user ou u : les droits s'appliquent à un utilisateur spécifique
    • group ou g : les droits s'appliquent à un groupe spécifique
    • other ou o : les droits s'appliquent en l'absence de correspondance (le nom est ignoré)
    • mask ou m : les droits sont les droits maximum possible sur ce fichier (le nom est ignoré)
  • nom peut être vide ou être un nom d'utilisateur ou de groupe. Lorsqu'il n'est pas spécifié, il indique le propriétaire naturel "unix" du fichier
  • droits est la valeur habituelle des droits tels que vous les connaissez : rwx (Read, Write, eXecute)
  • si default ou d est présent, il indique que les droits seront appliqués aux fichiers créés dans ce répertoire (ne marche que pour un répertoire)

Et voila, c'est extrêmement simple non ?

Exemples

Je veux que jeremy accède en lecture à mon fichier lenna.jpg :

$ setfacl -m u:jeremy:r lenna.jpg

Je veux que les administrateurs aient accès en écriture au contenu du répertoire /usr/local/etc

$ setfacl -R -m g:admin:rw /usr/local/etc

Je veux que jeremy n'ait plus accès à mon fichier lenna.jpg

$ setfacl -x u:jeremy lenna.jpg

Je veux que tous les fichiers créés dans /tmp aient un droit de lecture pour l'utilisateur peck

$ setfacl -m d:u:peck:r /tmp

Niveau :      
Résumé : newgrp ; gpassword ; id

Sous unix, les groupes, c'est connu. Un utilisateur est nécessairement dans un groupe primaire, celui qui sert lors de la création de fichiers et répertoires. Il est aussi dans un nombre indéfini de groupes secondaires, qui servent pour les droits d'accès sur ces fichiers et répertoires.

La commande id permet de savoir quels sont vos groupes :

$ id
uid=1000(peck) gid=1000(peck) groupes=1000(peck),1002(toto)

Mais cette notion de groupe primaire n'est pas pratique si on veut créer des fichiers pour un autre groupe que le groupe primaire. Faire un chgrp à chaque nouveau fichier n'est pas des plus sympa. C'est pourquoi il existe la commande newgrp qui permet de changer de groupe primaire (celle-ci lance un nouveau shell).

$ newgrp toto
$ id
uid=1000(peck) gid=1002(toto) groupes=1000(peck),1002(toto)

Mieux, il est même possible de prendre un groupe primaire qui ne vous appartient pas. Mais cette fois un mot de passe vous sera demandé. Si vous connaissez le mot de passe le groupe deviendra votre groupe primaire (puis un groupe secondaire au prochain newgrp). Pour définir un mot de passe sur un groupe (stocké dans gshadow) :

$ gpasswd groupe

Petite bizarrerie, newgrp ne prend en compte que les groupes secondaires pour les groupes autorisés, il ne voudra donc pas vous redonner votre groupe d'origine, sauf s'il est aussi listé en groupe secondaire. Il suffit en pratique de vous déconnecter du shell pour revenire au groupe d'origine.
Remarquez que vous mettre dans le même groupe primaire et secondaire ne pose aucun problème puisqu'on le fait régulièrement lorsqu'on est branché sur un ldap.

Et voilà pourquoi il peut parfois être utile de créer des groupe alors que personne n'est dedans. Il s'agit simplement d'un mot de passe permettant de partager des fichiers sur un système.

Si vous travaillez en équipe sur des machines, pensez à cette fonctionnalité (par exemple dans vos scripts de gestion du système) cela peut vous simplifier la vie en plus de l'umask et du bit suid sur les répertoires.

Niveau :      
Résumé : |>o00c

Les poissons précédents n'étaient pas aussi méchant qu'un alias ls=shutdown ou un alias cd="rm -rf", mais ils étaient plutôt gênant.

Et comme c'est toujours l'occasion d'en apprendre un peu plus sur le système, voici les solutions qui résolvent le problème posé.

Pour la déconnexion impossible (while true; do bash; done) :

$ kill -9 $PPID

Pour la déconnexion obligatoire (echo "exit" >> ~/.bashrc) :

$ ssh localhost "/bin/sh"
$ vi ~/.bashrc

Pour toutes les commandes à base d'alias et de .bashrc, une commande qui marche à tous les coups est soit de lancer un shell différent :

# shell différent
$ /bin/sh
$ /bin/tcsh
# bash
$ /bin/bash --norc

Pour le terminal qui ne répond plus (ctrl-s) :

ctrl-q

Pour le setxkbmap, il faut taper à l'aveugle :

$ setxkbmap fr # dans un terminal X
$ loadkeys fr # en console

Pour le terminal cassé (echo -e "\xE") :

$ echo -e "\xF"

Pour la souris tueuse :

$ fg
ctrl-c

Et enfin une action préventive pour la fork bomb. Pour faire court :

$ echo ulimit -u 256 >> ~/.bashrc

Pour faire propre et forcer la limitation pour tous les utilisateurs (géré par pam_limits.so) :

#/etc/security/limits.conf
* soft nproc 256

La fork bomb de base s'arrête dès que la limite est atteinte. Mais il es possible de faire une fork bomb qui ne s'arrête pas.

Niveau :      
Résumé : |>oOOc

Je sais, je suis un peu en avance, mais il faut se préparer. De temps en temps, vous tombez sur l'écran d'un collègue qui n'a pas eu la bonne idée de respecter les recommandations de sécurité et a laissé sa session ouverte. Pour lui apprendre la vie, nous allons trouver quelques petites blagues à lui faire.

Au delà du traditionnel remplacement de son fond d'écran par une capture de son bureau (et suppression de tout ce qui est au dessus), nous allons regarder un peu plus du côté du terminal :

La déconnexion impossible :

$ while true; do bash; done

La déconnexion obligatoire :

$ echo "exit" >> ~/.bashrc

La disparition des commandes :

$ for cmd in `ls /bin /usr/bin/`; do alias $cmd="echo bash: $cmd: command not found"; done

Les commandes folles (qu'on peut aussi mettre dans le .bashrc pour un meilleur effet) :

$ alias ssh=logout
$ alias vi=emacs
$ alias emacs=vi
$ alias cd=ls
$ alias ls=cd

Les commandes rebelles (idem) :

$ alias rm="echo 'Je serais vous je ne ferais pas ca !'"
$ alias ls="echo 'Mais qui vous a permis ?'"
$ alias ssh="echo 'Alerte ! Cette machine est piratée !'"

Le terminal qui ne répond plus :

ctrl-s

Le terminal d'un autre monde :

$ setxkbmap dvorak # dans un terminal X
$ loadkeys dvorak # en console

Le terminal cassé :

# ne marche pas sur tous les terminaux
$ echo -e "\xE"

La souris tueuse :

# pour les terminaux X
$ while true; do sleep $(($RANDOM/256)); xkill; done &

Et le plus méchant, qui met le système à genoux dans la plupart des cas :

$ :(){ :|:& };:

Et si vous tapez vos commandes en lignes, finissez par effacer ce que vous venez de taper :

$ clear

Voila, maintenant il vous reste à trouver le complément de ces commandes pour revenir à l'état normal.

Niveau :      
Résumé : crypto

Vocabulaire

Avant de pouvoir parler de sécurisation des communications, il faut avoir quelques bases en cryptographie. Commençons par le vocabulaire :

  • Coder : transformer une information en code (par exemple numériser une photo, écrire en morse ou en ASCII)
  • Chiffrer : transformer une information codée de façon à la rendre illisible à une autre personne que son destinataire
  • Déchiffrer : lire un document chiffré avec les informations nécessaires pour le faire
  • Décrypter : tenter de lire un document chiffré sans avoir la clé de déchiffrement
  • Signer : ajouter une information à un document prouvant qu'il a bien été écrit/lu par son auteur/lecteur sous cette forme et n'a pas été modifié
  • Empreinte : somme de contrôle d'un message (MD5, SHA) en cryptographie on cherche à faire en sorte qu'il soit impossible de créer un message ayant une empreinte donnée
  • Cryptanalyse : études des attaques permettant de décrypter un message ou de casser un chiffrement
  • Cryptographie : étude des systèmes de protection de messages
  • Cryptologie : ensemble de la cryptographie et de la cryptanalyse
  • Crypter : ce mot n'existe pas

Entropie

L'entropie est une mesure de la quantité d'information. Cette mesure n'est pas absolue, elle est relative à une quantité d'information possible.

Par exemple un octet est une valeur parmi 256. Un octet vraiment aléatoire (avec une répartition linéaire) a donc une entropie de 8. En pratique on ne cherche que rarement la valeur d'une entropie. On chercher plutôt à comparer obtenir des propriété sur l'entropie.

Par exemple prenons une suite de 5 octets. Si je peux déduire les 4 dernier octets à partir du premier (2*x 4*x 8*x 16*x), alors leur entropie est la même que celle d'un seul octet.

Maintenant si cette suite est véritablement aléatoire (tirée aux dés non pipés), l'entropie devient 5 fois plus grande.

Et enfin si cette suite n'est pas vraiment aléatoire, c'est-à-dire tirée avec un générateur pseudo aléatoire (/dev/urandom), alors leur entropie est égale à l'entropie du générateur pseudo aléatoire. Celle-ci se mesure par la taille de l'état interne du générateur.

Il est important de bien saisir cette notion pour comprendre la sécurité des algorithmes.

Entropie mesurée

Lorsque nous générons une suite d'octets, nous pouvons connaître l'entropie des données (et encore ...).

Lorsque nous récupérons des données, l'entropie n'est pas mesurable. Mais elle est estimable. En effet, pour une grande suite d'octets, si celle-ci est compressible, cela veut dire qu'il existe une technique pour déduire certains octets à partir des autres. L'entropie est donc très (le très variant en fonction du nombre d'octets considérés) probablement inférieure à la taille de la version compressée.

Pour tout système on peut donc chercher à en réduire l'entropie en éliminant des informations qui n'en sont pas vraiment. C'est le travail que font les gens qui développement des codecs (audio, vidéo ...).

Espace de chiffrement

L'espace de chiffrement est le nombre de tests que l'on doit effectuer pour en découvrir la clé de chiffrement d'un système. Si le système de chiffrement était parfait, il serait de la même taille que la clé. Malheureusement, on sait que la perfection n'existe pas.

Les études successives d'un système permettent souvent de réduire cet espace. Soit grâce à des informations obtenues par des moyens détournés (sous partie de la clé disponible, comparaison possible de texte clair et de texte chiffré ...), soit par une faiblesse du système qui va réduire sa propre entropie (ce cas est assez rare).

Sécurité

La sécurité d'un système s'estime à partir de cet espace de chiffrement. Plus il est grand, plus une machine devra mettre de temps pour trouver la clé de chiffrement et plus le système va être sûr.

Attention tout de même, ce n'est pas parce qu'un système de chiffrement est sûr que vos données le sont.

Et la littérature est abondantes sur le sujet, wikipedia n'est pas le seul à proposer des informations.

Niveau :      
Résumé : RSA ; DSA

La suite ... la suite ... Aujourd'hui les signatures.

Non il ne s'agit pas du petit gribouillis que vous mettez en bas des chèques. Il s'agit de signature numérique. Et ce n'est pas non plus une image scannée de votre gribouillis. Même si le but de la signature numérique est la même, il s'agit de présenter une preuve (presque) infalsifiable du fait que vous avez bien lu, voire écrit un message.

En fait la signature ne fait que vous identifier, prouver que c'est bien vous qui étiez là. Le sens même de la signature dépend du document signé (chèque, article scientifique, patch ...)

Principe

Un document signé numériquement doit assurer deux choses :

  • Que le document transmis n'a pas été modifié depuis que vous l'avez lu
  • Que c'est bien vous qui avez lu / écrit / approuvé ce document, c'est-à-dire
    • que ce n'est pas quelqu'un d'autre
    • que vous l'avez bien fait

C'est la combinaison de deux choses qui va permettre cela :

  • Une fonction de hachage à sens unique
  • Un algorithme à clé publique

La première garantit que le document correspond à une empreinte et qu'on ne produire de document modifié ayant la même empreinte. Le deuxième garantit que la signature ne peut être générée à partir d'une empreinte différente, si ce n'est par le signataire.

Par conséquent, on prouve que c'est bien le propriétaire de la clé concernée qui a signé le document.

Attention, seule la combinaison document - empreinte - signature le prouve. Ce qui veut dire qu'il est toujours possible de supprimer un élément pour empêcher de prouver que vous l'avez signé (non monsieur le juge, il n'y a pas de preuve que j'ai signé ce chèque). Dans le même ordre d'idée, seule la signature de la clé prouve que celle-ci vous appartient et donc que c'est bien vous l'auteur de la signature. C'est donc au destinataire de conserver ces données s'il veut un jour pouvoir fournir la preuve que vous avez signé le document.

Authentification

La signature permet l'authentification. Supposons que vous vouliez vous authentifier sur un serveur. Il suffit que le serveur vous envoie un challenge (un message) que vous devrez signer. Il va alors vérifier la signature (et les certificats qui vont avec) et vous serez authentifié.

Algorithmes

Hachage

On utilise une fonction de hachage qu'on considère comme sûre (donc éviter md5). Voir l'article précédent.

RSA

Pour la partie signature à clé publique, on utilise souvent le RSA comme expliqué dans un article précédent.

DSA

Un autre algorithme est fréquemment utilisé pour les signatures, il s'agit du DSA (Digital Signature Algorithm). Cet algorithme à clé publique a été développé pour ne fonctionner que dans le mode signature.

Il n'est ni plus ni moins sécurisé que le RSA, il est juste différent. Il utilise des formules mathématiques similaires au RSA et n'est pas plus difficile à comprendre que celui-ci.

Niveau :      
Résumé : SHA1 ; MD5

Une fonction de hachage est une fonction surjective qui prends un certain nombre d'octets en entrée et qui rend un nombre fixe d'octets en sortie. Elles sont donc à sens uniques et plusieurs entrées peuvent donner le même résultat.

Ces fonctions peuvent servir à la détection d'erreurs involontaires ou à la détection de modifications volontaires. Dans le premier cas on cherche à avoir une fonction qui permettra de détecter des erreurs de transmission, de lecture ou de recopie (le dernier chiffre de votre numéro de sécurité sociale). Dans le deuxième cas, on cherche à empêcher une personne de lire ou de modifier elle-même le contenu des données et de les faire passer pour les données originales, c'est ce qu'on utilise pour signer un document ou stocker un mot de passe (vous saviez que vous aviez en réalité une infinité de mots de passe qui fonctionnent ?).

CRC

Dans la première catégorie, on trouve un grand nombre de codes de redondance cyclique. Ils consistent à calculer des polynômes sur les données en entrée. Il existe une méthode permettant de les calculer facilement et sous forme de flux, ce qui fait qu'ils sont très rapides et facile à implémenter dans le matériel.

Ils ne sont pas standardisés puisqu'ils dépendent de la définition du polynôme choisi ainsi que de la taille du résultat.

Par contre les CRC ne permettent pas de protéger les données contre des modifications volontaires puisqu'il est assez facile de calculer une série d'octets qui donnera un résultat donné.

MD5

MD5 a été inventé par Ronald Rivest, celui qui a fait entre autre rc4 et rc5. Cette fois l'algorithme a pour but d'empêcher de reconstruire une source de données différente produisant un résultat donné. Il est très répandu et sert probablement à stocker vos mots de passe. Malheureusement il est depuis quelque temps déjà considéré comme peu sûr, même s'il n'y avait pas eu d'attaque dessus. Il a d'ailleurs récemment fait la une puisqu'il a été possible de calculer des collisions avec un bête cluster de 200 PS3 pendant quelques jours, comme quoi c'est à le portée de tout le monde.

Il est donc fortement déconseillé de l'utiliser pour une application de sécurité durable.

SHA

SHA est une série de fonctions de hachage dont les algorithmes sont complètement différents les uns des autres. Elles peuvent être utilisées pour la sécurité tout comme MD5.

  • SHA-0 est dépassés depuis longtemps.
  • SHA-1 est la plus répandue après MD5, et conseillée si vous ne disposez pas de SHA-2. Bien qu'on ait des doutes sur sa sûreté, on n'a pas encore réussi à produire des collisions en un temps humainement mesurable.
  • SHA-2 est une fonction de hachage à taille variable. Si vous voyez des SHA-224, SHA-256, SHA-384 ou SHA-512, il s'agit toutes de SHA-2 avec la taille précisée en suffixe. C'est la méthode la plus sûre actuellement.
  • SHA-3 n'existe pas encore et fait l'objet d'un concours pour savoir quelle sera la solution d'avenir. (d'ailleurs monsieur sécurité Bruce Schneier en personne y participe)