====== Serveur Debian chiffré (FDE) avec déchiffrement distant ====== Nous allons utiliser **dropbear**, un serveur ssh avec la particularité de pouvoir fonctionner dans l'initramfs, c'est-à-dire la partie du disque non-chiffrée qui est accessible au démarrage de la machine sur le réseau et permet de débloquer le disque chiffré à distance. Sans cela, il faudrait se déplacer physiquement sur le serveur pour entrer la phrase de passe sur un clavier. //Note// : FDE est l'acronyme de "Full Disk Encryption" (chiffrement intégral du disque). //Pré-requis// : Un serveur avec Debian installé en mode "[[https://debian-handbook.info/browse/fr-FR/stable/sect.installation-steps.html#sect.install-partman|Utiliser tout un disque avec LVM Chiffré]]". ===== Sources & Documentation ===== * [[https://github.com/lhost/pkg-cryptsetup-debian/blob/master/debian/README.remote|Documentation officielle sur le déchiffrement distant]] * [[http://wiki.faimaison.net/doku.php?id=projets:wifi:ateliers:4_raid_luks_lvm|Notes sur install RAID + LVM + FDE chez FAImaison]] * [[https://rootlogin.ch/howto_en/installing_debian_jessie_with_encrypted_lvm_and_softraid/|How-To chez rootlogin.ch]] * [[https://projectgus.com/2013/05/encrypted-rootfs-over-ssh-with-debian-wheezy/|How-To chez projetgus.com]] * [[https://sowhatisthesolution.wordpress.com/2016/03/20/unlock-luks-via-ssh-in-debian/|How-To chez sowhatisthesolution.wordpress.com (Unlock LUKS via SSH in Debian)]] * [[https://www.theo-andreou.org/?p=1579|How-To chez How to theo-andreou.org (remotely decrypt a LUKS encrypted)]] * [[https://hamy.io/blog/remote-unlocking-of-luks-encrypted-root-in-ubuntu-debian/|How-To chez hamy.io (Remote unlocking of LUKS-encrypted root in Ubuntu/Debian)]] ===== Installation de dropbear ===== apt install dropbear ==== Avec Jessie (debian 8) ==== L'installation de ''dropbear'' génère une paire de clés ssh mais qui sont stockées sur la partie non-chiffrée du disque. Il faut donc vider les clés autorisées à se connecter sur l'initramfs echo "" > /etc/initramfs-tools/root/.ssh/authorized_keys et supprimer les clés ssh générées par l'installation de dropbear rm /etc/initramfs-tools/root/.ssh/id_rsa* Ensuite, il faut ajouter les clés ssh autorisées à se connecter pour déchiffrer le disque au fichier ''/etc/initramfs-tools/root/.ssh/authorized_keys'' (cela peut être une copie de ''~/.ssh/authorized_keys'', par exemple à condition que vous ayez copié votre clé publique dans ce fichier). ==== À partir de stretch (debian 9) ==== L'installation de ''dropbear'' entraîne l'installation d'un paquet complémentaire ''dropbear-initramfs''. Les clés autorisées à se connecter sur l'initramfs ne sont plus générées automatiquement, elles seront à ajouter dans ''/etc/dropbear-initramfs/authorized_keys''. C'est pourquoi à la fin de l'installation ou si l'on reconstruit l'initramfs avant d'avoir ajouter les clés, on a un message nous indiquant : dropbear: WARNING: Invalid authorized_keys file, remote unlocking of cryptroot via SSH won't work! ===== Ajout du pilote de la carte réseau à l'initram-fs ===== //Note : Cette étape n'est pas obligatoire sur toutes les machines, le pilote de la carte réseau étant déjà chargé dans certains cas. // Pour cela, il faut détecter le pilote avec la commande # "e*" permet de fonctionner avec l'ancien (eth*) et le nouveau (enps*) nommage des interfaces. grep DRIVER /sys/class/net/e*/device/uevent qui retourne par exemple DRIVER=r8169 et l'ajouter au fichier ''/etc/initramfs-tools/modules'' (uniquement le nom du driver ''r8169'' ici). Cela peut se faire en une seule ligne grep DRIVER= /sys/class/net/e*/device/uevent | cut -d= -f2 >>/etc/initramfs-tools/modules ===== Configuration de l'initramfs ===== //Note : La configuration décrite ci-après est réalisée dans le fichier ''/etc/initramfs-tools/initramfs.conf'', mais pour éviter des surprises vis à vis des mises à jour Debian, il serait préférable d'utiliser un autre fichier comme par exemple ''/etc/initramfs-tools/conf.d/dropbear-fde-unlock''.// Pour savoir quelle partition a été chiffrée, utiliser la commande ''lsblk''. ==== Avec Jessie (debian 8) ==== Certaines des informations demandées ci-après (comme l'adresse IP) et qui sont spécifiques à votre machine se trouvent dans le fichier ''/etc/network/interfaces'', s'y référer donc. Éditer le fichier ''/etc/initramfs-tools/initramfs.conf'' et ajouter les lignes suivantes : # enable dropbear explicitly DROPBEAR=y //(ligne ci-dessus à ajouter si non déjà présente dans le fichier)// # network configuration. # network module is loaded by /etc/initramfs-tools/modules # IP should be like IP=::::::off DEVICE=eth0 IP=111.222.333.444::111.222.333.254:255.255.255.0::eth0:off Notez que les valeurs '''' et suivantes doivent être remplacées par les vôtres et que la présence de ''::'' avant '''' permet d'omettre la valeur de '''' par facilité. Reconstruire l'initramfs (à faire après chaque modification) update-initramfs -u Enfin, il faut forcer l'extinction de l'interface réseau allumée par le initramfs avant sa réactivation par le système principal. Ajouter ceci dans la spécification de l'interface, dans le fichier ''/etc/network/interfaces'', en dessous la règle ''iface'' : pre-up ip addr flush dev eth0 # pre-up ifdown eth0 ==== À partir de stretch (debian 9) ==== Le fonctionnement est identique, à ceci près : === Activer dropbear dans l'initramfs === ''dropbear'' est activé par défaut, il n'est donc pas nécessaire d'ajouter la ligne suivante au fichier ''/etc/initramfs-tools/initramfs.conf'' : # enable dropbear explicitly DROPBEAR=y === Forcer l'extinction de l'interface réseau === Il n'est plus utile de forcer //manuellement// l'extinction de l'interface réseau, car c'est désormais le comportement par défaut (voir l'option ''IFDOWN'' dans ''/etc/dropbear-initramfs/config''). Extrait du changelog de la version 2015.68-1 de dropbear : Bring down interfaces and flush IP routes and addresses before exiting the ramdisk, to avoid dirty network configuration in the regular kernel. (Closes: #715048, #720987, #720988.) The interfaces considered are those matching the $DROPBEAR_IFDOWN shell pattern (default: '*'); the special value 'none' keeps all interfaces up and preserves routing tables and addresses. ==== Variante ===== ''DROPBEAR=y'' et ''DEVICE=eth0'' étant les valeurs par défaut, il est possible de définir la configuration réseau via le Grub. Pour cela il faut éditer le fichier ''/etc/default/grub'' et ajouter la ligne suivante # GRUB_CMDLINE_LINUX="ip=::::::" GRUB_CMDLINE_LINUX="ip=111.222.333.444::111.222.333.254:255.255.255.0::eth0:off" Puis recharger la configuration de Grub update-grub //Note : // Il est cependant nécessaire de reconstruire l'initramfs (''update-initramfs -u'') suite à la suppression des clés générées par dropbear et à l'ajout du pilote réseau. ===== Connexion à la machine ===== * seul l'utilisateur ''root'' peut se connecter à dropbear * il est possible de remplacer le message ''FDE passphrase'' par le message que l'on souhaite ==== Avec Jessie (debian 8) ==== ssh -t -o UserKnownHostsFile=~/.ssh/machine_known_hosts root@machine "/lib/cryptsetup/askpass 'FDE Passphrase : ' > /lib/cryptsetup/passfifo" avec machine = IP de la machine Explications : * L'utilitaire ''/lib/cryptsetup/askpass'' permet de demander une phrase de passe que l'on peut personnaliser (en remplaçant '''FDE Passphrase : ' '' par le message souhaité) * La phrase de passe est écrite dans le [[https://fr.wikipedia.org/wiki/Tube_nomm%C3%A9|fifo]] ''/lib/cryptsetup/passfifo'' (sur le serveur) au sein duquel le programme de déverrouillage du disque la lit ; * Un fichier //KnownHost// spécifique est utilisé car la clé ssh du serveur diffère entre l'initramfs et le root filesystem. Notez qu'il est possible de se connecter simplement en ssh à la machine (''ssh -o UserKnownHostsFile=~/.ssh/machine_known_hosts root@machine'') puis de saisir la commande ''/lib/cryptsetup/askpass 'FDE Passphrase : ' > /lib/cryptsetup/passfifo'' pour entrer sa phrase de passe. ==== À partir de stretch (debian 9) ==== On peut toujours se connecter avec la méthode décrite, ci-dessus, mais désormais le paquet cryptsetup inclut un script de déverrouillage complémentaire (cf. ''/usr/share/cryptsetup/initramfs/bin/cryptroot-unlock'' et ''/usr/share/initramfs-tools/hooks/cryptroot-unlock''), que l'on peut définir comme [[https://man.openbsd.org/sshd.8#command=%22command%22|unique commande proposée à la connexion]]. Pour cela, on ajoute la clé ssh autorisée à se connecter au boot, avec les commandes suivante : # echo -n "command=\"/bin/cryptroot-unlock\" " > /etc/dropbear-initramfs/authorized_keys # cat /home/.ssh/id_rsa.pub >> /etc/dropbear-initramfs/authorized_keys ou avec votre éditeur de texte préféré. Dès lors, pour se connecter, il suffit de lancer : ssh -t -o UserKnownHostsFile=~/.ssh/machine_known_hosts root@machine ==== Configuration persistante de SSH ==== SSH permet de définir des [[http://www.delafond.org/traducmanfr/man/man5/ssh_config.5.html|configurations par défaut]] dans le fichier ''~/.ssh/config''. Dans notre cas nous pouvons configurer l'utilisation d'un fichier //KnownHost// spécifique pour cette machine, ainsi que d'autres paramètres. Exemple : Host machine-initrd PasswordAuthentication no IdentityFile ~/.ssh/id_rsa User root Hostname machine.example.org UserKnownHostsFile ~/.ssh/machine_known_hosts StrictHostKeyChecking yes Ensuite, suffit de faire : ssh machine-initrd -t "/lib/cryptsetup/askpass 'FDE Passphrase : ' > /lib/cryptsetup/passfifo" //À noter qu'une fois la passphrase entrée, la connexion ssh est coupée étant donnée que la machine se lance et se déchiffre.// ==== Et en IPv6 ? ==== Le serveur SSH dans l'initrd écoute également par défaut en IPv6. Cela signifie : * Si vous avez de l'[[http://mirrors.deepspace6.net/Linux+IPv6-HOWTO-fr/x2027.html|auto-configuration IPv6]] sur votre réseau, vous pourrez utiliser l'adresse publique de votre machine pour la déverrouiller à distance. * En étant sur le même LAN que votre machine, vous pouvez utiliser l'adresse [[https://fr.wikipedia.org/wiki/Adresse_IPv6#Cat.C3.A9gories_d.27adresses|link-local]] de votre machine pour la déverrouiller. ===== Complément et alternative ===== ==== Activer l'output de Grub sur la console ==== Dans certains cas, si vous utiliser du SoL (Serial over Lan) par exemple, et que vous avez besoin de debugger la séquence de boot, il peut-être utile de rediriger l'output de grub vers la console. Voici comment faire: vi /etc/default/grub GRUB_CMDLINE_LINUX="ip=111.222.333.444::111.222.333.254:255.255.255.0::eth0:off console=ttyS1,9600" Ne pas oublier: update-grub ==== Nommage des interfaces réseau ==== En prévention de l'arrivée de la version GNU/Linux Debian (Buster), actuellement en stable sur stretch, vous pourriez avoir des surprises quant à la déclaration du nom de votre interface réseau. Buster, implémente les [[https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/|PredictableNetworkInterfaceNames]]. De fait, si vous avez suivi ce tutoriel, vous aurez renseigné "eth0" dans la configuration de grub. Et donc, nous vous conseillions de désactiver, provisoirement ou non, le renommage des interfaces. Cela ce fait par un argument à passer au kernel au moment du boot. vi /etc/default/grub GRUB_CMDLINE_LINUX_DEFAULT="net.ifnames=0" De fait, le nommage en eth0 sera conservé. Ne pas oublier: update-grub ==== Sécurisation de dropbear-initramfs ==== À partir de debian 9, il y a une configuration spécifique pour le paquet ''dropbear-initramfs''. Sans rien y toucher ça marche, mais il est possible d'ajouter quelques options, dans le fichier ''/etc/dropbear-initramfs/config'', pour sécuriser le tout. Quelques options extraites de ''man dropbear'' : | **-p** | Listen on specified TCP port. | | **-s** | Disable password logins. | | **-j** | Disable local port forwarding. | | **-k** | Disable remote port forwarding. | | **-I** | Disconnect the session if no traffic is transmitted or received for n seconds. | La ligne ''#DROPBEAR_OPTIONS='' dans le fichier de config peut donc devenir : ''DROPBEAR_OPTIONS=-w -s -j -k -I 60''. ==== Cohabitation dropbear et openssh ==== Avec la mise en place de dropbear, du point de vue du client SSH on se connecte deux fois de suite sur la même ip+port en ssh, mais sur deux serveurs SSH (dropbear, puis openssh-server) identifiés par des clés différentes (côté serveur). Ces clés sont stockées par le client SSH dans ~/.ssh/known_hosts et vérifiées à la connexion. Pour éviter que notre client SSH ne crie à chaque connexion croyant que l'on ne se connecte pas à la même machine, il y a //au moins// deux possibilités : * Utiliser un fichier known_hosts spécifique, comme détaillé au paragraphe [[debian-fde-dropbear#Connexion à la machine|Connexion à la machine]]. * Définir un port de connexion différent pour dropbear en utilisant l'option ''-p'' dans le fichier ''/etc/dropbear-initramfs/config'' (cf. [[debian-fde-dropbear#Sécurisation de dropbear-initramfs|Sécurisation de dropbear-initramfs]]). ===== Le cas particulier d'une Brique Internet ===== Dropbear est déjà installé et utilisé sur les installations chiffrées de la Brique Internet, donc pas besoin de l'installer. Et vis-a-vis des explications précédentes, la brique fonctionne avec u-boot et non grub comme gestionnaire de démarrage. Ouvrir ''/etc/initramfs-tools/root/.ssh/authorized_keys'' et y copier le contenu de ''~/.ssh/authorized_keys'' (en espérant que vous aviez précédemment [[https://yunohost.org/#/security_fr|sécurisé la connexion ssh par clé]]) : vi /etc/initramfs-tools/root/.ssh/authorized_keys Découvrir quel est le driver utilisé par l'interface réseau ethernet eth0 : grep DRIVER /sys/class/net/eth0/device/uevent qui donne ''DRIVER=stmmaceth'' par exemple Et ajouter le résultat de la commande précédente (stmmaceth) dans le fichier ''/etc/initramfs-tools/modules'' : vi /etc/initramfs-tools/modules //(c'est en prévention, cela marche aussi généralement sans)// Et finalement compléter le fichier ''/etc/initramfs-tools/initramfs.conf'' : vi /etc/initramfs-tools/initramfs.conf pour y ajouter : # network configuration. # network module is loaded by /etc/initramfs-tools/modules # IP should be like IP=::::::off DEVICE=eth0 IP=89.234.176.xxx::89.234.176.193:255.255.255.24::eth0:off (ici, exemple de configuration pour rackage dans le DC, remplacer xxx par l'IP) Et reconstruire l'initramfs avec ces informations (pas besoin de plus pour la configuration de u-boot) : update-initramfs -k all -u N'oubliez pas de configurer la connexion réseau ''une fois la brique déchiffrée'' comme [[machine-adherent#reseau|expliqué ici]] avant de continuer la procédure ===== Limites ===== Il est important de se rappeler les limites d'une telle méthode. Si un attaquant obtient un accès root au système, il peut obtenir la clé de chiffrement (''dmsetup table --showkeys'') et n'a plus besoin de découvrir la phrase de passe. Il est également possible de récupérer la clé de chiffrement en mémoire via [[https://citp.princeton.edu/research/memory/|dump de la mémoire après redémarrage]]. Dans tous les cas, cela rend l'opération plus compliquée que simplement partir avec la machine, donc c'est bien mais ça a ses limites. À noter aussi, [[http://www.recompile.se/mandos|Mandos]] peut servir à automatiser l'opération. ===== Ajouter, modifier et supprimer des phrases de passes ===== Il est possible d'avoir jusqu'à 8 phrases de passes différentes pour la même partition chiffrée. ==== Détecter la partition chiffrée avec lsblk ==== # lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT fd0 2:0 1 4K 0 disk sda 8:0 0 20G 0 disk ├─sda1 8:1 0 243M 0 part /boot ├─sda2 8:2 0 1K 0 part └─sda5 8:5 0 19.8G 0 part └─sda5_crypt 254:0 0 19.8G 0 crypt ├─foo--vg-root 254:1 0 3.5G 0 lvm / ├─foo--vg-var 254:2 0 2G 0 lvm /var ├─foo--vg-swap_1 254:3 0 1G 0 lvm [SWAP] ├─foo--vg-tmp 254:4 0 364M 0 lvm /tmp └─foo--vg-home 254:5 0 13G 0 lvm /home sr0 11:0 1 290M 0 rom sr1 11:1 1 1024M 0 rom La partition chiffrée est donc ''sda5''. ''sda5_crypt'' est la partition obtenue suite au **déchiffrement** de la partition chiffrée. On peut vérifier que la partition est bien une partition Luks avec la commande suivante : # cryptsetup -v isLuks /dev/sda5 Command successful. # cryptsetup -v isLuks /dev/sda1 Device /dev/sda1 is not a valid LUKS device. Command failed with code 22: Invalid argument # cryptsetup -v isLuks /dev/mapper/sda5_crypt Device /dev/mapper/sda5_crypt is not a valid LUKS device. Command failed with code 22: Invalid argument Toutes les commandes ''cryptsetup'' sont donc à exécuter sur la partition ''/dev/sda5''. ==== Pour ajouter une phrase de passe : ==== # cryptsetup -v luksAddKey /dev/sda5 Enter any existing passphrase: ********* Key slot 1 unlocked. Enter new passphrase for key slot: ********* Verify passphrase: ********* Key slot 1 unlocked. Command successful. ==== Pour supprimer une phrase de passe : ==== # cryptsetup -v luksRemoveKey /dev/sda5 Enter passphrase to be deleted: ****** Key slot 0 unlocked. Key slot 0 selected for deletion. Command successful. Dans le cas où la passphrase n'existerait pas ou serait incorrecte: # cryptsetup -v luksRemoveKey /dev/sda5 Enter passphrase to be deleted: No key available with this passphrase. Command failed with code 1: Operation not permitted ==== Pour modifier une phrase de passe : ==== - Ajouter une nouvelle phrase de passe. - :!: rebooter pour tester la nouvelle phrase de passe (ignorez cette étape à vos risques et périls) - Supprimer l'ancienne phrase de passe.