dm-crypt/特記事項
Dm-crypt に戻る。
目次
暗号化されていない boot パーティションのセキュア化
The /boot
partition and the Master Boot Record are the two areas of the disk that are not encrypted, even in an encrypted root configuration. They cannot be encrypted because the boot loader and BIOS (respectively) are unable to unlock a dm-crypt container in order to continue the boot process. This section describes steps that can be taken to make the boot process more secure.
リムーバルデバイスから起動
Using a separate device to boot a system is a fairly straightforward procedure, and offers a significant security improvement against some kinds of attacks. Two vulnerable parts of a system employing an encrypted root filesystem are
- the Master Boot Record, and
- the
/boot
partition.
These must be stored unencrypted in order for the system to boot. In order to protect these from tampering, it is advisable to store them on a removable medium, such as a USB drive, and boot from that drive instead of the hard disk. As long as you keep the drive with you at all times, you can be certain that those components have not been tampered with, making authentication far more secure when unlocking your system.
It is assumed that you already have your system configured with a dedicated partition mounted at /boot
. If you do not, please follow the steps in dm-crypt/System configuration#Boot loader, substituting your hard disk for a removable drive.
Prepare the removable drive (/dev/sdx
).
# gdisk /dev/sdx #format if necessary. Alternatively, cgdisk, fdisk, cfdisk, gparted... # mkfs.ext2 /dev/sdx1 # mount /dev/sdx1 /mnt
Copy your existing /boot
contents to the new one.
# cp -R -i -d /boot/* /mnt
Mount the new partition. Do not forget to update your fstab file accordingly.
# umount /boot # umount /mnt # mount /dev/sdx1 /boot # genfstab -p -U / > /etc/fstab
Update GRUB. grub-mkconfig
should detect the new partition UUID automatically, but custom menu entries may need to be updated manually.
# grub-mkconfig -o /boot/grub/grub.cfg # grub-install /dev/sdx #install to the removable device, not the hard disk.
Reboot and test the new configuration. Remember to set your device boot order accordingly in your BIOS or UEFI. If the system fails to boot, you should still be able to boot from the hard drive in order to correct the problem.
chkboot
Referring to an article from the ct-magazine (Issue 3/12, page 146, 01.16.2012 http://www.heise.de/ct/inhalt/2012/03/6/) the following script checks files under /boot
for changes of SHA-1 hash, inode, and occupied blocks on the hard drive. It also checks the MBR. The script cannot prevent certain type of attacks, but a lot are made harder. No configuration of the script itself is stored in unencrypted /boot
. With a locked/powered-off encrypted system, this makes it harder for some attackers because it is not apparent that an automatic checksum comparison of the partition is done upon boot. However, an attacker who anticipates these precautions can manipulate the firmware to run his own code on top of your kernel and intercept file system access, e.g. to boot
, and present the untampered files. Generally, no security measures below the level of the firmware are able to guarantee trust and tamper evidence.
The script with installation instructions is available here: ftp://ftp.heise.de/pub/ct/listings/1203-146.zip (Author: Juergen Schmidt, ju at heisec.de; License: GPLv2). There is also an AUR package: chkbootAUR and a slightly updated AUR package chkboot-gitAUR which includes systemd support.
After installation:
- For classical SysVinit: add
/usr/local/bin/chkboot.sh &
to your/etc/rc.local
- For systemd: add a service file and enable the service. The service file might look like:
[Unit] Description=Check that boot is what we want Requires=basic.target After=basic.target [Service] Type=oneshot ExecStart=/usr/local/bin/chkboot.sh [Install] WantedBy=multi-user.target
There is a small caveat for systemd: At the time of writing, the original chkboot.sh
script provided contains an empty space at the beginning of #!/bin/bash
which has to be removed for the service to start successfully.
As /usr/local/bin/chkboot_user.sh
need to be excuted after login, add it to the autostart (e.g. under KDE -> System Settings -> Startup and Shutdown -> Autostart; GNOME 3: gnome-session-properties).
With Arch Linux, changes to /boot
are pretty frequent, for example by new kernels rolling-in. Therefore it may be helpful to use the scripts with every full system update. One way to do so:
#!/bin/bash # # Note: Insert your <user> and execute it with sudo for pacman & chkboot to work automagically # echo "Pacman update [1] Quickcheck before updating" & sudo -u <user> /usr/local/bin/chkboot_user.sh # insert your logged on <user> /usr/local/bin/chkboot.sh sync # sync disks with any results sudo -u <user> /usr/local/bin/chkboot_user.sh # insert your logged on <user> echo "Pacman update [2] Syncing repos for pacman" pacman -Syu /usr/local/bin/chkboot.sh sync sudo -u <user> /usr/local/bin/chkboot_user.sh # insert your logged on <user> echo "Pacman update [3] All done, let us roll on ..."
Alternatively to above scripts, a hash check can be set up with AIDE which can be customized via a very flexible configuration file.
While one of these methods should serve the purpose for most users, they do not address all security problems associated with the unencrypted /boot
. One approach which endeavours to provide a fully authenticated boot chain was published with POTTS as an academic thesis to implement the STARK authentication framework.
The POTTS proof-of-concept uses Arch Linux as a base distribution and implements a system boot chain with
- POTTS - a boot menu for a one-time authentication message prompt
- TrustedGrub - a GRUB Legacy implementation which authenticates the kernel and initramfs against TPM chip registers
- TRESOR - a kernel patch which implements AES but keeps the master-key not in RAM but in CPU registers during runtime.
As part of the thesis installation instructions based on Arch Linux (ISO as of 2013-01) have been published. If you want to try it, be aware these tools are not in standard repositories and the solution will be time consuming to maintain.
GPG や OpenSSL で暗号化されたキーファイルを使う
The following forum posts give instructions to use two factor authentication, gpg or openssl encrypted keyfiles, instead of a plaintext keyfile described earlier in this wiki article System Encryption using LUKS with GPG encrypted keys:
- GnuPG: Post regarding GPG encrypted keys This post has the generic instructions.
- OpenSSL: Post regarding OpenSSL encrypted keys This post only has the
ssldec
hooks. - OpenSSL: Post regarding OpenSSL salted bf-cbc encrypted keys This post has the
bfkf
initcpio hooks, install, and encrypted keyfile generator scripts.
Note that:
- You can follow the above instructions with only two primary partitions one boot partition
(required because of LVM), and one primary LVM partition. Within the LVM partition you can have
as many partitions as you need, but most importantly it should contain at least root, swap, and
home logical volume partitions. This has the added benefit of having only one keyfile for all
your partitions, and having the ability to hibernate your computer (suspend to disk) where the
swap partition is encrypted. If you decide to do so your hooks in /etc/mkinitcpio.conf
should look like
HOOKS=" ... usb usbinput (etwo or ssldec) encrypt(if using openssl) lvm2 resume ... "
and you should add "resume=/dev/mapper/<VolumeGroupName>-<LVNameOfSwap>"
to your kernel parameters.
- If you need to temporarily store the unecrypted keyfile somewhere, do not store them on an unencrypted disk. Even better make sure to store them to RAM such as
/dev/shm
. - If you want to use a GPG encrypted keyfile, you need to use a statically compiled GnuPG version 1.4 or you could edit the hooks and use this AUR package gnupg1AUR
- It is possible that an update to OpenSSL could break the custom
ssldec
mentioned in the second forum post.
root などのパーティションのリモート解除
If you want to be able to reboot a fully LUKS-encrypted system remotely, or start it with a Wake-on-LAN service, you will need a way to enter a passphrase for the root partition/volume at startup. This can be achieved by running the mkinitcpio net
hook along with an SSH server in initrd. Install the dropbear_initrd_encryptAUR package from the AUR and follow the post-installation instructions:
- If you do not have an SSH key pair yet, generate one on the client system (the one which will be used to unlock the remote machine).
- Insert your SSH public key (i.e. the one you usually put onto hosts so that you can ssh in without a password, or the one you just created and which ends up in .pub) into the remote machine's
/etc/dropbear/root_key
file using the method of your choice, e.g.:- copy the public key to the remote system
- then enter the following command (on the remote system):
# cat /home/<user>/.ssh/authorized_keys > /etc/dropbear/root_key
- Add the
dropbear encryptssh
hooks beforefilesystems
within the "HOOKS" array in/etc/mkinitcpio.conf
(or replaceencrypt
with them if it was present). Put thenet
hook early in the HOOKS array if your DHCP server takes a long time to lease IP addresses, and in any case place it before thedropbear encryptssh
hooks (betweenmodconf
andblock
proves functional). Then rebuild the initramfs image. - Configure the required
cryptdevice=
parameter and add theip=
kernel command parameter to your bootloader configuration with the appropriate arguments (see Mkinitcpio#Using_net). For example, if the DHCP server does not attribute a static IP to your remote system, making it difficult to access via SSH accross reboots, you can explicitly state the IP you want to be used:ip=192.168.1.1:::::eth0:none
Then update the configuration of your bootloader, e.g. for GRUB:# grub-mkconfig -o /boot/grub/grub.cfg
- Finally, restart the remote system and try to ssh to it, explicitly stating the "root" username (even if the root account is disabled on the machine, here it is a special "root" user set by dropbear for the purpose of unlocking the remote system). You may see a warning about host authenticity that you can safely ignore (type yes), then you should be presented with a prompt asking you to enter the passphrase for unlocking the remote root:
$ ssh root@192.168.1.1
Enter passphrase for /dev/disk/by-id/wwn-...-part2: Connection to 192.168.1.1 closed.
Afterwards, the system will complete its boot process and you can ssh to it as you normally would (with the remote user of your choice).
ソリッドステートドライブ (SSD) の Discard/TRIM のサポート
Solid state drive users should be aware that by default, Linux's full-drive encryption mechanisms will not forward TRIM commands from the filesystem to the underlying drive. The device-mapper maintainers have made it clear that TRIM support will never be enabled by default on dm-crypt devices because of the potential security implications.
Most users will still want to use TRIM on their encrypted SSDs. Minimal data leakage in the form of freed block information, perhaps sufficient to determine the filesystem in use, may occur on devices with TRIM enabled. An illustration and discussion of the issues arising from activating TRIM is available in the blog of a cryptsetup
developer. As a result encryption schemes that rely on plausible deniability should never be used on a device that utilizes TRIM.
In linux 3.1 and up, support for dm-crypt TRIM pass-through can be toggled upon device creation or mount with dmsetup. Support for this option also exists in cryptsetup version 1.4.0 and up. To add support during boot, you will need to add :allow-discards
to the cryptdevice
option. The TRIM option may look like this:
cryptdevice=/dev/sdaX:root:allow-discards
For the main cryptdevice
configuration options before the :allow-discards
see Dm-crypt/System configuration
Besides the kernel option, it is also required to mount the filesystem (e.g. /dev/mapper/root
in this example) with the discard
option in /etc/fstab
. For details, please refer to the SSD page. For LUKS devices unlocked manually on the console or via /etc/crypttab
either discard
or allow-discards
may be used.
encrypt フックと複数のディスク
The encrypt
hook only allows for a single cryptdevice=
entry. In system setups with multiple drives this may be limiting, because dm-crypt has no feature to exceed the physical device. For example, take "LVM on LUKS": The entire LVM exists inside a LUKS mapper. This is perfectly fine for a single-drive system, since there is only one device to decrypt. But what happens when you want to increase the size of the LVM? You cannot, at least not without modifying the encrypt
hook.
The following sections briefly show alternatives to overcome the limitation. The first deals with how to expand a LUKS on LVM setup to a new disk. The second with modifying the encrypt
hook to unlock multiple disks in LUKS setups without LVM. The third section then again uses LVM, but modifies the encrypt
hook to unlock the encrypted LVM with a remote LUKS header.
Expanding LVM on multiple disks
The management of multiple disks is a basic LVM feature and a major reason for its partitioning flexibility. It can also be used with dm-crypt, but only if LVM is employed as the first mapper. In such a LUKS on LVM setup the encrypted devices are created inside the logical volumes (with a separate passphrase/key per volume). The following covers the steps to expand that setup to another disk.
新しいドライブの追加
First, it may be desired to prepare a new disk according to Dm-crypt/Drive preparation.
Second, it is partitioned as a LVM, e.g. all space is allocated to /dev/sdY1
with partition type "8E00" (Linux LVM).
Third, the new disk/partition is attached to the existing LVM volume group, e.g.:
# pvcreate /dev/sdY1 # vgextend MyStorage /dev/sdY1
論理ボリュームの拡張
For the next step, the final allocation of the new diskspace, the logical volume to be extended has to be unmounted. It can be performed for the cryptdevice
root partition, but in this case the procedure has to be performed from an Arch Install ISO.
In this example, it is assumed that the logical volume for /home
(lv-name homevol
) is going to be expanded with the fresh disk space:
# umount /home # fsck /dev/mapper/home # cryptsetup luksClose /dev/mapper/home # lvextend -l +100%FREE MyStorage/homevol
Now the logical volume is extended and the LUKS container comes next:
# cryptsetup open --type luks /dev/mapper/MyStorage-homevol home # umount /home # as a safety, in case it was automatically remounted # cryptsetup --verbose resize home
Finally, the filesystem itself is resized:
# e2fsck -f /dev/mapper/home # resize2fs /dev/mapper/home
Done! If it went to plan, /home
can be remounted
# mount /dev/mapper/home /home
and now includes the span to the new disk. Note that the cryptsetup resize
action does not affect encryption keys, they have not changed.
複数のパーティションの encrypt フックを修正
複数の root パーティション
It is possible to modify the encrypt hook to allow multiple hard drive decrypt root (/
) at boot. The cryptsetup-multiAUR package may be used for it. An alternative way according to an Arch user (benke):
# cp /usr/lib/initcpio/hooks/encrypt /usr/lib/initcpio/hooks/encrypt2 # cp /usr/lib/initcpio/install/encrypt /usr/lib/initcpio/install/encrypt2 # nano /usr/lib/initcpio/hooks/encrypt2
Change $cryptkey
to $cryptkey2
, and $cryptdevice
to $cryptdevice2
.
Add cryptdevice2=
(e.g. cryptdevice2=/dev/sdb:hdd2
) to your boot options (and cryptkey2=
if needed).
Change the /etc/fstab
flag for root:
/dev/sdb /mnt btrfs device=/dev/sda,device=/dev/sdb, ... 0 0
複数の root 以外のパーティション
Maybe you have a requirement for using the encrypt
hook on a non-root partition. Arch does not support this out of the box, however, you can easily change the cryptdev and cryptname values in /lib/initcpio/hooks/encrypt
(the first one to your /dev/sd*
partition, the second to the name you want to attribute). That should be enough.
The big advantage is you can have everything automated, while setting up /etc/crypttab
with an external key file (i.e. the keyfile is not on any internal hard drive partition) can be a pain - you need to make sure the USB/FireWire/... device gets mounted before the encrypted partition, which means you have to change the order of /etc/fstab
(at least).
Of course, if the cryptsetup package gets upgraded, you will have to change this script again. Unlike /etc/crypttab
, only one partition is supported, but with some further hacking one should be able to have multiple partitions unlocked.
If you want to do this on a software RAID partition, there is one more thing you need to do. Just setting the /dev/mdX
device in /lib/initcpio/hooks/encrypt
is not enough; the encrypt
hook will fail to find the key for some reason, and not prompt for a passphrase either. It looks like the RAID devices are not brought up until after the encrypt
hook is run. You can solve this by putting the RAID array in /boot/grub/menu.lst
, like
kernel /boot/vmlinuz-linux md=1,/dev/hda5,/dev/hdb5
If you set up your root partition as a RAID, you will notice the similarities with that setup ;-). GRUB can handle multiple array definitions just fine:
kernel /boot/vmlinuz-linux root=/dev/md0 ro md=0,/dev/sda1,/dev/sdb1 md=1,/dev/sda5,/dev/sdb5,/dev/sdc5
リモート LUKS ヘッダーを使ってシステムを暗号化
This example follows the same setup as in Dm-crypt/Encrypting an entire system#Plain dm-crypt, which should be read first before following this guide. It shows how to modify the encrypt
hook in order to use a remote LUKS header.
By using a remote header the encrypted blockdevice itself only carries encrypted data, which gives deniable encryption as long as the existence of a header is unknown to the attackers. It is similar to using plain dm-crypt, but with the LUKS advantages such as multiple passphrases for the masterkey and key derivation. Further, using a remote header offers a form of two factor authentication with an easier setup than using GPG or OpenSSL encrypted keyfiles, while still having a built-in password prompt for multiple retries. See Disk encryption#Cryptographic metadata for more information.
See Dm-crypt/Device encryption#Encryption options for LUKS mode for encryption options before performing the first step to setup the encrypted system partition and creating a header file to use with cryptsetup
:
# truncate -s 2M header.img # cryptsetup luksFormat /dev/sdX --header header.img
Open the container:
# cryptsetup open --header header.img --type luks /dev/sdX enc
Now follow the LVM on LUKS setup to your requirements. The same applies for preparing the boot partition on the removable device (because if not, there is no point in having a separate header file for unlocking the encrypted disk).
Next move the header.img
onto it:
# mv header.img /mnt/boot
Follow the installation procedure up to the mkinitcpio step (you should now be arch-chroot
ed inside the encrypted system).
Now the encrypt
hook has to be modified to let cryptsetup
use the separate header (base source and idea for these changes published on the BBS). Make a copy so it is not overwritten on a mkinitcpio update:
# cp /lib/initcpio/hooks/encrypt{,2} # cp /usr/lib/initcpio/install/encrypt{,2}
/lib/initcpio/hooks/encrypt2 (around line 52)
warn_deprecated() { echo "The syntax 'root=${root}' where '${root}' is an encrypted volume is deprecated" echo "Use 'cryptdevice=${root}:root root=/dev/mapper/root' instead." } local headerFlag=false for cryptopt in ${cryptoptions//,/ }; do case ${cryptopt} in allow-discards) cryptargs="${cryptargs} --allow-discards" ;; header) cryptargs="${cryptargs} --header /boot/header.img" headerFlag=true ;; *) echo "Encryption option '${cryptopt}' not known, ignoring." >&2 ;; esac done if resolved=$(resolve_device "${cryptdev}" ${rootdelay}); then if $headerFlag || cryptsetup isLuks ${resolved} >/dev/null 2>&1; then [ ${DEPRECATED_CRYPT} -eq 1 ] && warn_deprecated dopassphrase=1
Now edit the mkinitcpio.conf to add the encrypt2
and lvm2
hooks, the header.img
to FILES
and the loop
to MODULES
, apart from other configuration the system requires:
/etc/mkinitcpio.conf
MODULES="loop" FILES="/boot/header.img" HOOKS="... encrypt2 lvm2 ... filesystems ..."
This is required so the LUKS header is available on boot allowing the decryption of the system, exempting us from a more complicated setup to mount another separate USB device in order to access the header. After this set up the initramfs is created.
Next the boot loader is configured to specify the cryptdevice=
also passing the new header
option for this setup:
cryptdevice=/dev/sdX:enc:header
To finish, following Dm-crypt/Encrypting an entire system#Post-installation is particularly useful with a /boot
partition on an USB storage medium.