Créer un initrd avec ssh pour déchiffrer la partition système à distance
Création de l'initrd
Ayant slackware installée sur une partition chiffrée via Luks, cette distribution propose deux possibilités pour la déchiffrer au démarrage de l'OS :
- soit on saisit le mot de passe ce qui implique que l'on a un accès physique à la machine,
- soit on branche une clé USB contenant la clé de déchiffrement. Si on n'a pas un accès physique à la machine alors cette clé est toujours branchée, et on perd l'intérêt du chiffrement.
Grâce à cette page, j'ai pu créer un initrd permettant d'accéder à distance à la machine via ssh me permettant ainsi de déchiffrer la partition contenant slackware avec le mot de passe.
Avant d'expliquer la marche à suivre, je suppose que vous savez déjà créer un initrd avec les modules et les options nécessaires pour être en mesure de déchiffrer votre partition slackware via la clé USB ou le mot de passe. Voici la marche à suivre :
- Tout d'abord, créer le paquet dropbear qui sera le serveur ssh utilisé. Une fois le paquet créé, vous aurez juste besoin de l'extraire avec la commande explodepkg
- Dans votre fichier /etc/mkinitrd.conf, assurez vous d'avoir le module du pilote de votre carte réseau
- Créer votre initrd.gz comme vous avez l'habitude de le faire avec l'option “-c” pour supprimer /boot/initrd-tree
- Copier la commande dropbearmulti dans /boot/initrd-tree/bin/ :
cd /boot/initrd-tree/bin cp $PKG/usr/bin/dropbearmulti . ln -s dropbearmulti dropbear ln -s dropbearmulti dropbearkey
- Créer une bannière (optionnelle). Vous pouvez y saisir les commandes dont vous aurez besoin pour déchiffrer votre partition et poursuivre le démarrage de l'OS :
vi /boot/initrd-tree/etc/dropbear/banner
- L'utilisateur root doit avoir le shell /bin/sh et non bash car il n'est pas présent. Modifier le fichier /boot/initrd-tree/etc/passwd comme ceci :
root:x:0:0::/root:/bin/sh
- Copier votre fichier /etc/shadow (uniquement la ligne root) car il contient le mot de passe à saisir :
grep ^root /etc/shadow > /boot/initrd-tree/etc/shadow
- Créer le fichier /boot/initrd-tree/bin/bootlock :
echo $$ > /bootlock.pid echo "###########################################" echo "### Wait for user input ###" echo "###########################################" echo "Press enter to continue booting:" read INPUT
- Créer le fichier /boot/initrd-tree/bin/unlock en spécifiant votre LUKSDEV. Il est important que le nom donné au périphérique déchiffré soit “lukssdXX” :
LUKSDEV=sda2 PATH="/sbin:/bin:/usr/sbin:/usr/bin" # unlock needed devices cryptsetup luksOpen /dev/${LUKSDEV} luks${LUKSDEV} || exit 1 echo "/dev/${LUKSDEV} unlocked" # kill bootlock kill $(cat /bootlock.pid)
- Créer le fichier /boot/initrd-tree/udev.sh :
# initialize network interfaces for ssh boot /sbin/udevadm trigger --action='add' --subsystem-match='net' /sbin/udevadm settle --timeout=10
- Créer le fichier /boot/initrd-tree/network.sh en remplaçant INET, IP et GATEWAY :
INET=eth0 IP=192.168.0.71 GATEWAY=192.168.0.1 # init network # Obviously, you should put in the correct interfaces # here, and edit the ip addresses. It's easiest to # use a different ip address than the pc usually # has, because the host keys are different and ssh # will die over that, unless you explicitly tell it # not to EVERY SINGLE TIME. This way, ssh will not # see this as the same host and there's no problem. # Right now, it's configured for a static ip. Dhcp # is within the possibilities, I just don't use it. # It will most likely be difficult though, as it's # not automatically included in the initrd. Do # yourself a favor and just configure it statically. # ;) echo "###########################################" echo "### Initializing network ###" echo "###########################################" echo "-------- Bringing up lo on 127.0.0.1" ifconfig lo 127.0.0.1 echo "-------- Bringing up $INET on $IP" ifconfig $INET up $IP echo "-------- Adding $GATEWAY as default gw" route add -net 127.0.0.0 netmask 255.0.0.0 lo route add default gw $GATEWAY # start ssh # This kinda speaks for itself. You could set a few # options for dropbear if you wanted (-s to disable # password login for example). echo "###########################################" echo "### Starting ssh daemon ###" echo "###########################################" echo "-------- Starting daemon on port 22" dropbearkey -t dss -f /etc/dropbear/dropbear_dss_host_key dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key dropbearkey -t ecdsa -f /etc/dropbear/dropbear_ecdsa_host_key dropbear -b /etc/dropbear/banner # lock system until user provides input, or this script is killed (via ssh) bootlock # We don't need ssh anymore - kill off dropbear echo "###############################################" echo "### Shut down network ###" echo "###############################################" killall dropbear sleep 1 # Now shut down the network so it doesn't interfere with the normal booting process # I'm not sure this is needed, but I've read reports of network issues because the # regular boot process couldn't overwrite the initial configuration. Seemed the safe # thing to do. Also, I don't like the idea of leaving the network open unprotected # (no firewall) any longer than I have to. ifconfig $INET down ifconfig lo down
- Rendre ces fichiers exécutables :
chmod +x /boot/initrd-tree/{udev.sh,network.sh,bin/bootlock,bin/unlock}
- Ajouter la ligne “/udev.sh” dans /boot/initrd-tree/init (ligne 139) :
# If udevd is available, use it to generate block devices # else use mdev to read sysfs and generate the needed devices if [ -x /sbin/udevd -a -x /sbin/udevadm ]; then /sbin/udevd --daemon --resolve-names=never /sbin/udevadm trigger --subsystem-match=block --action=add /sbin/udevadm settle --timeout=10 /udev.sh else [ "$DEVTMPFS" != "1" ] && mdev -s fi
- Ajouter la ligne “/network.sh” dans /boot/initrd-tree/init (ligne 193) :
if [ -x /sbin/cryptsetup ]; then /network.sh # Determine if we have to use a LUKS keyfile: if [ ! -z "$LUKSKEY" ]; then…
- Recréer votre initrd.gz sans l'option “-c”
- Relancer lilo