Pull to refresh

Мечта параноика или Еще раз о шифровании

Reading time7 min
Views101K
В свете последних событий с torrents.ru и активизации государственных группировокорганов по борьбе с пиратством, думаю многие задумались как же обезопасить себя или свой сервер на случай если придут нежданные «гости». Вот и мне подвернулась задача защитить локальный медиасервер от посягательств, проведя пару дней за гугленнием и чтением мануалов/howto — мне удалось это реализовать. Скажу сразу, статей по шифрованию очень много, но в основном они рассчитаны на шифрование только определенных разделов, либо устарели/содержат много ошибок.

ЦЕЛИ:

  1. Весь винт(винты) должны быть надежно зашифрованы
  2. На винтах не должно быть абсолютно никакой разбивки, так как будто это новый(или стертый) винт
  3. ОС должна стоять на зашифрованных разделах
  4. Должна быть возможность увеличения дискового пространства, путем добавления новых винтов
  5. Загрузка системы без ввода ключа от шифрованных данных


ТЕОРИЯ:


Для начала вкратце объясню теорию как это все будет работать: загрузчик системы и ключ доступа будут храниться на небольшом(<50Mb) разделе флешки, при включении загрузчик разблокирует доступ к шифрованному винту, загружает ядро, подключает виртуальные разделы(LVM), далее происходит обычная загрузка системы.
В качестве операционной системы был выбран Ububtu Server 9.10, но реализовать эту задачу можно на любой UNIX-like системе. Сразу оговорюсь, в самом инсталляторе есть возможность шифрования системы на этапе установки, но там нельзя реализовать пункты 1 и 2 из списка выше потому будем действовать в ручную.
Нам понадобится:
  1. Образ Ubuntu Server 9.10
  2. LiveCD дистрибутив. Я взял обычный Ubuntu Desktop CD, так как он умеет работать с шифрованными разделами «из коробки».
  3. Флешка которая будет использоваться для загрузки системы
  4. Базовый знания по *nix системам
  5. Прямые руки


ЭТАП 1. Подготовка флешки и жесткого диска


А) Разбивка флешки на разделы и создание ключа
Подключаем флешку к компьютеру на котором будет шифроваться винт и загружаемся с LiveCD. Наша задача создать на нашей флешке 2 раздела: первый займет почти все пространство и будет отформатирован в FAT16,FAT32,NTFS(на ваш выбор), второй раздел делаем в конце флешки на 50MB и форматируем в ext2. Такая разбивка не случайна — благодаря начальному разделу флешка будет полностью функциональна в любой ОС. Также в windows второй раздел будет недоступен — что является плюсом, если ваша флешка попадет не в те руки. Для создания разделов я воспользовался графической утилитой GParted(была на LiveCD), но никто не мешает вам воспользоваться fdisk. После создания разделов примонтируем их в системе:
sudo su
mkdir /mnt/flash /mnt/boot
mount /dev/sdb1 /mnt/flash
mount /dev/sdb2 /mnt/boot

Теперь создадим файл-ключ с помощью которого будем шифровать винт и сделаем его дубликат (на всякий случай):
dd if=/dev/random of=/mnt/boot/mykey bs=1 count=256
cp /mnt/boot/mykey /mnt/flash/

Б) Подготовка винта для шифрования
Для начала нам нужно забить наш винт полностью случайными данными. Это делается для того чтобы невозможно было определить в каких секторах находятся ваши данные и сколько места они занимают, грубо говоря весь винт открытый в HEX-редакторе, должен выглядеть равномерно забитым несвязным мусором, вне зависимости от количества вашей информации. Существует 2 стандартных способа сделать это, оба они медленные, так что запаситесь терпением.
Первый способ. Случайная информация берется из псевдогенератора случайных чисел и пишется на винт блоками по 2MB. Скорость генерации данных на Core Quad Q6600 составила всего 6Mb/сек, так что тестовый винт на 80Гиг заполнился за 4 часа.
sudo dd if=/dev/urandom of=/dev/sda bs=2M

Второй способ лично я не проверил так как нашел уже после подготовки винта. В нем используется программа проверки винта на BAD-блоки. О скорости данного способа и «качестве» рандомданных сказать ничего не могу.
sudo /sbin/badblocks -c 10240 -s -w -t random -v /dev/sda


Теперь, когда поверхность диска заполнена, пора его зашифровать. Для этого воспользуемся технологией LUKS.
sudo cryptsetup -h=sha256 -c=aes-cbc-essiv:sha256 -s=256 luksFormat /dev/sda /mnt/boot/mykey

Вас предупредят об уничтожении данных, для подтверждения нужно написать YES(большими буквами). Подключаем шифрованный диск:
sudo cryptsetup -d=/mnt/boot/mykey luksOpen /dev/sda drivespace

Вводим пароль и получаем новое блочное устройство /dev/mapper/drivespace. С полученным устройством можно работать как с обычным винтом.
В) Создание виртуальной разбивки на разделы(LVM)
Можно создать обычные разделы и отформатировать их, но такой способ не позволит в будущем расширять наши разделы(придется добавлять новые) поэтому воспользуемся технологией LVM. Вкратце она позволяет в любой момент добавить новые винты в пул и расширить логические разделы на добавленное свободное место. Мой LiveCD загрузился без нужных пакетов поэтому сначала устанавливаем их, а потом создаем из нашего расшифрованного винта физический раздел и делим его на логические.
sudo su
apt-get install lvm2
pvcreate /dev/mapper/drivespace
vgcreate vg /dev/mapper/drivespace
lvcreate -L1G -nswap vg
lvcreate -L3G -nroot vg
lvcreate -l 100%FREE -ndata vg

Теперь у нас есть еще 3 блочных устройства /dev/mapper/vg-swap /dev/mapper/vg-root /dev/mapper/vg-data. Форматируем их в нужные ФС.
sudo su
mkswap /dev/mapper/vg-swap
mkfs.ext4 /dev/mapper/vg-root
mkfs.xfs /dev/mapper/vg-data

Все! Наш винт готов к переносу ОС на него. Для подготовки системы нам понадобятся UUIDы винта и разделов потому сохраним их в файл на флешке
ls -l /dev/disk/by-uuid >/mnt/flash/uuid.txt

ЭТАП 2. Подготовка операционной системы


А) Установка системы
Устанавливать нашу ОС нужно либо на отдельный винт, либо на втором компьютере(вирт. машине). Перед установкой подключаем нашу флешку. Установку лучше делать в минимальной конфигурации, настройки выбираете под свои нужды. Единственный важный момент — нужно указать чтобы /boot устанавливался на второй раздел флешки сразу же(чтобы потом не переносить) и убедится что загрузчик Grub будет поставлен на флешку.
Б) Установка дополнительных пакетов, изменение настроек
После завершения установки нам нужно добавить в систему пакеты для поддержки шифрования и LVM и подправить некоторые конфиги. Устанавливаем пакеты(при подключеном инете):
sudo apt-get -y install cryptsetup lvm2
Правим конфиг GRUB. В Ubuntu используется GRUB2, потому правим /boot/grub/grub.cfg. Ищем menuentry «Ubuntu, Linux 2.6.31-14-server» и чуть ниже меняем
linux   /vmlinuz-2.6.31-14-server root=UUID=9a651089-88fa-46d6-b547-38d3e10d4e67 ro   quiet splash

на
linux   /vmlinuz-2.6.31-14-server root=/dev/mapper/vg-root ro   quiet splash

Правим /etc/fstab
proc            /proc           proc    defaults        0       0
UUID=eb7f5e37-b957-43dd-8af6-3c8983670df5       /boot           ext2    defaults        0       2
/dev/mapper/vg-root       /               ext4    errors=remount-ro 0       1
/dev/mapper/vg-data      /home           xfs     defaults        0       1
/dev/mapper/vg-swap       none            swap    sw              0       0

Для /boot точку монтирования указываем в виде UUID второго раздела флешки(можно взять с файла на флешке или посмотреть заново в системе), это нужно чтобы система всегда монтировала правильный раздел независимо от количества подключенных флешек/винтов.
Правим /etc/crypttab
drivespace   UUID=090d14c1-e3c8-48e7-b123-6d9b8b2e502b       /boot/mykey      luks,cipher=aes-cbc-essiv:sha256

тут указываем UUID от нашего шифрованного винта(смотрим его в файле на флешке)
В) Изменение initrd
Подготавливаем initrd для работы с шифрованием и LVM. В файле /etc/initramfs-tools/modules добавляем:
dm_mod
dm_crypt
sha256
aes_generic

Создаем файл /etc/initramfs-tools/hooks/cryptokeys с таким скриптом:
PREREQ=""

prereqs()
{
        echo "$PREREQ"
}

case $1 in
prereqs)
        prereqs
        exit 0
        ;;
esac

if [ ! -x /sbin/cryptsetup ]; then
        exit 0
fi

. /usr/share/initramfs-tools/hook-functions
mkdir ${DESTDIR}/etc/console
cp /boot/mykey ${DESTDIR}/etc/console
copy_exec /sbin/cryptsetup /sbin

Он скопирует наш файл-ключ в необычное место внутри образа initrd, чтобы лишний раз флешку не монтировать. Создаем файл /etc/initramfs-tools/scripts/local-top/cryptokeys со скриптом:
PREREQ="udev"

prereqs()
{
        echo "$PREREQ"
}

case $1 in
# get pre-requisites
prereqs)
        prereqs
        exit 0
        ;;
esac
modprobe -b dm_crypt
modprobe -b aes_generic
modprobe -b sha256

while ! /sbin/cryptsetup -d=/etc/console/mykey luksOpen /dev/disk/by-uuid/090d14c1-e3c8-48e7-b123-6d9b8b2e502b drivespace; do
       echo "Try again..."
done

Он выполнится в процессе загрузки initrd, загрузит нужные модули ядра и будет пытаться открыть наш зашифрованный винт с UUID=090d14c1-e3c8-48e7-b123-6d9b8b2e502b. (Цикл был сделан для случая с парольной фразой вместо ключа). Вам нужно вписать сюда свой UUID от зашифрованного винта.
Теперь выполняем:

sudo chmod +x /etc/initramfs-tools/hooks/cryptokeys
sudo chmod +x /etc/initramfs-tools/scripts/local-top/cryptokeys
sudo update-initramfs -u -k all

Г) Упаковка системы для переноса
Смонтируем наш раздел с корневой фс в отдельную папку и упакуем на первый раздел флешки:
mkdir /mnt/root && mount /dev/sda1 /mnt/root && cd /mnt/root
tar cfjv /mnt/flash/systembackup.tar.bz2 .  #НЕ ПРОПУСТИТЕ ТОЧКУ В КОНЦЕ СТРОКИ

Теперь можно переносить систему.

ЭТАП 3. Перенос системы


Тут все просто: подключаем нашу флешку с бекапом, загружаемся с LiveCD, подключаем шифрованный винт, устанавливаем пакет поддержки LVM, монтируем виртуальный корневой раздел(возможно сначала придется выполнить vgscan и vgmknodes чтобы система увидела разделы), монтируем флешку и распаковываем архив с системой.
sudo su
mkdir /mnt/flash 
mount /dev/sdb1 /mnt/flash
cryptsetup -d=/mnt/flash/mykey luksOpen /dev/disk/by-uuid/090d14c1-e3c8-48e7-b123-6d9b8b2e502b drivespace
apt-get install lvm2
#vgscan && vgchange -a y && vgmknodes vg  #Выполняем если система не увидела виртуальные разделы
mkdir /mnt/root
mount /dev/mapper/vg-root /mnt/root
mkdir /mnt/root/home
mount /dev/mapper/vg-home /mnt/root/home
cp /mnt/flash/systembackup.tar.bz2 /mnt/root && cd /mnt/root  #переносим архив на винт, для ускорения распаковки
tar xfvj systembackup.tar.bz2

Ну вот и все, перезагружаем компьютер и загружаемся с флешки. Если все сделано правильно, то через несколько секунд вы увидите надпись Key slot 0 unlocked, значит ваш винт расшифровался и подключился, после этого пойдет стандартная загрузка системы.

Примечания, источники


В случае домашнего компьютера такая система дает вам возможность надежно защитить свою личную информацию и не позволит никому пользоваться компьютером без вашего ведома(без флешки); в случае сервера в организации, если к вам пришла проверка — выдернули флешку и тыкнули reset и для экспертов у вас нерабочий/новый компьютер; для сервера у хостера я бы усложнил систему и хранил ключ где-то в сети, если сервер отключат и заберут, он не загрузится без инета(а вам нужно быстро убрать доступ к ключу — чтобы вообще не загрузился).

Если у вас все заработало с первого раза, то можно смело удалять все файлы с первого раздела флешки.

Обязательно сделайте копию своего ключа, чтобы не потерять доступ к своим данным. Также неплохой идеей будет добавить второй ключ в виде пароля(как это сделать можно прочитать в документации LUKS/cryptsetup). Организация устойчивого к сбоям хранилища на основе RAID1,5,6 также будет не лишней при хранении ценной инфы.

При настройке всей этой системы я изначально смоделировал ее на виртуальной машине, а потом только перенес на реальный компьютер. Еще очень хотелось бы узнать мнение юристов (желательно из Украины) на счет доказуемости вины в распространении пиратского контента, если эксперты не смогут добраться до информации (а это невозможно без ключа), но обнаружат что винт зашифрован.

LUKS Википедия
LVM
EncryptedFilesystemHowto5 — самая полезная из найденных мной статей, практически все делалось по ней.
UPD Внес исправление в команду шифрования винта. За замечание спасибо ITpower
Tags:
Hubs:
Total votes 183: ↑176 and ↓7+169
Comments198

Articles