Utilisation de Cryptsetup avec LUKS (Linux Unified Key Setup) ------------------------------------------------------------- Cette brève explique comment mettre en place une partition chiffrée par utilisateur avec une clef de recouvrement pour toutes les partitions. 1 - Installer Cryptsetup + LUKS ------------------------------- Soit votre distribution le supporte, soit il faut y aller à la main. Par exemple sous Gentoo, il suffit d'installer le package sys-fs/cryptsetup-luks plutôt que sys-fs/cryptsetup. Sinon : $ wget http://luks.endorphin.org/source/cryptsetup-1.0.5.tar.bz2 $ tar -xvjf cryptsetup-1.0.5.tar.bz2 $ cd cryptsetup-1.0.5/ $ ./configure --prefix=/usr/local $ make # make install Et voila, normalement tout est installé dans /usr/local/sbin et /usr/local/bin. Si vous voulez remplacer ou écraser le cryptsetup existant, il suffit d'enlever l'option --prefix=/usr/local au lancement de ./configure 2 - Créer le volume RAID-1 -------------------------- Par exemple, nous allons créer un LV (Volume Logique) sur le disque /dev/hda avec comme miroir /dev/hdb : # mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/hda /dev/hdb Évidemment, le md0 est à changer suivant votre configuration et les existants. Pour voir où en est la duplication, il suffit de regarder dans /proc/mdstat. # cat /proc/mdstat Personalities : [raid0] [raid1] [faulty] md0 : active raid1 hdb[1] hda[0] 488386496 blocks [2/2] [UU] [>....................] resync = 0.0% (233344/488386496) finish=209.1min speed=38890K/sec unused devices: Dans notre cas, la durée de création du LV est assez longue car on travaille sur deux disques de 500Go en SATA. Pour parfaire le travail on va créer le PV (Volume Physique) avec la commande suivante : # pvcreate /dev/md0 Physical volume "/dev/md0" successfully created # pvs PV VG Fmt Attr PSize PFree /dev/md0 lvm2 -- 465.76G 465.76G Tout a l'air OK. 3 - Créer le groupe de volume conteneur --------------------------------------- Maintenant, il va falloir créer un VG (Groupe de Volume) permettant de contenir les futurs volumes chiffrés. Pour cela, nous utiliserons la commande suivante : # vgcreate -l 0 -p 0 -s 8M vg_sauv /dev/md0 Volume group "vg_sauv" successfully created J'ai pris une taille de bloc d'allocation minimum à 8 Méga octets vu la taille du VG. Et surtout, je n'ai pris aucune limite pour le nombre de LV et de PV contenu dans ce VG, ça laisse de la marge :-) Sinon, si vous êtes puriste, vous pouvez toujours les limiter. Par exemple : # vgcreate -l 256 -p 8 -s 8M vg_sauv /dev/md0 Le nombre de PV ne devrait pas être trop grand car nous n'allons pas en utiliser dans ce VG. Par contre, il va y avoir un LV par utilisateur, donc visez juste. 4. Création de la clef de recouvrement -------------------------------------- Il nous faut une clef particulièrement aléatoire de 256 bits puisque nous avons choisi un chiffrement AES 256 bits. DéDé est là pour nous aider à extraire ce qu'il faut de /dev/random : $ dd if=/dev/random of=/root/RecoveryKey bs=32 count=1 Pourquoi 32 ? Parce que 32x8=256 :-) 5 - Créer et formater les partitions LUKS ----------------------------------------- 5.A. Initialisation de la partition coté root --------------------------------------------- Tout d'abord, créons notre LV de 10Go : # lvcreate -L10G -n lv_poggi_crypt vg_sauv Définissez bien la taille du LV, car une fois créée, modifier la taille n'est pas une chose aisée. J'ai choisi la convention de nommage suivante : LV chiffrée : lv_$USER_crypt LV en clair : $USER_clair Pour utiliser des "partitions LUKS" ou plutôt des LV de type LUKS, nous allons avoir besoin de la clef de recouvrement, et nous allons l'utiliser comme clef stockée dans le SLOT 0 de notre LV. # cryptsetup --batch-mode --hash=sha256 --key-size=256 --cipher=aes \ --key-file=/root/RecoveryKey luksFormat /dev/mapper/vg_sauv-lv_poggi_crypt \ /root/RecoveryKey Maintenant, il faut installer une "clef bidon" pour ne jamais donner la clef de recouvrement et surtout pour installer la clef qui sera définie par l'utilisateur lors de la phase d'initialisation. Cette dernière phase pourra se faire sans l'intervention d'un administrateur et donc rendra le processus plus "light". # echo "clef bidon" | \ cryptsetup --batch-mode --hash=sha256 --key-size=256 \ --cipher=aes --key-file=/root/RecoveryKey luksAddKey \ /dev/mapper/vg_sauv-lv_poggi_crypt Ici, il faut quand même donner la clef de recouvrement, mais ce n'est que pour installer la clef "bidon". Évidemment la clef "bidon" étant quand même un peu sensible, il est fortement recommandé d'en choisir une un peu mieux. Tout en sachant qu'elle va trainer en clair dans un batch d'initialisation lancé par l'utilisateur. Attention au droit par conséquent ;-) pas de 777 ou autre fantaisie que l'on retrouve de temps en temps en audit ... Pour être sûr que tout est OK, on peut lancer la sous commande luksDump de cryptsetup : # cryptsetup luksDump /dev/mapper/vg_sauv-lv_poggi_crypt LUKS header information for /dev/mapper/vg_sauv-lv_poggi_crypt Version: 1 Cipher name: aes Cipher mode: cbc-plain Hash spec: sha1 Payload offset: 2056 MK bits: 256 MK digest: e0 40 4e 1b 03 53 4e 4f 54 8e 10 54 96 87 24 1c 8e 7d 4b 30 MK salt: 53 70 31 03 60 1f d9 0a ea c2 3c 37 fd 63 36 f2 e5 cc 74 2d ac 7d 6c a3 cd f6 3b 74 70 05 39 cb MK iterations: 10 UUID: 07ba4f54-0e66-4a38-964d-67a15c0f1722 Key Slot 0: ENABLED Iterations: 76853 Salt: 19 a1 cc 71 77 38 74 cb 60 74 f7 61 7d 8a ea 7a 6e 73 75 6c 74 61 6e 74 73 03 83 35 f7 81 a8 15 Key material offset: 8 AF stripes: 4000 Key Slot 1: ENABLED Iterations: 69289 Salt: 65 72 6f 6d 65 2e 50 6f 67 67 69 40 68 73 63 2e 48 65 72 76 65 20 53 63 68 61 75 65 72 20 43 6f Key material offset: 264 AF stripes: 4000 Key Slot 2: DISABLED Key Slot 3: DISABLED Key Slot 4: DISABLED Key Slot 5: DISABLED Key Slot 6: DISABLED Key Slot 7: DISABLED Juste en passant, ce ne sont pas les même valeurs que chez moi ;-) Évidemment, on peut scripter tout ça comme suivant : #!/bin/sh CLEF_BIDON_DINITIALISATION="phai1ah7ain6eeLo" for User in arnault collignon dembour feil poggi do cryptsetup --batch-mode --hash=sha256 --key-size=256 --cipher=aes \ --key-file=/root/RecoveryKey luksFormat /dev/mapper/vg_sauv-lv_${User}_crypt \ /root/RecoveryKey echo "$CLEF_BIDON_DINITIALISATION" | \ cryptsetup --batch-mode --hash=sha256 --key-size=256 \ --cipher=aes --key-file=/root/RecoveryKey luksAddKey \ /dev/mapper/vg_sauv-lv_${User}_crypt cryptsetup luksDump /dev/mapper/vg_sauv-lv_${User}_crypt done 5.B. Initialisation de la partition coté utilisateur ---------------------------------------------------- Pour l'instant, la partition n'est pas utilisable par l'utilisateur, le système de fichiers n'est même pas créé. Il va falloir faire les opérations suivantes : - Ajout de la clef de chiffrement chiffrée avec la pass-phrase de l'utilisateur : # cryptsetup --verify-passphrase --batch-mode --hash=sha256 \ --key-size=256 --cipher=aes \ --key-file=FichierContenantLaClefTemp luksAddKey \ /dev/mapper/vg_sauv-lv_poggi_crypt - Ouverture du conteneur luks avec la pass-phrase de l'utilisateur : # cryptsetup luksOpen /dev/mapper/vg_sauv-lv_poggi_crypt poggi_clair - Destruction de la clef temporaire d'initialisation : # cryptsetup luksDelKey /dev/mapper/vg_sauv-lv_poggi_crypt 1 - Création du système de fichiers : # /sbin/mkfs.ext2 -q /dev/mapper/poggi_clair - Montage sur le répertoire destination : # /bin/mount -o sync /dev/mapper/poggi_clair /home/poggi/crypt - Changement des droits pour donner à l'utilisateur l'inode une fois monté : # /bin/chown poggi:0 /home/poggi/crypt # /bin/chmod 700 /home/poggi/crypt # /bin/chmod u+s /home/poggi/crypt - démontage et fermeture du conteneur chiffré : # /bin/umount /dev/mapper/poggi_clair # cryptsetup remove poggi_clair ou # cryptsetup luksClose poggi_clair - Protection du conteneur chiffré et marquage du point de montage, pour marquer que le conteneur a été initialisé et pour éviter que l'utilisateur détruise sans le vouloir ce point de montage ou le conteneur : # /bin/chown root:root /home/poggi/crypt/.conteneur_chiffre_deja_cree # /bin/chmod 444 /home/poggi/crypt/.conteneur_chiffre_deja_cree # echo "Fichier permettant de savoir si le conteneur chiffré a déjà été créé" > \ # /home/poggi/crypt/.conteneur_chiffre_deja_cree # echo "NE PAS SUPPRIMMER !!! SINON le programme va détruire le conteneur chiffré !!!" >> \ # /home/poggi/crypt/.conteneur_chiffre_deja_cree # /bin/chattr +i /home/poggi/crypt/.conteneur_chiffre_deja_cree - Ajout du point de montage dans /etc/fstab : # echo "/dev/mapper/poggi_clair /home/poggi/crypt ext2 noauto,user,sync,rw 0 0" >> /etc/fstab À partir de ce moment, l'utilisateur peut monter facilement sa partition sans avoir besoin de quelques connaissances que ce soit. 6 - Scripts de montage / démontage / initialisation --------------------------------------------------- Ils sont disponibles ici : MC : Pour monter la partition http://www.hsc.fr/~poggi/scripts/MC UC : pour la démonter http://www.hsc.fr/~poggi/scripts/UC InitConteneurChiffre : Pour initialiser la partition http://www.hsc.fr/~poggi/InitConteneurChiffre Seul ce script a besoin d'être lancé avec des droits root. Ici nous utilisons sudo (extrait de /etc/sudoers) User_Alias HSC = arnault collignon dembour feil poggi Cmnd_Alias CRYPTSETUP = /bin/cryptsetup, /usr/local/sbin/InitConteneurChiffre Cmnd_Alias TUNE2FSL = /sbin/tune2fs -l /dev/mapper/[a-z]*_clair Cmnd_Alias FSCK = /sbin/fsck -C -T -f -a /dev/mapper/[a-z]*_clair Cmnd_Alias TUNE2FSC = /sbin/tune2fs -c 30 /dev/mapper/[a-z]*_clair HSC ALL=(root) NOPASSWD: CRYPTSETUP, TUNE2FSL, FSCK, TUNE2FSC Vous pourrez voir qu'il y a pas mal de code en plus dans les scripts, mais c'est pour attraper les erreurs, et autre sorties de programmes ... :-) 7 - L'explication technique --------------------------- Le challenge était d'avoir une clef de recouvrement, et de donner la possibilité à l'utilisateur de choisir son mot de passe quand bon lui semblait. Pour cela, nous avons utilisé le slot 0 comme slot pour la clef de recouvrement. Et les 3 autres sont à disposition de l'utilisateur. Il est alors possible de permettre à 4 personnes différentes d'accéder à un même conteneur chiffré avec 4 mots de passe différents. En fait, la véritable clef de chiffrement, celle qui sert véritablement à chiffrer/déchiffrer les données, est stockée dans au moins un des 4 conteneurs (slot). Et chaque slot (initialisé) est protégé par un mot de passe différent. 8 - Références -------------- - Site de LUKS http://luks.endorphin.org/ - Site de pwgen http://sourceforge.net/projects/pwgen/ - Site de sudo http://www.sudo.ws/ par Jérôme Poggi (07/03/07)