====== Encrypted filesystem ======
===== Web =====
* [[http://www.saout.de/misc/dm-crypt/|dm-crypt: a device-mapper crypto target]]
* [[http://www.shimari.com/dm-crypt-on-raid/|Encrypt with dm-crypt]]
* [[http://luks.endorphin.org/dm-crypt|Linux Unified Key Setup]]
* [[http://arg0.net/users/vgough/encfs.html|EncFS – Encrypted Filesystem module for Linux]]
* [[http://www.linuxdevcenter.com/pub/a/linux/2005/04/14/encfs.html|Userspace Filesystem Encryption with EncFS]]
===== 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
[[wp>Twofish]] was developed by indipendent cryptographers, leaded by [[wp>Bruce Schneier]]. [[wp>Advanced_Encryption_Standard|AES]] is instead approved by the U.S. [[wp>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 [[http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=495509|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''**
#
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 option **''BOOT=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 into ''fstab'' and ''crypttab'' (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 during ''update-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 [[https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=495509|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