Autoblog de gordon.re

Ce site n'est pas le site officiel de gordon.re
C'est un blog automatisé qui réplique les articles de gordon.re

Howto pratique : l’installation d’une Gentoo encore plus sécurisée

Sat, 18 Aug 2012 23:01:39 +0000 - (source)

Il y a un certain temps, j’avais écrit un billet expliquant étape par étape l’installation d’une Gentoo Linux avec des partitions intégralement chiffrées. Ma récente aventure avec FreeBSD sur une de mes machines, et mon retour sous Gentoo me donne l’occasion de pousser un peu plus loin cet objectif.

En effet, le simple fait de chiffrer un disque ne le rend pas totalement sécurisé par miracle. La faiblesse d’un système de chiffrement, en pratique, repose souvent dans la clé et la façon de la gérer par l’utilisateur. Parce qu’un chiffrement Rijndael bien barbu ne vaut rien si sa clé est la date de naissance de l’utilisateur, naturellement. Sans tomber dans cet extrême, la solution retenue précédemment avait quelques faiblesses :

Il existe donc une solution pas très complexe à cela, mais que je n’avais pas voulu essayer à l’époque (par peur de voir trop gros d’un coup, l’autre raison étant que les explications claires n’étaient pas encore écrites sur le guide utilisé) : stocker le noyau et l’initramfs sur un support amovible, qui serait sur moi en permanence, et qui par ailleurs contiendrait la clé de déchiffrement du disque, chiffrée en GPG. La dernière fois, utiliser GPG ne me semblait pas être une bonne idée, mais le fait de stocker la clé sur un support externe apporte une solution convenable à ce problème : on a maintenant une authentification forte (car basée sur 2 méthodes distinctes) pour déverrouiller la machine : il faut à la fois posséder le support externe et connaître la passphrase pour accéder au disque. Par ailleurs, au lieu d’avoir plusieurs partitions que l’on déverrouillera avec la même clé, on peut utiliser LVM pour créer des partitions logiques, stockées sur une seule partition physique, qui, elle, sera chiffrée en premier lieu.

En plus de cela, j’ai choisi de partir sur le projet Gentoo Hardened, qui est un ensemble de modifications et d’ajouts pensés pour la sécurité, sur la distribution Gentoo. Concrètement, il s’agit de l’ajout de PaX, SElinux, GRsec et autres modules améliorant la sécurité du système en consolidant les accès systèmes, fichiers, etc. Cette « déclinaison » de la Gentoo a la réputation d’être le meilleur choix de sécurité pour du GNU/Linux (les systèmes BSD étant encore un cran au-dessus, pour peu qu’on sache les utiliser comme il faut). Et pour finir, j’ai souhaité garder un système Libre, sans exception. Bien que non référencée dans les distributions GNU-compliant par la Free Software Foundation, deux petites astuces permettent de se prémunir de tout code non-libre dans son beau système. Non seulement parce que je crois qu’utiliser du logiciel libre me permet d’avoir confiance dans mon système, mais également par principe, sachant que j’utilise très peu de logiciels non-libres sur mes autres systèmes. C’est en quelque sorte un défi.

Disque dur chiffré, le retour

Pour rappel, les améliorations du système précédent sont donc :

Au moment de partitionner le disque, nous allons donc créer une seule partition, puisque c’est LVM qui, à l’intérieur, s’occupera de la segmenter en partitions logiques. Dans cet article, on supposera que le disque dur est /dev/sda. Avec fdisk ou votre outil de partitionnement préféré, supprimez donc tout, puis créez une unique partition qui prendra toute la capacité disponible (ce sera /dev/sda1). Cette partition sera un conteneur LUKS, qui, une fois ouvert, contiendra le VG de LVM, dans lequel seront nos 3 partitions : root (/), home (/home) et swap (non monté). Mais pour commencer, on génère la clé. Pour cela, je pioche dans le générateur de pseudo-aléa /dev/random une quantité raisonnable de données, que je découpe proprement pour avoir une chaîne alphanumérique de 255 caractères.

head -c 255 /dev/random | uuencode -m - | head -n -1 | tail -n +2 | tr -d '\n' | gpg --symmetric -a > sda1.gpg #puis on agite sauvagement la souris, ou on tape comme un goret sur son clavier, pour générer de l’entropie

Nous avons notre clé. Notez que nous avons pris soin de supprimer les retours à la ligne pour éviter une mauvaise surprise avec les pipes, bien qu’il ne devrait pas en avoir. Créons maintenant le conteneur LUKS.

gpg --quiet --decrypt sda1.gpg | cryptsetup -d - -v --cipher serpent-cbc-essiv:sha256 --key-size 256 luksFormat /dev/sda1

Notez bien le « -d - », il permet d’éviter le genre d’ennuis cité ci-dessus, et surtout, il sera utilisé par défaut par le script d’initialisation, alors il vaut mieux utiliser la même méthode. Ensuite, pour ouvrir le conteneur :

gpg --quiet --decrypt sda1.gpg | cryptsetup -d - luksOpen /dev/sda1 vg0

Le nom du volume LUKS (ici vg0) importe peu, et je fais confiance à votre imagination fertile pour attribuer un nom qui vous fera briller en société. Notre volume étant ouvert (mais pas formaté, ni monté) dans /dev/mapper/vg0, nous allons pouvoir en faire un VG, justement, et crééer les partitions à l’intérieur.

pvcreate /dev/mapper/vg0
vgcreate vg0 /dev/mapper/vg0 #le premier vg0 est le nom du volume, tandis que /dev/mapper/vg0 est la partition LUKS ouverte. Faut suivre hein
#on peut créer nos LV. Mettons que notre disque fait 100Go
lvcreate -n root -L 49g vg0
lvcreate -n home -L 49g vg0
lvcreate -n swap -L 2g vg0

Vous aurez compris que l’on a assigné 2Go de swap (l’équivalent de notre mémoire physique, au cas où on voudrait suspendre le système), puis que l’on a bêtement redistribué équitablement à /home et /. N’hésitez pas à personnaliser ces valeurs pour correspondre à vos besoins. Nous avons maintenant nos partitions, prêtes à recevoir un filesystem (XFS dans mon cas). Si jamais vous devez reprendre votre installation (à cause d’une tentative infructueuse de boot, par exemple), vous risquez de vous demander comment retrouver vos volumes LVM, après avoir déchiffré /dev/sda :

vgscan && vgchange -ay

Et vos partitions vous attendront sagement dans /dev/vg0/*. Activez le swap avec « mkswap /dev/vg0/swap && swapon /dev/vg0/swap », puis continuez l’installation classique du système. Après la compilation du noyau, il est inutile de l’installer, car nous n’utiliserons de toutes façons pas le /boot. À la place, installez sys-kernel/dracut, qui se chargera de générer un initramfs tout beau pour vous. Mais avant, spécifiez les modules que vous souhaitez compiler (j’indique mon propre choix, utile pour cette installation) :

echo 'DRACUT_MODULES="crypt crypt-gpg lvm"' >> /etc/make.conf
echo 'sys-kernel/dracut device-mapper' >> /etc/portage/package.use
emerge -va dracut

Ensuite, il vous faut un support amovible, tel qu’une bête clé USB. Commençons par effacer son MBR : après l’avoir insérée, et vérifié son nom de device (ici, /dev/sdb), installez syslinux, puis tapez :

emerge -va syslinux
dd if=/dev/zero of=/dev/sdb bs=1024k count=5 conv=notrunc
mke2fs -m0 /dev/sdb1
mkdir tempdir && cd tempdir
cp /usr/portage/distfiles/syslinux-*.tar.bz2 .
tar -xvjf syslinux-*.tar.bz2
cd syslinux-*
cat mbr/mbr.bin > /dev/sdb
mkdir /mnt/usb
mount /dev/sdb1 /mnt/usb
cd /mnt/usb
cp /usr/src/linux/arch/<arch>/boot/bzImage . #remplacez <arch> par votre architecture
cp syslinux-<version>/com32/menu/menu.c32 .
cp chemin/vers/sda1.gpg .

Il ne reste plus qu’à générer l’initramfs avant de rendre le médium bootable. À ce stade, vous êtes toujours en chroot, avec un système dont il y fort à parier dont le noyau diffère de celui que vous venez de compiler. Dracut va donc logiquement couiner, ne trouvant pas les modules du noyau actuel. Il faut donc d’abord générer les dépendances de modules pour le noyau actuel, puis générer l’initramfs en lui indiquant le bon répertoire pour les modules :

depmod `uname -r`

Avant d’utiliser dracut, on va le configurer un peu, histoire de s’assurer qu’il chargera les bons modules (ça serait bête de ne pas pouvoir utiliser gpg, par exemple). Tout ce que j’ai eu à faire a été de modifier cette ligne dans /etc/dracut.conf :

add_dracutmodules+="crypt crypt-gpg lvm dm selinux"

Nous sommes enfin prêts à générer l’image.

dracut -k /lib/modules/`uname -r`
mv initramfs-* initramfs-`uname -r`.img

Il nous reste cependant à configurer le programme de démarrage, extlinux. Créez un fichier extlinux.conf dans /mnt/usb, et adaptez son contenu selon le mien :

DEFAULT menu.c32
TIMEOUT 100
PROMPT 0
LABEL Gentoo
    MENU LABEL Gentoo ^Linux
    MENU DEFAULT
    KERNEL bzImage
    APPEND root=/dev/vg0/root rd.luks.key=/sda1.gpg initrd=initramfs-<version>.img

Vérifiez scrupuleusement les paramètres de boot, dans « APPEND ». Ils sont la principale source de boot foireux. Si vous désirez choisir une keymap précise (par défaut, ce sera en qwerty), ajoutez « vconsole.keymap=<keymap> », en insérant le nom de la keymap, fr-dvorak-bepo pour moi. On finit donc :

extlinux .
cd
umount /mnt/usb
sync

Et on tente le reboot. Naturellement, vérifiez que votre BIOS vous permet de booter sur un support amovible. N’oubliez d’ailleurs pas de brancher ledit support, ça évitera un arrachage de cheveux tout à fait inopportun. Si vous avez bien fait les choses, un joli menu s’affichera, vous proposant de booter votre noyal. Après validation, celui-ci se chargera, exécutera l’initramfs, qui analysera alors le disque, et, trouvant le keyfile que vous lui avez indiqué, vous demandera sa passphrase. Méfiez-vous de la keymap, si vous ne l’avez pas fixée manuellement. Ensuite, le système continue paisiblement son boot. Félicitations, vous venez de faire un pas de plus vers la paranoïa sécuritaire.

Gentoo, GNU/Linux libre ?

Pour finir, deux mots sur l’astuce évoquée, pour bénéficier d’un système 100% libre selon les termes très stricts de la FSF. Si vous êtes habitué de Portage, vous savez qu’il connaît la licence de chaque paquet, et que, si vous tentez d’installer certains programmes pas trop libres, il vous demandera d’accepter explicitement cette nouvelle licence. Et bien Portage permet de définir la politique d’acceptation des licences, et c’est très bien fait, car il possède des « sets » de licences, permettant de les trier facilement. Il suffit de spécifier votre choix dans /etc/make.conf. Par exemple, j’ai opté pour ça :

ACCEPT_LICENCE="-* @FREE"

Ce qui n’accepte que les programmes sous licence libre agréée par la FSF. Comme vous pouvez le voir, c’est simplissime. Il y a encore une chose à faire : le noyau Linux contient, dans ses sources officielles, des morceaux de code binaire non libre, essentiellement des drivers. Il existe un script permettant d’analyser les sources, de débusquer ces blobs et de les supprimer. Ainsi, les sources que vous compilerez seront propres. Naturellement, ça implique de se passer desdits drivers. Encore une fois, Portage nous vient en aide, puisqu’il offre un USE flag disponible sur tous les noyaux (par exemple sys-kernel/hardened-sources pour moi).

echo 'sys-kernel/hardened-sources deblob' >> /etc/portage/package.use
emerge -va hardened-sources

Et voilà le travail. Le script met un peu de temps à faire son boulot, mais ensuite, votre noyau ne contiendra que du logiciel libre ! Et avec les 2 astuces combinées, vous êtes certain de ne pas ajouter de logiciels non-libres sur votre système, hormis exceptions explicitement créées.


Powered by VroumVroumBlog 0.1.31 - RSS Feed
Download config articles