Table of Contents
Encrypted filesystem
Web
Linux kernel modules
Due possibilità offerte dal kernel Linux: cryptoloop (deprecata) e dm-crypt.
Cryptoloop
WARNING: This device is not safe for journaled file systems like ext3 or Reiserfs. Please use the Device Mapper crypto module instead, which can be configured to be on-disk compatible with the cryptoloop device.
Cryptoloops is also vulnerable to known plaintext attacks and watermark attacks.
Kernel option: CONFIG_BLK_DEV_CRYPTOLOOP
.
Dm-crypt
Kernel option: CONFIG_DM_CRYPT
.
This device-mapper target allows you to create a device that transparently encrypts the data on it. You'll need to activate the ciphers you're going to use in the cryptoapi configuration.
modprobe dm-mod /dev/mapper /dev/mapper/control
Storing keys with LUKS
The Debian version of cryptsetup(8)
is enhanced with LUKS (Linux Unified Key Setup) for keys handling.
LUKS works by prepending a partition header (luks_phdr) to the partition, where setup information like cipher, keysize is stored as well as key slots. A key slots is holding an encrypted version of the master key. The master key is used to encrypt bulk data. It will never be stored to disk directly, but encrypted version of the master key will be stored. To be more precise, every version of the master key is encrypted by a different passphrase and stored a separate key slot. The user needs to provide one passphrase only, since any correct passphrase will restore a copy of the master key.
Example
With those commands we initialize an encrypted (dm-crypt) filesystem sitting on a RAID1 partition.
Create a RAID level 1 (mirror) device /dev/md4
:
mknod /dev/md4 b 9 4 mdadm --create /dev/md4 --level=1 -n 2 /dev/sda3 /dev/sdb3
Load the needed kernel modules and initialize the dm-crypt volume:
modprobe dm-mod modprobe dm-crypt modprobe twofish cryptsetup isLuks /dev/md4; echo $? cryptsetup --cipher twofish-cbc-essiv:sha256 --key-size 256 luksFormat /dev/md4 cryptsetup luksDump /dev/md4
In the example above we used the twofish crypto algorithm provided by the twofish
kernel module. Another popular crypto algorithm is provided byt the aes kernel module; in that case use the parameter aes-cbc-essiv:sha256. You can ask the kernel which crypto modules are loaded with the command:
cat /proc/crypto name : aes driver : aes-generic module : aes priority : 100 type : cipher blocksize : 16 min keysize : 16 max keysize : 32 name : twofish driver : twofish-generic module : twofish priority : 0 type : cipher blocksize : 16 min keysize : 16 max keysize : 32
Twofish was developed by indipendent cryptographers, leaded by Bruce Schneier. AES is instead approved by the U.S. National Security Agency (NSA).
The ecnryption key will be 256 bits long (how it is generated?). The key will be hashed with a passphrase typed by the user and stored in a LUKS keyslot contained in /dev/md4
.
To start the dm-crypt device we must type the passphrase to unlock the crypt key. Finally we create an ext3 filsystem and mount it:
cryptsetup luksOpen /dev/md4 dm0 ls -l /dev/mapper/ mkfs.ext3 -m0 /dev/mapper/dm0 mount /dev/mapper/dm0 /mnt
Useful commands to see the status or to close a dm-crypt device:
cryptsetup status dm0 cryptsetup remove dm0 cryptsetup luksClose dm0; # Same as above!
To initialize automatically the dm-crypt volume at bootstrap (via /etc/init.d/cryptdisks
), put the following line in /etc/crypttab
:
dm0 /dev/md4 none luks,tries=1,timeout=10
The passphrase will be asked only once with a 10 seconds timeout.
WARNING! See bug 495509. The timeout
paramter does not work, use instead noauto
and start the crypt disk manually with /etc/init.d/cryptdisks force-start
. Beware to set noauto
also into the fstab options for that device.
If you want to start automatically the crypto device at boot without prompting for the passphrase you have to:
- Generate a random key with the required size (32 bytes * 8 = 256 bits)
- Add the new key into one LUKS slot
- Open the crypto device using this key
dd if=/dev/urandom of=luks.key bs=1 count=32 cryptsetup luksAddKey /dev/md4 luks.key cryptsetup --key-file luks.key luksOpen /dev/md4 mycryptdev
Starting a crypted device without LUKS
cryptsetup create crypted-hdd1 /dev/hdd1 ls -l /dev/mapper/ mount /dev/mapper/crypted-hdd1 /mnt
Other kernel modules
Loop-aes
Through politics and in-fighting the Loop-AES developers have alienated the Linux kernel team, including Linus himself. As a result loop-AES is not supported by the mainline Linux kernel.
One strong point of loop-aes is that Encryption keys can be stored in a GnuPG-encrypted keyfile, which allows the passphrase to be changed without re-encryption. Keyfiles can also be encrypted asymmetrically for multi-user access. Much like LUKS in cryptsetup
and dm-crypt.
User space
enc-fs
Per creare una directory criptata in $HOME/encfs/crypt/
:
mkdir ~/encfs encfs ~/encfs/.crypt ~/encfs/crypt
Scegliendo l'opzione p si dovrebbe ottenere una Paranoia configuration. Viene ovviamente chiesta una password che protegge il filesystem, tale filesystem viene montato tramite fuse.encfs, quindi tutto in user-space.
La directory $HOME/encfs/.crypt/
contiene i dati veri e propri, criptati. La directory $HOME/encfs/crypt/
è invece una vista in chiaro dei dati.
Per smontare la directory in chiaro (e quindi lasciare solo la versione cifrata dei dati):
fusermount -u ~/encfs/crypt
Per montare nuovamente il filesystem cifrato (la directory) si usa lo stesso comando encfs
utilizzato per inizializzarlo; viene ovviamente chiesta la password di cifratura. Per il montaggio è indispensabile conservare il file .encfs6.xml che è stato creato nella directory radice.
È possibile eliminare file e/o directory nel filesystem cifrato: ogni oggetto compare con un nome cifrato. Non è possibile invece spostare una directory: per decodificare correttamente il contenuto è necessario mantenere il percorso originale completo.
È possibile modificare la password; si tratta in realtà della password che protegge la chiave di cifratura vera e propria, pertanto non sarà necessario cifrare nuovamente tutto il contenuto. Si usa il comando:
encfsctl passwd ~/encfs/.crypt
Reverse enc-fs
È possibile usare encfs
per ottenere una “vista” cifrata di una normale directory (ad esempio per effettuare un backup tramite rsync su host remoto e mantenere la riservatezza dei dati). Per automatizzare il processo la password deve essere memorizzata in un file, questo il comando per montare la vista cifrata della directory:
cat secret.txt | encfs --standard --reverse --stdinpass /home /home-crypt
L'opzione --standard serve a disabilitare la richiesta dei parametri quando si esegue il montaggio encfs per la prima volta. In tale circostanza infatti vengono chiesti via stdin alcuni parametri che “consumerebbero” una parte della password fornita appunto via stdin. I parametri di encfs vengono salvati nella directory radice in un file di nome .encfs6.xml.
Per smontare la directory cifrata si utilizza:
fusermount -u /home-crypt
Which encryption algorythm?
When the U.S. govt. and dept. of defense set out to search for a replacement for the previous encryption standard, DES, they launched a public process involving many cryptographers and evaluated a great many encryption algorithms. Eventually, through many rounds of expert consultation and review, the field was narrowed down to five really good, fast, flexible encryption algorithms:
- Rijndael (now known as AES)
- Serpent
- Twofish
- MARS
- RC6
RC6 was abandoned for intellectual property reasons, and few of the reviewers like MARS. The other three were serious contenders, and all are available to you in the modern Linux kernel. All three are fast, flexible, cryptographically strong, and very well reviewed. In the end, Rijndael was selected and it is now known as AES. Strong arguments can still be made in favour of twofish or serpent as well.
Someone choosed Twofish because of: I elected to choose between the three based on performance benchmarks, counting on the fact that all three of them are strong enough cryptographically to meet my needs.
Crypto root filesystem
The most generic case is a crypto root filesystem with a modular kernel and initramfs.
Installing the cryptsetup and the initramfs-tools will provide a good infrastructure: just add the proper entries into /etc/fstab
/dev/mapper/root / ext3 defaults,errors=remount-ro 0 1
and /etc/crypttab
# <target name> <source device> <key file> <options> root /dev/sda2 /etc/crypto_root.key luks,keyscript=/bin/cat
Just to be on the safe side, add also the required kernel modules into /etc/initramfs-tools/modules
:
# Modules for crypto device dm-mod dm-crypt aes twofish sha256
Then run the command:
update-initramfs -v -u
The boot sequence that will be embedded into the initramfs is like this:
- The kernel boots and opens the ramdisk image.
- The kernel runs the
init
program which loads the kernel modules. init
will run the/scripts/local
because it wants a local root filesystem (this is took from the optionBOOT=local
contained in/etc/initramfs-tools/initramfs.conf
).- The
/script/local
will run the helper script/scripts/local-top/cryptroot
. The script was included into the ramdisk image because of the entries found intofstab
andcrypttab
(see above). All the configuration options will be read from/conf/conf.d/cryptroot
. - Also
/script/local
will mount the root filesystem. Default root filesystem is took from/conf/param.conf
(ROOT=/dev/mapper/root
in my case). This file is created duringupdate-initramfs
.
My case was a bit special: the crypto disk is opened with LUKS and using a key stored onto the disk itself, instead of asking the passphrase on the console. So I had to use a key file and the keyscript option.
I keep the key file in /etc/crypto_root.key
, but this file must be present also into the initramfs. For this reason I had to provide to update-initramfs
an hook script: /etc/initramfs-tools/hooks/cryptoroot_key
:
#!/bin/sh PREREQ="" prereqs() { echo "$PREREQ" } case $1 in prereqs) prereqs exit 0 ;; esac if [ -f /etc/crypto_root.key ]; then install -d $DESTDIR/etc cp -p /etc/crypto_root.key $DESTDIR/etc fi
Using a key-file instead of an interactive password
If you want to store the key into a file instead of unlocking it via a passphrase:
dd if=/dev/urandom of=crypto.key bs=1 count=32 cat crypto.key | cryptsetup --key-file=- --cipher aes-cbc-essiv:sha256 --key-size 256 luksFormat /dev/sda8 cryptsetup --key-file=crypto.key luksOpen /dev/sda8 crypto_sda8
Manual start of encrypted disk
If an encrypted disk requires a password to be typed interactively, it is obviously not possible to start it automatically at boot time. In old Debian releases there was the timeout parameter to be added into /etc/crypttab. Using that parameter, the starting of a LUKS volume is skipped at boot time and can be executed later using /etc/init.d/cryptdisks start.
Starting with Debian 5 Lenny the timeout parameter was not longer available (see bug #495509). The noauto parameter is instead required in /etc/crypttab and eventually in /etc/fstab.
Starting with Debian 6 Squeeze the noauto parameter is still required. Once the system is running you can execute the command /etc/init.d/cryptdisks force-start to start the encrypted disk, asking for the password.
Starting with Debian 9 Stretch the noauto parameter is used as usual, but sysvinit init system was superceeded by systemd, so the script /etc/init.d/cryptdisks
is no longer used. To start the encrypted disk interactively you should use the script cryptdisks_start instead, e.g.:
cryptdisks_start dm0