PROJET AUTOBLOG


Gordon

source: Gordon

⇐ retour index

Installation de Proxmox avec chiffrement de disque

dimanche 21 février 2016 à 00:00

Suite à l’installation d’une nouvelle machine en datacenter, j’ai souhaité dépoussiérer mon utilisation de Proxmox, et réfléchir à ce qui pouvait être fait pour améliorer mes précédentes utilisations, du point de vue de la sécurité.

Première installation test

Dès ma machine reçue (un Dell R210), j’ai téléchargé une image Proxmox pour l’installer. Étant frileux sur l’adoption de SystemD, j’ai opté pour une version 3.4 de Proxmox, basée sur Debian-oldstable, et donc sous SysVinit. Je précise au passage que je dispose de deux disques durs dans cette machine, et que je souhaite utiliser du RAID1 soft afin de sécuriser mes données (dans le sens « ne pas les perdre suite à une panne »). À savoir que l’installeur Proxmox ne supporte pas le RAID soft(en) lors d’une installation bare-metal.

Bref, lors de l’installation, je remarque l’ajout d’options « ZFS » en tant que système de fichier supporté pour le formatage. Excellente nouvelle, car ZFS gère la création de systèmes en miroir, en alternative à dm-raid. Encore mieux, Proxmox propose, si on utilise ZFS, de créer une grappe en miroir, et donc de tout gérer de lui-même.

J’opte donc pour cette approche. J’installe Proxmox, je le configure, puis je crée un conteneur pour tester mes repères (et les performances de la machine). Ça fonctionne, très bien. Étant donné que c’est à ce moment que FAImaison s’installe en datacenter, j’en profite pour racker ma machine et jouer le rôle de beta-testeur pour l’association. Ce qui se traduit par un succès, grâce aux adminsys qui ont fait un super boulot. Bref, ça marche. Sauf qu’il y a un problème important : je n’ai pas chiffré le disque, lors de l’installation. Étant donné que cette machine sera vouée à héberger mes données, ce n’est pas un état de fait acceptable.

Approche naïve

Je planifie donc une intervention au datacenter, avec cet objectif : copier intégralement le contenu des disques sur un disque externe, puis reformater les partitions ZFS pour créer une partition LUKS, puis restaurer les partitions ZFS mirrorées sur les conteneurs LUKS ouverts. Piece of cheese, comme disent les auvergnats. Sauf que c’était la théorie.

La pratique a donc été constituée d’une heure et demi de galère pour réussir à simplement démarrer une clé USB live (Ubuntu, en l’occurrence), sur la machine. Je m’en suis sorti en activant l’UEFI dans le BIOS du serveur. Ensuite est venue la consternation en constatant le schéma de partitionnement d’un des disques :

root@fromage:~/# parted -l
Model: ATA WDC WD5003ABYX-1 (scsi)
Disk /dev/sda: 500GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End     Size    File system  Name  Flags
 1      17.4kB  1049kB  1031kB                     bios_grub
 2      1049kB  500GB   500GB   zfs          zfs
 9      500GB   500GB   8389kB


Model: ATA WDC WD5003ABYX-1 (scsi)
Disk /dev/sdb: 500GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End     Size    File system  Name  Flags
 1      17.4kB  1049kB  1031kB                     bios_grub
 2      1049kB  500GB   500GB   zfs          zfs
 9      500GB   500GB   8389kB


Model: Unknown (unknown)
Disk /dev/zd0: 16.1GB
Sector size (logical/physical): 512B/4096B
Partition Table: loop

Number  Start  End     Size    File system     Flags
 1      0.00B  16.1GB  16.1GB  linux-swap(v1)

L’information utile est la suivante : contrairement aux architectures que j’ai l’habitude de traiter en termes de chiffrement de disque, il n’y a pas de partition /boot, mais une seule (par disque) partition ZFS, qui contient toute la racine du système. J’apprends donc que Grub sait démarrer nativement du ZFS.

Le problème, c’est que pour chiffrer la racine du disque, il faut que je puisse sortir le noyau et son image initramfs de là, d’où la partition /boot séparée. Du haut de ma connaissance moyenne de ZFS, je n’étais pas suffisamment à l’aise pour tenter une modification à la volée du schéma de partitionnement. Donc, impasse pour cette approche.

Approche idéale : utilisation de chiffrement intégré à ZFS

Il faut savoir que ZFS était un projet de Sun, initialement. Sun ayant été racheté par le mal absoluOracle, leur branche de ZFS a très vite perdu sa licence libre. Aujourd’hui, seule cette branche supporte le chiffrement intégré. Les versions intégrées à FreeBSD et GNU/Linux n’en disposent pas, et ce n’est visiblement pas prêt d’arriver. Seconde impasse.

Approche de compromis

À ce stade, je commençais à me rendre compte qu’une réinstallation de la machine était indispensable, et qu’il faudrait abandonner ZFS. Je me suis alors renseigné sur l’état du chiffrement intégré à Ext4(en), existant depuis la version 4.1 du noyau Linux. Cet article(en) m’a fait comprendre que l’implémentation n’était pas tout à fait sèche, et qu’elle partageait notamment la faiblesse de conception d’eCryptFS(en), c’est à dire que seul le contenu et le nom des fichiers est chiffré, pas les méta-données (nombre de fichiers, dates d’accès et de modification…). Ne souhaitant pas baser le chiffrement du serveur gérant mes données privées sur un système instable, et étant donné que la version de Proxmox que je souhaitais utiliser avait un kernel trop vieux, je suis passé à autre chose.

Approche standard

Par « standard », j’entends « comme à mon habitude », c’est à dire le formatage à la main, avec un /boot séparé. Donc, plutôt que d’installer Proxmox en bare-metal, il a fallu installer une Debian standard, avec chiffrement, puis, une fois celle-ci opérationnelle, suivre les instructions pour installer Proxmox dessus. Le tout en acceptant finalement de me baser sur la dernière version de Debian, comprenant SystemD.

J’enchaîne donc sur la suite de l’article avec les instructions détaillées sur cette installation.

Installation définitive

D’abord, il nous faut booter sur un installeur Debian. Téléchargez donc celle-ci sur le site officiel, prenez soin de vérifier l’empreinte du fichier (et vérifiez l’intégrité des empreintes.

gordon@fromage:~$ wget http://cdimage.debian.org/debian-cd/8.3.0/amd64/iso-cd/debian-8.3.0-amd64-netinst.iso
[…]
gordon@fromage:~$ wget http://cdimage.debian.org/debian-cd/8.3.0/amd64/iso-cd/SHA512SUMS
[…]
gordon@fromage:~$ wget http://cdimage.debian.org/debian-cd/8.3.0/amd64/iso-cd/SHA512SUMS.sign
[…]
gordon@fromage:~$ gpg --recv-key 6294BE9B
gpg: clef 6294BE9B : clef publique « Debian CD signing key <debian-cd@lists.debian.org> » importée
gordon@fromage:~$ gpg --verify SHA512SUMS.sign
gpg: les données signées sont supposées être dans « SHA512SUMS »
gpg: Signature faite le dim. 24 janv. 2016 19:08:33 CET avec la clef RSA d'identifiant 6294BE9B
gpg: Bonne signature de « Debian CD signing key <debian-cd@lists.debian.org> » [inconnu]
gpg: Attention : cette clef n'est pas certifiée avec une signature de confiance.
gpg:             Rien n'indique que la signature appartient à son propriétaire.
Empreinte de clef principale : DF9B 9C49 EAA9 2984 3258  9D76 DA87 E80D 6294 BE9B
gordon@fromage:~$ sha512sum -c SHA512SUMS --ignore-missing
debian-8.3.0-amd64-netinst.iso: Réussi

Une fois ces vérifications passées avec succès, copiez l’image sur une clé USB avec dd, en prenant soin de ne pas vous planter le nom de périphérique.

# après branchement de la clé USB
root@fromage:~$ dmesg | tail -n 1
[16916.267063] sd 6:0:0:0: [sdb] Attached SCSI removable disk
# ma clé est donc "sdb"
root@fromage:~$ dd if=debian-8.3.0-amd64-netinst.iso of=/dev/sdb bs=1M

Branchez la clé sur le serveur, démarrez dessus et sélectionnez « Expert install ».

Démarrage de
l’installation Debian

Je ne m’étends pas sur l’intégralité de l’installation, si vous n’avez jamais installé de Debian, peut-être que l’installation d’une Proxmox chiffrée est inadaptée pour vous.

Lors de l’étape « Load installer components from CD », prenez soin de choisir crypto-dm-modules et parted-udeb dans la liste.

Sélection des composants d’installation

Continuez jusqu’à l’étape de partitionnement. Choisissez « Manual ». Voici, pour information, ce que nous allons mettre en place.

Schéma de
partitionnement final

Partitionnement manuel

Vous devriez avoir quelque chose de similaire. Au besoin, supprimez les partitions existantes (ou créez une table de partition vierge), pour partir d’un état similaire au mien.

Disques vierges

La toute première étape est de créer deux paires de volumes RAID : un pour le /boot, l’autre pour le volume chiffré qui contiendra nos autres volumes. Commencez donc par créer, dans chaque disque, une partition destinée à être une grappe RAID.

Création des partitions pour /boot

Création des partitions pour /boot

Création des partitions pour /boot

Nous avons maintenant deux partitions destinées au RAID, un sur chaque disque. Nous allons créer le volume pour /boot, puis nous occuper de la suite. Ça se passe dans « Configure software RAID ». Suivez les instructions, sélectionnez bien /dev/sda1 et /dev/sdb1, qui sont les partitions que nous venons de créer.

Création du RAID pour /boot

Prêt à créer /boot

Utilisons ce « RAID1 device #0 » pour créer une partition au format ext2 (pas besoin de journalisation pour un /boot), et assignez-lui le bon point de montage.

Création de /boot

/boot créé

Étape suivante, utiliser l’espace libre restant sur les disques (notez qu’il y a un espace libre d’1Mo avant mon RAID, ce n’est pas lui qui nous intéresse) pour créer une seconde grappe RAID. On peut passer directement par le menu « Configure software RAID ». Cette fois, sélectionnez bien les deux « FREE SPACE », qui devraient de toutes façons être les seuls disponibles.

Création de la grappe RAID principale

RAID créé

C’est maintenant sur la ligne en dessous de « RAID1 device #1 » que nous allons créer le reste. Dans l’ordre : un conteneur LUKS (pour le chiffrement), puis un groupe de volume LVM, puis nos partitions finales.

Allons donc dans « Configure encrypted volumes ». Sélectionnez /dev/md1 comme volume à chiffrer, étant donné que c’est le volume RAID principal (les autres ne sont que les miettes restantes sur les disques, et notre /boot).

Sélection du volume à chiffrer

À la fin de la configuration du volume chiffré, il faudra vous armer d’un peu de patience, car l’installateur écrira des données aléatoires sur l’espace en question, pour nettoyer d’éventuelles anciennes traces de fichiers.

Vient l’épineuse question du choix de la passphrase. Comme d’habitude, choisissez avec soin et ne notez pas cette passphrase. Rappelez-vous pour autant que si vous la perdez, votre serveur est mort.

Volume LUKS créé

Étape suivante, si vous avez suivi : création du groupe de volumes LVM. Ça se fait dans « Configure the Logical Volume Manager ». Créez un « volume group » (je le nomme « vg0 », pas besoin d’être beaucoup plus créatif), puis choisissez votre volume chiffré précédemment créé (/dev/mapper/md1_crypt ici).

Création du groupe de volumes

Une fois le groupe de volume créé, il reste à créer les volumes logiques, soit les partitions finales. Créez-en 3 : 'root', 'data' et 'swap'. Leur signification est claire. Le volume data contiendra /var/lib/vz, soit l’intégralité des VMs de votre serveur. C’est donc lui qui sera logiquement le plus gros. Vous devriez pouvoir vous en sortir avec 20Go pour root si vous disposez de suffisamment de place. Pour swap, l’équivalent de la moitié de votre RAM est correct.

Détail des volumes logiques

Détail des volumes logiques

L’affichage de l’outil de partitionnement commence à sérieusement se complexifier. Rassurez-vous, nous en avons quasiment fini. Il reste à créer les systèmes de fichiers sur les volumes logiques nouvellement créés. J’opte pour XFS. N’oubliez pas de définir le LV swap comme… du swap, ni de définir /var/lib/vz comme point de montage du volume data.

Fin du partitionnement

Nous en avons enfin fini. Enregistrez, puis continuez l’installation. Lors de l’installation du boot loader (Grub), l’installeur m’a renvoyé une erreur, sans trop d’explications. Il semble que l’installeur Debian soit cassé à ce niveau. Pour corriger cela, choisissez « Execute a shell », puis entrez les commandes suivantes :

~ # parted /dev/sda
GNU Parted 3.2
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) set 1 bios_grub on
set 1 bios_grub on
(parted) quit
~ # parted /dev/sdb
GNU Parted 3.2
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) set 1 bios_grub on
set 1 bios_grub on
(parted) quit
~ # exit

Le menu principal réapparaît alors, et vous pouvez donc installer Grub sur /dev/sda. Redémarrez ensuite.

Si tout se passe bien, Grub se lance, puis le système. Vous aurez alors à entrer votre passphrase LUKS pour déverrouiller le volume.

prompt LUKS

Entrez donc la passphrase, le système boote correctement.

Installation complète

C’est bien beau d’avoir un disque entièrement (ou presque) chiffré, mais comment le déverrouiller en cas de reboot, étant donné que la machine est bien au chaud dans un datacenter ? Il est possible de faire démarrer un démon SSH au sein de l’initramfs, qui permet d’entrer la passphrase de façon sécurisée à distance.

Authentifiez-vous donc sur votre système nouvellement installé, il va falloir toucher un peu à la génération de l’initramfs. Je vous conseille la lecture de ces deux pages (1, 2) sur le wiki de FAImaison qui détaillent la procédure. Je vous suggère donc de suivre le déroulé du premier lien, ce que j’ai fait moi-même.

Avant de redémarrer la machine pour tester le déchiffrement à distance, n’oubliez pas d’installer grub sur sdb, pour assurer la redondance des disques (sdb doit pouvoir remplacer sda à la volée) :

root@fromage:~# grub-install /dev/sdb

Dans le fichier /etc/initramfs-update/root/.ssh/authorized_keys que vous avez rempli selon le guide précédent, insérez command="cat - >/lib/cryptsetup/passfifo" (sans oublier l’espace finale) juste avant votre clé (ou avant chacune d’entre elles). Si vous aviez déjà tapé update-initramfs -u, refaites-le pour prendre en compte cette modification.

Si, comme moi, votre système local utilise ZSH comme shell, la commande à base de read -p… ne fonctionnera pas. À la place, utilisez celle-ci (qui fonctionnera même sous bash, et qui prend en compte l’astuce précédente) :

gordon@local:~$ echo -n 'Password: '; read -s pw; echo -n $pw | ssh  -o UserKnownHostsFile=~/.ssh/known_hosts.initramf root@fromage "cat - >/lib/cryptsetup/passfifo"; unset pw

On colle Proxmox par dessus

Maintenant, il reste à suivre bêtement (ou presque) le guide d’installation Proxmox. J’attire votre attention sur un détail : lorsqu’il faut ajouter le dépôt Proxmox sur APT, on vous demande d’ajouter la clé GPG utilisée pour signer les paquets. Et la commande pour le faire est…

wget -O- "http://download.proxmox.com/debian/key.asc" | apt-key add -

Comme vous pouvez le voir, on vous recommande d’importer une clé GPG depuis un serveur web non sécurisé. Pour rappel, vérifier l’intégrité des paquets grâce à cette clé vous permet d’éviter d’installer des programmes réécrits par des tiers, un peu comme peut l’être cette clé. En résumé, c’est une très mauvaise pratique d’importer cette clé de cette façon-là, car rien ne vous garantit que c’est la bonne.

Alors, que se passe-t-il si on essaie tout simplement de rajouter un « s » sur « http » ? Et bien, le certificat TLS est invalide, car il appartient à enterprise.proxmox.com et proxmox.com. Par ailleurs, le serveur web ne renvoie pas vers la même page. Impossible donc de récupérer la clé GPG de façon fiable par ce biais.

Pour l’instant, le seul moyen (largement détourné) pour m’assurer de la fiabilité de cette clé est le suivant :

1) Je télécharge l’ISO bare-metal de Proxmox sur https://www.proxmox.com/en/downloads/item/proxmox-ve-4-1-iso-installer-bittorrent

2) Je vérifie l’empreinte (MD5, c’est très faible voir troué…) du fichier en conformité avec celle indiquée sur la page (attention à la consulter en HTTPS)

3) J’installe cette version de Proxmox dans une VM

4) Dans cette VM, je lance :

root@proxmox:~# apt-key list | grep -A2 proxmox
/etc/apt/trusted.gpg
--------------------
pub   1024D/9887F95A 2008-10-28
uid                  Proxmox Release Key <proxmox-release@proxmox.com>
sub   2048g/A87A1B00 2008-10-28

5) L’ID court étant faible, je vérifie l’empreinte de cette clé, et je la compare avec celle fournie en ligne :

root@proxmox:~# apt-key export 9887F95A | gpg --import -a
gpg: key 9887F95A: public key "Proxmox Release Key <proxmox-release@proxmox.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1
root@proxmox:~# gpg --fingerprint 9887F95A
pub   1024D/9887F95A 2008-10-28
      Key fingerprint = BE25 7BAA 5D40 6D01 157D  323E C23A C7F4 9887 F95A
uid                  Proxmox Release Key <proxmox-release@proxmox.com>
sub   2048g/A87A1B00 2008-10-28

6) Ensuite, sur la machine que je suis en train d’installer :

root@fromage:~# wget "http://download.proxmox.com/debian/key.asc"
[…]
root@fromage:~#  gpg --with-fingerprint key.asc 
pub  1024D/9887F95A 2008-10-28 Proxmox Release Key <proxmox-release@proxmox.com>
      Key fingerprint = BE25 7BAA 5D40 6D01 157D  323E C23A C7F4 9887 F95A
sub  2048g/A87A1B00 2008-10-28

7) Enfin, je compare les deux empreintes. Ici, elles sont identiques, mais vérifiez bien par vous-mêmes. Ici, la faiblesse est l’empreinte MD5 de l’ISO. Si ça peut aider, je mets à disposition la clé en question, signée par mes soins, et hébergée sur mon serveur où vous pouvez la récupérer en HTTPS. Si vous me faites confiance (en général, ne le faites pas), ça peut vous faciliter la tâche.

Maintenant que vous avez la possibilité de récupérer les paquets de Proxmox et que vous avez un moyen de savoir que ce sont les bons, continuez de suivre le guide d’installation, vous ne devriez plus rencontrer de problèmes.

Et voilà, vous disposez maintenant d’un serveur chiffré, que vous pouvez déverrouiller proprement à distance, prêt à héberger vos services !