Установка Линукса на зашифрованный DM-Crypt с LUKS корневой раздел
Введение
В этой статье будет описан способ установки 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 Заполнение диск случайными данными
Процедура записи случайных данных на все дисковое пространство раздела необходимо для того, чтобы было невозможно узнать как много данных было записанно на диск.
Теперь следуем Gentoo Installation Guide (http://www.gentoo.org/doc/en/handbook/handbook-x86.xml) с 5-го до 7-го пункта, либо копируем зараннее установленный дистрибутив линукс на смонтированный раздел.
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}"
# 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}"
}
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
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)
Если компилировать эти опции как модули, то их нужно скопировать вместе с зависимостями в дирректорию /tmp/initramfs/lib/modules/`uname -r`/ и добавить имена без суффикса .ko в файл /tmp/initramfs/etc/modules/boot.
12 /etc/fstab
Редактирования файла описания точек монтирования файловых систем. UUID дисков находятся в /dev/disk/by-uuid.
Во время загрузки я получал такую ошибку:
"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