Table des matières
Ceci est une ancienne révision du document !
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).
À partir de stretch (debian 9)
L'installation de dropbear
entraine 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 detecter 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
Avec Jessie (debian 8)
Éditer le fichier `/etc/initramfs-tools/initramfs.conf` et ajouter les lignes suivantes :
# enable dropbear explicitly DROPBEAR=y
# 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
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, qu'il n'est pas utile d'ajouter la ligne :
# enable dropbear explicitly DROPBEAR=y
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
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 - 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.
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.
Mise en place avec debian 9 (stretch)
Paragraphe en attente de relecture
Côté serveur
Installation
# apt install dropbear
- À noter :
- Le paquet
dropbear-initramfs
est installé en tant que dépendance. - Le paquet
busybox
est lui normalement déjà présent, car installé en tant que dépendance decryptsetup
(dépendance Recommends). Dans le cas contraire, il faut l'installer aussi.
Configuration
dropbear
- Configuration générale
Avec cette configuration, 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, nous allons utiliser des ports de connexion différent pour dropbear et openssh-server.
La configuration se fait en éditant le fichier /etc/dropbear-initramfs/config, où l'on va remplacer la ligne :
#DROPBEAR_OPTIONS=
par
DROPBEAR_OPTIONS=-p 4748 -w -s -j -k -I 60
Ce qui peut être fait en une commande, avec :
# sed -i.bak 's/#DROPBEAR_OPTIONS=/DROPBEAR_OPTIONS="-p 4748 -s -j -k -I 60"/' /etc/dropbear-initramfs/config
Explication des options :
-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. |
- Authentification
Le paquet cryptsetup permet l'inclusion d'un script de déverrouillage (cf. /usr/share/cryptsetup/initramfs/bin/cryptroot-unlock
et /usr/share/initramfs-tools/hooks/cryptroot-unlock
).
Avec l'utilisation des options, ci-dessus, l'accès est limité à une connexion avec clé et en complément, cette clé ne pourra utiliser qu'une seule commande, celle permettant de déverrouiller la partition (cryptroot-unlock
).
On ajoute la clé ssh avec les commandes suivante :
# printf "%s" "no-port-forwarding,no-agent-forwarding,no-X11-forwarding,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é.
IP statique
Pour qu'une IP de connexion soit disponible dès le boot, nous allons définir une IP statique dans le fichier /etc/initramfs-tools/initramfs.conf
.
- Identifier le nom de l'interface réseau
$ ip -o a s | cut -d " " -f 2,7
- Ajout du pilote de la carte réseau à l'initramfs (au cas où)
Remplacer <ifname> par votre interface et lancer :
# grep "DRIVER=" /sys/class/net/<ifname>/device/uevent | cut -d= -f2 >> /etc/initramfs-tools/modules
- Ajout de l'IP statique
Éditer le fichier /etc/initramfs-tools/initramfs.conf et remplacer la ligne
DEVICE=
par
# 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=enp2s0 IP=111.222.333.444::111.222.333.254:255.255.255.0::enp2s0:off
- Forcer l'extinction de l'interface
Enfin, il faut forcer l'extinction de l'interface réseau allumée depuis l'initramfs avant sa réactivation par le système principal.
Pour cela, ajouter la règle suivante dans la configuration de l'interface (/etc/network/interfaces) :
pre-up ip addr flush dev enp2s0
Ce qui nous donne :
allow-hotplug enp2s0 iface enp2s0 inet static pre-up ip addr flush dev enp2s0 address 111.222.333.444 gateway 111.222.333.254 netmask 255.255.255.0 dns-nameservers 111.222.333.254
Reconstruire l'initramfs
Notre configuration est en place, il ne reste plus qu'à reconstruire l'initramfs :
# update-initramfs -u
Et côté client
Configuration
SSH permet de définir des configurations par défaut dans le fichier ~/.ssh/config. Dans notre cas, la configuration pourrait être de ce type :
Host host-init Hostname machine.example.org User root Port 4748 IdentityFile ~/.ssh/id_rsa IdentitiesOnly yes
Connexion
A la connexion on se retrouve sur un shell, qui nous demande gentiment la phrase de passe :
Please unlock disk sda2_crypt:
Une fois la phrase de passe validée, on se fait déconnecter et le vrai démarrage de la machine commence :
cryptsetup: sda2_crypt set up successfully Shared connection to 111.222.333.444 closed.
Ressources externes
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érants 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, ça rend l'opération plus compliqué que simplement partir avec la machine, donc c'est bien mais ça a ses limites.
À noter aussi, Mandos peut servir à automatiser l'opération.