Введение В этой статье будет описан способ установки Gentoo на зашифрованный корневой раздел. 1 Разметка диска. Имя Тип Тип ФС Точка монтир. Размер (MB) Шифрование ------------------------------------------------------------------------------------------------------------ sdb1 Основной ext2 /boot 100 нет sdb5 Логический swap swap 1000 да sdb6 Логический ext4 / 15000 да sdb7 Логический ReiserFS /home 1000 да sdb8 Логический ext4 /usr/local 5000 да sdb9 Логический ReiserFS /media/storage 10000 нет sdb10 Логический ext3 /media/backup 15000 да sdb11 Логический XFS /media/multimedia 160000 нет Осн/Лог Свободно 42900 sdb9 - раздел для хранения различной текстовой информации, софта, музыки (не зашифрован); sdb10 - раздел для создания резервных копии важных данных (зашифрован) sdb11 - раздел для хранения мультимедийной информации и больших файлов DVD с видео, дистрибутивами Linux'а (не зашифрован) Свободное пространство оставляем для экспериментов с другими дистрибутивами GNU/Linux и операционными системами, например Hackintosh или Solaries. 2 Заполнение диск случайными данными Процедура записи случайных данных на все дисковое пространство раздела необходимо для того, чтобы было невозможно узнать как много данных было записанно на диск. dd if=/dev/urandom of=/dev/sdb5 dd if=/dev/urandom of=/dev/sdb6 dd if=/dev/urandom of=/dev/sdb7 dd if=/dev/urandom of=/dev/sdb8 dd if=/dev/urandom of=/dev/sdb10 При записи на диск программа dd не предоставляет индикатор прогресса, но узнать сколько данных записанно можно командой: killall -USR1 dd 3 Генерация ключей dd if=/dev/urandom count=1 > swap_key dd if=/dev/urandom count=1 > home_key dd if=/dev/urandom count=1 > usr-local_key dd if=/dev/urandom count=1 > backup_key Ключь для корневого раздела зашифровываем: dd if=/dev/urandom count=1 | gpg --symmetric > ./root_key.gpg 4 Шифрование swap раздела cryptsetup -c blowfish -h sha256 -d /dev/urandom create swap /dev/sdb5 mkswap /dev/mapper/swap swapon /dev/mapper/swap 5 Шифрование разделов диска cryptsetup --cipher serpent-cbc-essiv:sha256 --key-size 256 luksFormat /dev/sdb7 home_key cryptsetup --cipher serpent-cbc-essiv:sha256 --key-size 256 luksFormat /dev/sdb8 usr-local_key cryptsetup --cipher serpent-cbc-essiv:sha256 --key-size 256 luksFormat /dev/sdb10 backup_key gpg --decrypt root_key.gpg | cryptsetup --cipher serpent-cbc-essiv:sha256 --key-size 256 luksFormat /dev/sdb6 6 Открытие зашифрованных LUKS разделов cryptsetup luksOpen /dev/sdb7 home --key-file home_key cryptsetup luksOpen /dev/sdb8 usr-local --key-file usr-local_key cryptsetup luksOpen /dev/sdb10 backup --key-file backup_key gpg --decrypt root_key.gpg | cryptsetup luksOpen /dev/sdb6 root 7 Создание файловых систем на зашифрованных разделах mkfs.ext4 /dev/sdb6 mkfs.reiserfs /dev/sdb7 mkfs.ext4 /dev/sdb8 mkfs.ext3 /dev/sdb10 8 Монтирование файловой(ых) системы mount /dev/mapper/root /mnt/gentoo Теперь следуем Gentoo Installation Guide (http://www.gentoo.org/doc/en/handbook/handbook-x86.xml) с 5-го до 7-го пункта, либо копируем зараннее установленный дистрибутив линукс на смонтированный раздел. 9 Скрипт загрузки initramfs - init #!/bin/sh uv_init=/sbin/init uv_root_mapping=root uv_swap_mapping=swap gv_root_mode=ro die() { local lv_msg="$1" umount -n /mnt 2>/dev/null echo -e "\033[01;31m${lv_msg}\033[00m" echo } bin_exist() { [ ! -e "/bin/${1}" ] && [ ! -e "/sbin/${1}" ] && die "Error: ${2} ${1} not found." } modprobe_group() { local lv_group="$1" local lv_mod if [ -f "/etc/modules/${lv_group}" ]; then for lv_mod in `cat "/etc/modules/${lv_group}"`; do modprobe "${lv_mod}" > /dev/null 2>&1 done fi } get_key() { local lv_dev="${1}" gv_filepath="${2}" local lv_devname="`echo "${lv_dev}" | cut -d'/' -f3 | tr -d '0-9'`" # for use with /sys/block/ local lv_filename="`echo "${gv_filepath}" | sed 's/\/.*\///g'`" local lv_first_time=1 local lv_iter=0 while ! mount -n -o ro,iocharset=cp437 "${lv_dev}" /mnt 2>/dev/null >/dev/null do if [ "${lv_first_time}" != 0 ]; then echo "Insert removable device and press Enter." read x echo "Please wait a few seconds...." lv_first_time=0 else [ ! -e "/sys/block/${lv_devname}" ] && echo "Info: /sys/block/${lv_devname} does not exist." [ ! -e "${lv_dev}" ] && echo "Info: ${lv_dev} does not exist." fi sleep 5 lv_iter = $(($lv_iter + 5)) echo "Passed ${lv_iter} sec" done echo "Info: Removable device mounted." # check if keyfile exist if [ ! -e "/mnt/${gv_filepath}" ]; then die "Error: ${gv_filepath} does not exist on ${lv_dev}." fi # get the key [ "$uv_check_env" -eq 1 ] && bin_exist "gpg" "--" } exec_cryptsetup() { # 1 is device, 2 is mapping local lv_arg1="create" local lv_arg2="${2}" local lv_arg3="${1}" cryptsetup isLuks "${1}" 2>/dev/null && { lv_arg1="luksOpen"; lv_arg2="${1}"; lv_arg3="${2}"; } # Fixup gpg tty requirement mv /dev/tty /dev/tty.org cp -a /dev/console /dev/tty while [ ! -e "/dev/mapper/${2}" ] do sleep 2 gpg --quiet --homedir / --logger-file /dev/null --decrypt /mnt/${gv_filepath} | \ cryptsetup "${lv_arg1}" "${lv_arg2}" "${lv_arg3}" 2>/dev/null done rm /dev/tty mv /dev/tty.org /dev/tty umount -n /mnt } do_root_work() { [ -n "${gv_root_device}" ] || die "Error: root missing." # if 'init_key_root' arg was given [ -n "${gv_key_root_device}" ] || die "Error: init_key_root: device field empty." [ -n "${gv_key_root_filepath}" ] || die "Error: init_key_root: filepath field empty." get_key "${gv_key_root_device}" "${gv_key_root_filepath}" echo "Partition: root" exec_cryptsetup "${gv_root_device}" "${uv_root_mapping}" mount -o "${gv_root_mode}" "/dev/mapper/${uv_root_mapping}" /new-root if [ "$?" -ne 0 ]; then cryptsetup luksClose "${uv_root_mapping}" 2>/dev/null || cryptsetup remove "${uv_root_mapping}" die "Error: mount root failed, dm-crypt mapping closed." fi } do_work() { print_msg do_root_work do_switch } do_switch() { # Unmount everything and switch root filesystems for good: # exec the real init and begin the real boot process. echo > /proc/sys/kernel/hotplug [ "${gv_splash_silent}" -eq 1 ] echo "Switching / ..." sleep 1 umount -l /proc umount -l /sys umount -l /dev exec switch_root /new-root "${uv_init}" } print_msg() { echo local msg=`cat /etc/msg` echo -e "\033[01;32m${msg}\033[00m" echo } set_gv() { gv_root_device="${gv_root}" gv_key_root_device="${gv_key_root}" gv_key_root_filepath="/.keys/gentoo-root-key.gpg" } main() { gv_root_uuid="8cg8ff58-859b-43ca-b7be-55a3ceb01ce9" gv_key_root_uuid="6A91-1360" export PATH=/sbin:/bin # dmesg -n 1 umask 0077 [ ! -d /proc ] && mkdir /proc mount -t proc proc /proc [ "$uv_check_env" -eq 1 ] && bin_exist "cryptsetup" "--" [ ! -d /tmp ] && mkdir /tmp [ ! -d /mnt ] && mkdir /mnt [ ! -d /new-root ] && mkdir /new-root mount -t sysfs sysfs /sys modprobe_group boot # populate /dev from /sys mount -t tmpfs tmpfs /dev /sbin/mdev -s # handle hotplug events echo /sbin/mdev > /proc/sys/kernel/hotplug # wait until root device won't be detected gv_root= gv_key_root= while [ -z "${gv_root}" ] || [ -z "${gv_key_root}" ] do sleep 3 gv_root=`findfs UUID=${gv_root_uuid}` gv_key_root=`findfs UUID=${gv_key_root_uuid}` done # set global variables for root and key devices set_gv do_work } main Этот скрипт является упрощенной версией (http://www.gentoo-wiki.info/SECURITY_System_Encryption_DM-Crypt_with_LUKS) 10 Создание initramfs образа Initramfs будет создан на основе BusyBox (www.busybox.net). ROOT="/tmp/bb" USE="static" emerge busybox cd /tmp mkdir initramfs cd initramfs mkdir bin dev etc lib mnt new-root proc sbin sys tmp cd bin cp /tmp/bb/bin/busybox . for i in echo md5sum mkdir mknod modprobe mount mv rm sed sh switch_root tr umount do ln busybox $i done cd ../sbin cp /sbin/cryptsetup . ln ../bin/busybox mdev cd ../dev mknode --mode=0660 null c 1 3 mknode --mode=0660 console c 5 1 Установка gnupg. Устанавливаем версию 1.4.9, в ней нет gpg-agent. USE="static" emerge -v =gnupg-1.4.9 cd ../bin cp /usr/bin/gpg . Копирование init скрипта в корневой раздел: cp /path/to/init /tmp/initramfs Упаковка initramfs образа в сжатый cpio архив: find . | cpio -o -H newc | gzip -9 > /boot/initramfs-gentoo-crypt 11 Конфигурация ядра Device Drivers ---> Multi-device support (RAID and LVM) ---> <*> Device mapper support <*> Crypt target support [*] DM uevents Device Drivers ---> Block devices ---> <*> RAM disk support [*] Initial RAM disk (initramfs/initrd) support File systems ---> Pseudo filesystems ---> [*] /proc file system support [*] Virtual memory file system support (former shm fs) # support for sysfs required (CONFIG_SYSFS) Cryptographic options ---> <*> SHA256 digest algorithm <*> SHA384 and SHA512 digest algorithms <*> Blowfish cipher algorithm <*> Twofish cipher algorithm <*> Serpent cipher algorithm <*> AES cipher algorithms (x86_64) <*> The Extended 4 (ext4) filesystem [ ] Enable ext4dev compatibility [*] Ext4 extended attributes [*] Ext4 POSIX Access Control Lists [*] Ext4 Security Labels Если компилировать эти опции как модули, то их нужно скопировать вместе с зависимостями в дирректорию /tmp/initramfs/lib/modules/`uname -r`/ и добавить имена без суффикса .ko в файл /tmp/initramfs/etc/modules/boot. 12 /etc/fstab Редактирования файла описания точек монтирования файловых систем. UUID дисков находятся в /dev/disk/by-uuid. UUID=b5bd3eaa-27ef-42g3-a2c4-ec8696564bdc /boot ext2 noauto,noatime 0 0 UUID=1a9cs4fb-3esd-48b6-b9fb-13dda6928060 / ext4 noatime 0 1 UUID=8d7d41ff-9geb-4e83-ad8b-4cc8cb89b408 none swap sw 0 0 UUID=e0a39a9d-d57b-44e3-9114-63c30726827f /home reiserfs noatime,noexec 0 0 UUID=f9601db4-d6e7-4952-b129-e501128c55e9 /usr/local ext4 relatime,user,exec 0 0 UUID=9776e7bd-15b6-44cc-b1fc-6700401f6466 /media/storage reiserfs noexec,user 0 0 UUID=3d3ea35b-b6eb-411f-9516-48741e038926 /media/backup ext4 defaults,noexec 0 0 UUID=a12cfa02-60e8-4c5b-bdfd-34d3c7006a6c /media/multimedia xfs noexec,user 0 0 13 Конфигурация загрузчика default 0 timeout 5 splashimage=(hd0,0)/boot/grub/splash.xpm.gz title Gentoo Linux 2.6.29-r5 root (hd0,0) kernel /boot/kernel-genkernel-x86_64-2.6.29-gentoo-r5 vga=791 root=UUID=ba596e56-046a-4c87-8ab8-184b2bbd7e81 initrd /boot/initramfs-gentoo-crypt 14 Монтирование зашифрованных разделов во время запуска системы В файле /etc/conf.d/dmcrypt: swap=crypt-swap source='/dev/disk/by-uuid/c01f3387-5426-4a25-8051-220938f81a7c' key='/.keys/gentoo-crypt-swap' remdev='/dev/disk/by-uuid/6A91-1378' target=home source='/dev/disk/by-uuid/6d155170-a323-46ca-aa17-cdb462bc842b' key='/.keys/gentoo-crypt-home' remdev='/dev/disk/by-uuid/6A91-1378' target=usr-local source='/dev/disk/by-uuid/c04f3387-5426-4a25-8051-220938f81a7c' key='/.keys/gentoo-crypt-usr_local' remdev='/dev/disk/by-uuid/6A91-1378' target=backup source='/dev/disk/by-uuid/6d255170-a323-46ca-aa17-cdb462bc842b' key='/.keys/gentoo-crypt-backup' remdev='/dev/disk/by-uuid/6A91-1378' Во время загрузки я получал такую ошибку: "Failed to find mount point for ${target}, skipping" Что бы ее исправить в скрипте /lib/rcscripts/addons/dm-crypt-start.sh заменяем строку: mount_point=$(grep "/dev/mapper/${target}" /proc/mounts | cut -d' ' -f2) на mount_point=$(grep "/dev/${target}" /proc/mounts | cut -d' ' -f2) 15 Проверка md5 суммы ядра во время загрузки системы Вычисляем md5 сумму ядра: md5sum /boot/vmlinux-2.6.29-gentoo-rc5 В скрипте /etc/init.d/local добавляем функцию, в которой вместо значения переменной md5sum_boot="xxx." подставляем свое. check_md5sum_initramfs() { mnt=`mount | grep /boot` if [[ -z ${mnt} ]]; then mount /boot fi local md5sum_boot="xxxxxxx" local md5sum=`md5sum /boot/vmlinuz-2.6.29-gentoo-r5 | cut -d" " -f1` [ "${md5sum}" != "${md5sum_boot}" ] && echo -e "\033[01;31m * ALARM! Kernel partition was modified!\033[00m" && read x if [[ -z ${mnt} ]]; then umount /boot fi } check_md5sum_initramfs Список литературы http://www.gentoo-wiki.info/SECURITY_System_Encryption_DM-Crypt_with_LUKS http://forum.antichat.ru/showthread.php?t=51519