Outils pour utilisateurs

Outils du site


debian-fde-dropbear

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 “Utiliser tout un disque avec LVM Chiffré”.

Sources & Documentation

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=<local_IP>::<gw_IP>:<netmask>:<hostname>:<network_interface>:off
  DEVICE=eth0
  IP=111.222.333.444::111.222.333.254:255.255.255.0::eth0:off

Notez que les valeurs <local_IP> et suivantes doivent être remplacées par les vôtres et que la présence de :: avant <network_interface> permet d'omettre la valeur de <hostname> 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=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>"
  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 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 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/<username>.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 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'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 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 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 :

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 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=<local_IP>::<gw_IP>:<netmask>:<hostname>:<network_interface>: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 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 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, 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 :

  1. Ajouter une nouvelle phrase de passe.
  2. :!: rebooter pour tester la nouvelle phrase de passe (ignorez cette étape à vos risques et périls)
  3. Supprimer l'ancienne phrase de passe.
debian-fde-dropbear.txt · Dernière modification : 2018/12/14 11:02 de kippix