Mise en place d'un répertoire utilisateur chiffré sous Debian GNU/Linux

Introduction

Cet article est destiné à montrer comment on peut créer un répertoire utilisateur crypté dans le but de crypter des informations importantes qui ne doivent pas être consultées par n'importe quel utilisateur. Bien sûr vous pourriez tout simplement changer les permissions de ces fichiers, mais l'administrateur du système ou une autre personne disposant de ses droits pourra facilement lire ces fichiers. Dans ce cas le cryptage de certaines informations s'avère nécessaire, si ce n'est pas indispensable.

Les pré-requis

  • Les sources du noyau Linux 2.4 : kernel-source-2.4.26 ou de la version 2.6 : kernel-sources-2.6.7.
  • Une connexion à Internet.
  • Les outils pour compiler le noyau : kernel-package, libncurses5-dev et fakeroot.
  • GNU GPG pour vérifier l'authenticité du patch : gnupg.
  • La librarie PAM mount : libpam-mount.
  • OpenSSL : openssl.
  • GNU Wget : wget.

Configuration du noyau

Prise en charge des méthodes de cryptage sur un noyau 2.4

Il vous suffit de taper la commande suivante pour installer les paquets nécessaires :

# apt-get install kernel-source-2.4.26 kernel-package libncurses5-dev fakeroot gnupg libpam-mount wget openssl

La première étape consiste à ajouter le support du chiffrement par blocs au noyau Linux. Cette fonctionnalité est apportée par un patch appliqué au noyau. Notez aussi que cryptoapi et cryptoloop sont directement intégrés dans le noyau 2.6, vous n'avez donc pas besoin de patcher le noyau si vous diposez de cette version.

Placez vous dans le répertoire où le packet kernel-source-2.4.26 a placé l'archive qui contient les sources du noyau et décompressez la :

# cd /usr/src
# tar -xvjf kernel-source-2.4.26.tar.bz2
# ln -s kernel-source-2.4.26 linux
# cd linux

Il faut ensuite récupérer le script appelé International Kernel Patch Magic Installer qui permet d'automatiser l'installation du patch international (vous pouvez également utiliser le patch du noyau de Con Kolivas qui contient parmi d'autres patchs celui de cryptoapi) :

# wget -O - "www.kerneli.org/go?VersionDuKernel/CodePays" | sh

Il faut bien sûr remplacer VersionDuKernel et CodePays par leurs valeurs. Comme par exemple

# wget -O - "www.kerneli.org/go?2.4.19/FR" | sh

Après l'application du patch nous allons construire un paquet Debian du noyau a l'aide de la commande make-kpkg (vous pouvez également consulter l'article sur la compilation d'un noyau à la sauce Debian) :

# make-kpkg kernel-image --fakeroot --append-to-version -crypto --config menuconfig

Lors de la configuration du noyau, la partie la plus importante est :

Cryptography support (CryptoAPI)
    <*> CryptoAPI support (NEW)
    [*] Cipher Algorithms
        --- 128 bit blocksize
        <M> AES (aka Rijndael) cipher (NEW)
        <M> MARS cipher (NEW)
        <M> RC6 cipher (NEW)
        <M> Serpent cipher (NEW)
        <M> Twofish cipher (NEW)
        --- 64 bit blocksize
        <M> 3DES cipher (NEW)
        <M> Blowfish cipher (NEW)
        <M> CAST5 cipher (NEW)
        <M> GOST cipher (NEW)
        <M> IDEA cipher (NEW)
        <M> RC5 cipher (NEW)
        --- Deprecated
        < > NULL cipher (NO CRYPTO) (NEW)
        < > DES cipher (DEPRECATED) (NEW)
        < > Old (mutated-endianess) Blowfish cipher (DEPRECATED) (NEW)
    [ ] Digest Algorithms
    [*] Crypto Devices
        <M> Loop Crypto support (NEW)
        [ ] Atomic Loop Crypto
        [*] Loop IV hack
        [ ] Loop Crypto Debugging
    < > IPSEC tunneling (ipsec_tunnel) support (NEW)

Vous pouvez mettre les ciphers ou algorithmes de chiffrement en dur dans le noyau ou bien en modules. Cela ne change rien sauf que vous devrez charger les modules si vous utilisez cette solution :

# modprobe cryptoloop cryptoapi cipher-twofish cipher-aes

Ajouter enfin le nom de ces modules au fichier /etc/modules afin qu'ils soient chargés au démarrage du système :

# /etc/modules: kernel modules to load at boot time.
#
# This file should contain the names of kernel modules that are
# to be loaded at boot time, one per line. Comments begin with
# a "#", and everything on the line after them are ignored.
cryptoloop
cryptoapi
cipher-twofish
cipher-aes

Attention la compilation d'un noyau 2.4.x peut ne pas fonctionner pas avec gcc 3.0, il faut donc remplacer gcc par gcc-2.95 dans le Makefile ou supprimer le lien vers gcc 3.0 dans le répertoire /usr/bin/ et le remplacer :

# rm /usr/bin/gcc && ln -s /usr/bin/gcc-2.95 /usr/bin/gcc

Si la compilation s'est bien passé il suffit d'installer le paquet :

# cd ..
# dpkg -i kernel-image-2.4.19-crypto_10.00.Custom_i386.deb

Après l'installation du paquet il faut configurer votre chargeur d'amorçage. Si vous disposez de Lilo installé ou GNU/Grub Migration de Lilo vers Grub. Dans le cas de GNU/Grub il suffit d'ajouter les lignes suivantes dans le fichier /boot/grub/menu.lst :

title Debian GNU/Linux 3.0 Woody Kernel 2.4.19-crypto
     root (hd0,0)
     kernel /boot/vmlinuz-2.4.19-crypto root=/dev/hda1

Redémarrez sur le nouveau noyau et vérifiez que cryptoapi et cryptoloop sont bien chargés :

# cat /var/log/dmesg | grep crypto
cryptoapi: loaded
cryptoloop: loaded

Voilà, votre noyau supporte le chiffrement par blocs.

Prise en charge des méthodes de cryptage sur un noyau 2.6

[…]

Avant de continuer

Afin de tester que tout cela fonctionne correctement, nous allons suivre l'exemple de la documentation officiel de cryptoapi dont la suite de cet section est quelque peu inspirée. Commençons donc par créer un fichier de données aléatoires de 10Mo dans /home/user/ et qui se nomme cryptofile :

# dd if=/dev/urandom of=/home/user/cryptofile bs=1M count=10

Une fois ce fichier créé, il ne nous reste plus qu'à monter le fichier comme un périphérique normal en utilisant la commande losetup et l'algorithme de chiffrement twofish (la première fois que vous monter ce périphérique vous devrez rentrer un mot que vous réutiliserez plus tard pour pouvoir monter votre système de fichiers crypté) :

# losetup -e twofish /dev/loop0 /home/user/cryptofile
Available keysizes (bits): 128 192 256
Keysize: 256
Password: votre_pass

Puisque c'est la première fois que nous accédons à ce fichier crypté, nous allons créer un système de fichiers sur celui-ci (l'option -j permet d'utiliser le système de fichier ext3 au lieu de ext2) :

# mke2fs -j /dev/loop0

Il ne vous reste plus qu'à monter le système de fichiers crypté en utilisant simplement la commande mount :

# mkdir /mnt/crypto
# mount -t ext3 /dev/loop0 /mnt/crypto

Vous pouvez désormais copier vos fichiers confidentiels dans /mnt/crypto/. Une fois que vous aurez fini, n'oubliez pas de démonter le système de fichiers crypté puis de dissocier le périphérique loop sinon n'importe qui pourra accéder à vos fichiers en remontant simplement le système de fichier crypté :

# umount /mnt/crypto/
# losetup -d /dev/loop0

Vous pouvez désormais accéder de nouveau à vos fichiers confidentiels en reprenant les même étapes , sauf, bien entendu, celle concernant la création d'un système de fichiers, puis en tapant le même mot de passe que précédemment.

Pour l'utilisation que je viens de décrire, il existe un autre logiciel plus intuitif grâce à une interface graphique et qui ne nécessite pas une recompilation du noyau ou l'installation de nouveaux pilotes. Cet utilitaire vous permet de crypter vos mots de passe mais également d'attacher des fichiers. Il propose aussi l'algorithme twofish et un cryptage allant jusqu'à 256 bits. Il se nomme gringotts :

# apt-get install gringotts

Configurer le module PAM mount

Chaque programme qui doit authentifier un utilisateur sous Linux utilise la bibliothèque PAM (Pluggable Authentication Module). Les fichiers de configuration de chaque service se trouvent dans le répertoire /etc/pamd.d. Si vous voulez que votre répertoire personnel soit monté lors de la session graphique. Il faut ajouter les deux lignes qui commencent par +++ dans le fichier de configuration de PAM de votre gestionnaire de connexion graphique (xdm, gdm, kdm ou wdm) :

auth required pam_nologin.so
auth required pam_env.so
auth required pam_unix_auth.so
account required pam_unix_acct.so
password required pam_unix_passwd.so shadow
session required pam_unix_session.so
session required pam_limits.so
+++ auth optional pam_mount.so use_first_pass
+++ session optional pam_mount.so use_first_pass

Après avoir configuré votre service, il faut configurer le comportement de la libpam-mount elle-même. Pour cela il faut éditer le fichier de configuration /etc/security/pam_mount.conf.

debug 0
mkmountpoint 1
lsof /usr/sbin/lsof
fsck /sbin/fsck
losetup /sbin/losetup
options_allow *
options_require nosuid,nodev
smbmount /usr/bin/smbmount
smbumount /usr/bin/smbumount
ncpmount /usr/bin/ncpmount
ncpumount /usr/bin/ncpumount
umount /bin/umount
lclmount /bin/mount --pass-fd 0
# Volumes that will be mounted when user triggers pam_mount module
# Format:
# volume <user> [smb|ncp|nfs|local] <server> <volume> <mount point>
# <mount options> <cipher> <key>
volume * local - /home/.&.img /home/&
sync,loop,encryption=aes,keybits=256 aes-256-ecb /home/.&.key

Les deux dernières lignes ne sont qu'une seul et unique ligne. Le caractère & est automatiquement remplacé par le login de l'utilisateur qui se connectera. L'image crypté du répertoire personnel de l'utilisateur se trouve dans le répertoire /home/ sous la forme .nom_d'utilisateur.img. La clé de cryptage se trouve dans le même répertoire, dans le fichier .nom_d'utilisateur.key. Bien sûr il est possible de placer ces fichiers dans un autre répertoire. Les images de répertoires personnels de l'utilisateur sont bien sûr protégées par une passphrase qui est le mot de passe de l'utilisateur.

Par défaut la librairie PAM ne ferme pas la session de chaque utilisateur et n'appelle jamais la fonction pam_close_session. Il faut modifier ce comportement pour démonter automatiquement le répertoire de l'utilisateur lorsque celui-ci se déconnecte. Pour cela il faut régler la valeur de la variable CLOSE_SESSIONS à yes dans le fichier /etc/login.defs.

#
# Enable pam_close_session() calling. When using normal (pam_unix.so)
# session handling modules, this is not needed. However with modules
# (such as kerberos or other persistent session models), login and su
# need to fork and wait for the shell to exit so that sessions can be
# cleaned up.
#
CLOSE_SESSIONS yes

Patcher la commande mount

La commande mount de la distribution Debian unstable ne supporte pas l'option keybits. Pour que la commande prenne en compte cette option il faut appliquer un patch sur les sources de la commande et recompiler le paquet mount.

$ apt-get source mount
Reading Package Lists... Done
Building Dependency Tree... Done
Need to get 1907kB of source archives.
Get:1 http://ftp.debian.org unstable/main util-linux 2.11z-4 (dsc) [641B]
Get:2 http://ftp.debian.org unstable/main util-linux 2.11z-4 (tar) [1840kB]
Get:3 http://ftp.debian.org unstable/main util-linux 2.11z-4 (diff) [66.0kB]
dpkg-source: extracting util-linux in util-linux-2.11z
$ cd util-linux-2.11z/mount
$ wget -O - "http://etud.epita.fr/~nowick_c/mount.patch" 2> /dev/null | patch -p0
patching file mount.c
$ cd ..
$ fakeroot
# dpkg-buildpackage -b -uc
...
# su
Password:
# dpkg -i ../mount_2.11z-4_i386.deb
(Reading database ... 87184 files and directories currently installed.)
Preparing to replace mount 2.11z-4 (using ../mount_2.11z-4_i386.deb) ...
Unpacking replacement mount ...
Setting up mount (2.11z-4) ...
# dpkg --set-selections | mount hold

Après avoir installé le nouveau paquet mount il faut geler la version de mount à l'aide de l'option –set-selection de dpkg.

Créer les répertoires personnels des utilisateurs

Il faut ensuite créer le fichier qui contient le répertoire de l'utilisateur. Ici nous créons un répertoire personnel d'une taille de 42Mo pour l'utilisateur user. Il faut faire une sauvegarde de l'ancien répertoire personnel de l'utilisateur au cas où la manipulation tournerait mal.

# dd if=/dev/urandom of=/home/.user.img bs=1M count=42
42+0 records in
42+0 records out
44040192 bytes transferred in 24.981949 seconds (1762881 bytes/sec)

Il faut broyer le mot de passe de l'utilisateur pour le mettre dans le fichier qui se termine par key. Ici nous utilisons algorithme AES (Advanced Encryption Standard) avec une clé de 256 bits (32 caractères).

# dd if=/dev/urandom bs=1c count=32 | openssl enc -aes-256-ecb > /home/user.key
32+0 records in
32+0 records out
32 bytes transferred in 0.001853 seconds (17269 bytes/sec)
enter aes-256-ecb encryption password:
Verifying - enter aes-256-ecb encryption password:

Il faut ensuite configurer le loop device pour que celui-ci associe le fichier image et le fichier de la clé.

# openssl enc -d -aes-256-ecb -in <home>.user.key | losetup -e aes -k 256 -p0 /dev/loop0 /home/.user.img
enter aes-256-ecb decryption password:

Il faut ensuite créer un système de fichiers (ext2fs, ext3fs, xfs, reiserfs, …) sur le périphérique loop, monter l'arborescence du système de fichiers, changer le propriétaire du nouveau système de fichiers pour que l'utilisateur ait les droits de créer un fichier dans son répertoire personnel. Après il s'agit de migrer l'ancien répertoire personnel vers le nouveau. Et de démonter le loop device puis d'effacer le cipher.

 mkfs -t ext3 -m 0 /dev/loop0
mke2fs 1.34-WIP (21-May-2003)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
10752 inodes, 43008 blocks
0 blocks (0.00%) reserved for the super user
First data block=1
6 block groups
8192 blocks per group, 8192 fragments per group
1792 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 21 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
# mount -t ext3 /dev/loop0 /mnt
# cd /mnt
# chown user. .
# cp -pr home/user. .
# sync
# cd ..
# umount /dev/loop0
# losetup -d /dev/loop0
 
securite/mise-en-place-d-un-repertoire-utilisateur-chiffre-sous-debian-gnu-linux.txt · Dernière modification: 11/12/2010 18:19 par orgrim