Encrypted Root Filesystem HOWTO


Christophe Devine


Revision History

Revision v1.2

2004-08-01

Revised by: cd

Updated the packages version.

Revision v1.1

2003-12-01

Revised by: cd

Added support for GRUB.

Revision v1.0

2003-09-24

Revised by: cd

Initial release, reviewed by LDP.

Revision v0.9

2003-09-11

Revised by: cd

Updated and converted to DocBook XML.

Questo documento spiega come rendere i vostri dati personali sicuri cifrando il vostro linux root filesystem con algoritmi di crittografia forte.

Preparazione del sistema


Settare il layout delle partizioni.


Il vostro hard disk (hda) dovrebbe contenere almeno tre partizioni:



A questo punto, sia hda1 e hda2 sono inutilizzati. In hda3 si trova installata la tua distribuzione linux; /usr e /boot non devono essere separate da questa partizione.



Qui trovi un esempio di come potrebbe assomigliare il tuo schema di partizionamento:


# fdisk -l /dev/hda

Disk /dev/hda: 255 heads, 63 sectors, 2432 cylinders
Units = cylinders of 16065 * 512 bytes

   Device Boot    Start       End    Blocks   Id  System
/dev/hda1             1         1      8001   83  Linux
/dev/hda2             2       263   2104515   83  Linux
/dev/hda3           264       525   2104515   83  Linux
/dev/hda4           526      2047  12225465   83  Linux

Installare Linux-2.4.27

Ci sono due progetti principali che aggiungono un supporto di crittografia forte al kernel: CryptoAPI e loop-AES. Questo how-to e' basato su loop-aes, poiché ha un'esecuzione estremamente veloce ed altamente ottimizzata di Rijndael in linguaggio assembler e quindi fornisce le prestazioni massime su una CPU IA-32 (x86).

Prima di tutto, scarichiamo e scompattiamo il pacchetto per loop-aes:


wget http://loop-aes.sourceforge.net/loop-AES/loop-AES-v2.1b.tar.bz2
tar -xvjf loop-AES-v2.1b.tar.bz2

Dopo devi scaricare i sorgenti del kernel ed applicarvi la patch:

wget http://ftp.kernel.org/pub/linux/kernel/v2.4/linux-2.4.27.tar.bz2
tar -xvjf linux-2.4.27.tar.bz2
cd linux-2.4.27
rm include/linux/loop.h drivers/block/loop.c
patch -Np1 -i ../loop-AES-v2.1b/kernel-2.4.26.diff


Setta la mappa per la tastiera:


dumpkeys | loadkeys -m - > drivers/char/defkeymap.c

Dopo, configura il tuo kernel; poni attenzione che queste opzioni sia attivate:


make menuconfig

    Block devices  --->

        <*> Loopback device support
        [*]   AES encrypted loop device support (NEW)

        <*> RAM disk support
        (4096)   Default RAM disk size (NEW)
        [*]   Initial RAM disk (initrd) support

    File systems  --->

        <*> Ext3 journalling file system support
        <*> Second extended fs support

(importante: non abilitare il supporto per il file system /dev)


Compila il kernel ed installalo:


make dep bzImage
make modules modules_install
cp arch/i386/boot/bzImage /boot/vmlinuz


Se usi grub come bootloader, aggiorna /boot/grub/menu.lst e /boot/grub/grub.conf:


cat > /boot/grub/menu.lst << EOF
default 0
timeout 10
color green/black light-green/black
title Linux
    root (hd0,2)
    kernel /boot/vmlinuz ro root=/dev/hda3
EOF

Altrimenti, aggiorna /etc/lilo.conf e fai partire lilo :


cat > /etc/lilo.conf << EOF
lba32
boot=/dev/hda
prompt
timeout=100
image=/boot/vmlinuz
    label=Linux
    read-only
    root=/dev/hda3
EOF
lilo


A questo punto riavvia il tuo sistema.

Installare Linux-2.6.7

Procedi come descritto nella sezione precedente, usando invece la patch kernel-2.6.6.diff di loop-aes. Nota che il supporto per il moduli richiede che tu abbia il pacchetto module-init-tools installato.

Installare le util-linux-2.12.

Il programma losetup, che e' parte del pacchetto util-linux, deve essere patchato e ricompilato per aggiungere il supporto per la crittografia forte.

Scarica, scompatta e applica la patch alle util-linux :

wget http://ftp.kernel.org/pub/linux/utils/util-linux/util-linux-2.12a.tar.bz2
tar -xvjf util-linux-2.12a.tar.bz2
cd util-linux-2.12a
patch -Np1 -i ../loop-AES-v2.1b/util-linux-2.12a.diff

Per usare password piu' corte di 20 caratteri, digita :

CFLAGS="-O2 -DLOOP_PASSWORD_MIN_LENGTH=8"; export CFLAGS

Se per te la sicurezza e' importante, non abilitare password piu' corte di 20 caratteri. La sicurezza non e' gratis, si deve pagare in termini di lunghezza della password.

Compila losetup e installalo come utente root:


./configure && make lib mount
mv -f /sbin/losetup /sbin/losetup~
rm -f /usr/share/man/man8/losetup.8*
cd mount
gzip losetup.8
cp losetup /sbin
cp losetup.8.gz /usr/share/man/man8/

Creazione del filesystem root crittato

Riempi la partizione che ospitera' il filesystem root criptato con dati casuali:

shred -n 1 -v /dev/hda2



Iniziallizza il loopback device criptato:

losetup -e aes256 -S xxxxxxxxxx /dev/loop0 /dev/hda2
Password:

Per prevenire attacchi ottimizzati a dizionario, e' raccomandato di aggiungere l'opzione -S xxxxxx, dove xxxxxx e' il tuo seme scelto in modo casuale (pe esempio, potreste scegliere "gPk4lA0v"). Inoltre, per evitare problemi in fase di boot con la mappa della tastiera, non usare caratteri non-ascii (accenti, etc..) per la tua password. Il sito Diceware ti offre un semplice modo per creare forti, ancora facili da ricordare, passphrases.

Adesso crea il filesystem ext3:

mke2fs -j /dev/loop0

Controlla che hai inserito correttemente la password:

losetup -d /dev/loop0
losetup -e aes256 -S xxxxxxxxxx /dev/loop0 /dev/hda2
Password:
mkdir /mnt/efs
mount /dev/loop0 /mnt/efs

Puoi confrontare i dati crittati con quelli non crittati:

xxd /dev/hda2  | less
xxd /dev/loop0 | less

E' il momento di installare il tuo filesystem linux criptato. Se usi una distribuzione Gnu/Linux (come sono Debian, Slackware, Gentoo, Mandrake, RedHat/Fedora, SuSe, etc..) fallo con i seguenti comandi :

cp -avx / /mnt/efs

Se usi il libro di Linux From Scrath , procedi come descritto sul manuale, con le seguenti differenze:

Configurare il dispositivo di avvio

Creazione del ramdisk

Per iniziare, esegui chroot dentro la partizione criptata e crea il mount point per il dispositivo di boot:

chroot /mnt/efs
mkdir /loader

Dopo, crea il ramdisk iniziale (initrd), che sara' necessario in seguito:

cd
dd if=/dev/zero of=initrd bs=1k count=4096
mke2fs -F initrd
mkdir ramdisk
mount -o loop initrd ramdisk

Se state usando le grsecurity, potete ottenere un messaggio di errore di “Permission denied”; in questo caso dovrete eseguire il comando mount fuori dalla chroot.

Crea la gerarchia del filesystem e copia i file richiesti su di essi :

mkdir ramdisk/{bin,dev,lib,mnt,sbin}
cp /bin/{bash,mount,umount} ramdisk/bin/
ln -s bash ramdisk/bin/sh
mknod -m 600 ramdisk/dev/console c 5 1
mknod -m 600 ramdisk/dev/hda2    b 3 2
mknod -m 600 ramdisk/dev/loop0   b 7 0
cp /lib/{ld-linux.so.2,libc.so.6,libdl.so.2} ramdisk/lib/
cp /lib/{libncurses.so.5,libtermcap.so.2}    ramdisk/lib/
cp /sbin/{losetup,pivot_root} ramdisk/sbin/

E' tutto ok se vedrai il messaggio "/lib/libncurses.so.5: No such file or directory", o "/lib/libtermcap.so.2: No such file or directory"; la bash richiede solo uno di queste due librerie. Puoi controllare manualmente quale delle due e' necessaria con:

ldd /bin/bash

Compile the sleep program, which will prevent the password prompt being flooded by kernel messages (such as usb devices being registered).

Compila il programma sleep, che impedira' che il prompt della richiesta della password venga floodato dai messaggi del kernel (come quando un dispositivo usb viene registrato)

cat > sleep.c << "EOF"
#include <unistd.h>
#include <stdlib.h>

int main( int argc, char *argv[] )
{
    if( argc == 2 )
        sleep( atoi( argv[1] ) );

    return( 0 );
}
EOF

gcc -s sleep.c -o ramdisk/bin/sleep

Crea lo script di init (senza dimenticare di sostituire “xxxxxxx” con il seme scelto):

cat > ramdisk/sbin/init << "EOF"
#!/bin/sh

/bin/sleep 3
/sbin/losetup -e aes256 -S xxxxxxxx /dev/loop0 /dev/hda2
/bin/mount -r -n -t ext3 /dev/loop0 /mnt

while [ $? -ne 0 ]
do
    /sbin/losetup -d /dev/loop0
    /sbin/losetup -e aes256 -S xxxxxxxx /dev/loop0 /dev/hda2
    /bin/mount -r -n -t ext3 /dev/loop0 /mnt
done

cd /mnt
/sbin/pivot_root . loader
exec /usr/sbin/chroot . /sbin/init
EOF

chmod 755 ramdisk/sbin/init

Smonta il dispositivo di loopback e comprimi l'initrd:

umount -d ramdisk
rmdir ramdisk
gzip initrd
mv initrd.gz /boot/



Avvio da un CD-ROM

Si consiglia fortemente di avviare il tuo sistema con un dispositivo a sola lettura, come un cdrom avviabile.


Scarica e scompatta syslinux:


wget http://ftp.kernel.org/pub/linux/utils/boot/syslinux/syslinux-2.10.tar.bz2
tar -xvjf syslinux-2.10.tar.bz2

Configura isolinux:

mkdir bootcd
cp /boot/{vmlinuz,initrd.gz} syslinux-2.10/isolinux.bin bootcd
echo "DEFAULT /vmlinuz initrd=initrd.gz ro root=/dev/ram0" \
    > bootcd/isolinux.cfg

Crea e masterizza l'immagine bootabile su cd-rom :

mkisofs -o bootcd.iso -b isolinux.bin -c boot.cat \
        -no-emul-boot -boot-load-size 4 -boot-info-table \
        -J -hide-rr-moved -R bootcd/

cdrecord -dev 0,0,0 -speed 4 -v bootcd.iso

rm -rf bootcd{,.iso}

Avviare il sistema da una partizione

La partizione di avvio puo' essere utile se il tuo CD di avvio va perso. Ricordati che hda1 e' un dispositivo scrivibile e quindi insicuro; usalo solo in caso di emergenza!

Crea e monta il filesystem ext2:

dd if=/dev/zero of=/dev/hda1 bs=8192
mke2fs /dev/hda1
mount /dev/hda1 /loader

Copia il kernel e il ramdisk iniziale:

cp /boot/vmlinuz-2.4.23 /loader/vmlinuz
cp /boot/initrd.gz /loader/



Se usi grub:

mkdir /loader/boot
cp -av /boot/grub /loader/boot/
cat > /loader/boot/grub/menu.lst << EOF
default 0
timeout 10
color green/black light-green/black
title Linux
    root (hd0,0)
    kernel /vmlinuz ro root=/dev/ram0 vga=4
    initrd /initrd.gz
EOF
grub-install --root-directory=/loader /dev/hda
umount /loader

Se usi lilo:

mkdir /loader/{boot,dev,etc}
cp /boot/boot.b /loader/boot/
mknod -m 600 /loader/dev/hda  b 3 0
mknod -m 600 /loader/dev/hda1 b 3 1
mknod -m 600 /loader/dev/ram0 b 1 0
cat > /loader/etc/lilo.conf << EOF
lba32
boot=/dev/hda
prompt
timeout=100
image=/vmlinuz
    label=Linux
    initrd=/initrd.gz
    read-only
    root=/dev/ram0
    vga=4
EOF
lilo -r /loader
umount /loader

Passi finali

Modifica /etc/fstab in modo che contenga:

/dev/loop0      /      ext3    defaults             0 1

Rimuovi /etc/mtab ed esci dalla chroot. Per concludere, lancia "umount - la d/mnt/efs" e riavvia. Se tutto andasse bene, puoi criptare sia hda3 e hda4; diciamo che hda3 conterra' il tuo dispositivo di swap e hda4 conterra' la /home. Dovresti inizializzare ambedue le partizioni prima:

shred -n 1 -v /dev/hda3
shred -n 1 -v /dev/hda4
losetup -e aes256 -S xxxxxxxx /dev/loop1 /dev/hda3
losetup -e aes256 -S xxxxxxxx /dev/loop2 /dev/hda4
mkswap /dev/loop1
mke2fs -j /dev/loop2

Dopodiche' crea uno script nella directory di avvio del sistema e aggiorna fstab :


cat > /etc/init.d/loop << "EOF"
#!/bin/sh

if [ "`/usr/bin/md5sum /dev/hda1`" != \
     "5671cebdb3bed87c3b3c345f0101d016  /dev/hda1" ]
then
    echo -n "WARNING! hda1 integrity verification FAILED - press enter."
    read
fi

echo "1st password chosen above" | \
    /sbin/losetup -p 0 -e aes256 -S xxxxxxxx /dev/loop1 /dev/hda3

echo "2nd password chosen above" | \
    /sbin/losetup -p 0 -e aes256 -S xxxxxxxx /dev/loop2 /dev/hda4

/sbin/swapon /dev/loop1

for i in `seq 0 63`
do
    echo -n -e "\33[10;10]\33[11;10]" > /dev/tty$i
done

EOF

chmod 700 /etc/init.d/loop
ln -s ../init.d/loop /etc/rcS.d/S00loop
vi /etc/fstab
...
/dev/loop2      /home           ext3    defaults       0       2

A proposito di questo HOWTO

L' Encrypted Root Filesystem HOWTO fu scritto per la prima volta nel novembre del 2002 per il progetto Linux From Scratch . Vorrei ringraziare molte persone che mi hanno aiutato a migliorare questo howto (in ordine cronologico inverso): Ernesto Pérez Estévez, Matthew Ploessel, Mike Lorek, Lars Bungum, Michael Shields, Julien Perrot, Grant Stephenson, Cary W. Gilmer, James Howells, Pedro Baez, Josh Purinton, Jari Ruusu and Zibeli Aton.

Questo HOWTO e' stato tradotto in svariate lingue:

Perpiacere manda i tuoi commenti a Christophe Devine.

Note per la traduzione italiana

Questo howto e' stato tradotto in italiano da Gaetano Zappulla <gaetano(at)linux.it>. Potete trovare la sua versione piu' aggiornata all'indirizzo www.linux.it/~gaetano/erfs.

Revision 1.0 terminata di tradurre il 29 Novembre 2003.

Revision 1.1 terminata di tradurre il 3 Dicembre 2003.

Revision 1.2 terminata di tradurre il 13 Agosto 2004.