Inspired by Insecure

December 5, 2015 at 4:43 pm

Криптофицируем FreeBSD

freebsd-operating-systems-_676085-36

В связи с последними событиями многие всерьез задумываются о безопасности своих компьютерных систем. Новостные ленты пестрят сообщениями о том, что спецслужбы промышляют слежкой за спинами обычных граждан. Громкие аресты, разоблачения и скандалы не сходят со страниц СМИ. И конечно, каждому хочется себя обезопасить от глаз Большого Брата, будь то реальная жизнь или виртуальная реальность.

Loading…

Обеспечение безопасности — дело трудное. Можно сравнить ее со стеной из кирпичей: если правильно их сложить и скрепить, то получится прочная конструкция. Но даже самая навороченная защита не спасет от злоумышленника, если тот может спокойно получить физический доступ к объекту нападения. Поэтому обеспечивать безопасность мы начнем с ограничения такого доступа. А точнее, рассмотрим случай, когда злоумышленник (спецслужбы, сантехник дядя Вася…) уже получил его и намеревается прочитать твои секреты.

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

Pre-install

Не секрет, что от конфигурации компьютера зависит очень много, а работа со средствами шифрования накладывает еще большие требования на железо. Моя тестовая система выглядит так:

Intel Xeon SL8P2 3,8 ГГц
8192 RAM DDR-333 ECC
Intel RAID Controller SRCU42L Ultra320 SCSI, RAID 0/1/4/5/10, Cache 64 Мбайт
6 HDD SCSI MAT3073NC Ultra 320 SCSI/SCA2/LVD in RAID-10
OS: FreeBSD 10.1

Вариантов использования криптографии великое множество. Можно сделать отдельный зашифрованный диск и хранить всю информацию там. Или же он будет съемным, и можно использовать его тогда, когда потребуется. Это в какой-то степени защитит от злоумышленника. Почему в какой-то? Да потому, что грамотный нападающий не побрезгует покопаться во временных или конфигурационных файлах твоей системы. Возможно, он найдет то, что его интересует, и ему не придется заниматься расшифровкой всего диска.

Чтобы избежать столь неприятной ситуации, мы объединим описанные варианты в один и на выходе получим зашифрованный диск с ОС, которая будет загружаться со съемного носителя. Ядро системы будет находиться на том же самом носителе: чтобы загрузиться, нам понадобится физическое присутствие. Вернее, для загрузки с зашифрованного корневого раздела необходимо, чтобы ядро ОС было не зашифрованным. В этом случае лучше всего его разместить отдельно. Так мы убьем сразу двух зайцев одним выстрелом: без носителя (ядра) система не загрузится, а злоумышленнику придется подумать, как, не выключая сервер, перенести его в другое место для более детального изучения :). Да и сам факт присутствия ОС будет скрыт от посторонних глаз, что не может не радовать.

Конечно, это доставляет много неудобств, особенно если сервер критический и работа должна идти 24/7/365. Но деваться некуда: чем безопаснее система, тем труднее ей пользоваться. Возможно, в будущем эти меры спасут тебе жизнь. Согласись, весомее аргумент найти весьма затруднительно…

 

Сверка контрольной суммы образа FreeBSD 10.1 с помощью HashTab

Сверка контрольной суммы образа FreeBSD 10.1 с помощью HashTab

Итак, нам понадобится дистрибутив FreeBSD 10.1, записанный на любой носитель. Настоятельно рекомендую скачивать последние с официального сайта производителя и сверять контрольные суммы. В качестве съемного носителя, на котором мы будем хранить наше ядро, возьмем Kingston DataTraveler microDuo USB 2.0. Выбор пал на него, так как он очень маленький — его можно легко проглотить или быстро уничтожить в экстренных ситуациях.

 

1437478141_c0a3_flashdrive

Размер съемного устройства в сравнении с монетой

Не менее важна надежность носителя. Если у нас каким-то волшебным образом пропадет информация с него, мы можем со стопроцентной уверенностью распрощаться с информацией на жестких дисках нашего сервера. У Kingston, по многочисленным отзывам пользователей, с надежностью все нормально. Стоит отметить, что стандарт USB 2.0 будет накладывать ограничения на скорость загрузки ОС. Для достижения более высоких скоростей используй версию USB 3.0, если ее поддерживает твое оборудование.

Install

Загружаемся с нужного нам устройства. Нас приветствует синий экран bsdinstall. Жмем Install => Выбираем Keymap => Пишем Hostname => По желанию выставляем галочки в меню компонентов системы => В меню Partitioning выбираем Shell.

Выбираем Shell

Выбираем Shell

Перед установкой ОС забьем наш диск (у меня аппаратный RAID-массив /dev/da0) мусором. Процесс долгий и нудный, так что запасись терпением:

#/bin/dd if=/dev/random of=/dev/da0 bs=100m

Так же поступим с флешкой (/dev/da1):

#/bin/dd if=/dev/random of=/dev/da1 bs=10m

Уничтожим таблицы разделов на устройствах:

#/sbin/gpart destroy –F /dev/da0
#/sbin/gpart destroy –F /dev/da1

Создадим таблицу разделов GPT на флешке:

#/sbin/gpart create –s gpt /dev/da1
da1 created

Для загрузки c USB-устройства нам необходим маленький раздел с загрузчиком на нем:

#/sbin/gpart add -t freebsd-boot -l bootcode -s 64k /dev/da1
da2p1 added

Далее создадим раздел, на котором будет храниться ядро ОС:

#/sbin/gpart add –t freebsd-usf –l bootfs –s 2g /dev/da1
da2p2 added

В первый сектор записываем загрузчик MBR (это делается для старого оборудования, которое не поддерживает GPT), которому передает управление BIOS после включения компьютера. Он ищет раздел freebsd-boot по таблице GPT и если его находит, то загружает его содержимое в память, тем самым передавая эстафету управления ему. Там у нас прописался /boot/gptboot, который проверяет корректность таблиц и заголовков, а также ищет раздел freebsd-ufs и уже с него пытается загрузить ядро. Флаг -i указывает, что второй загрузчик надо записать в первый раздел:

#/sbin/gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 /dev/da1
bootcode written to da1

Создаем файловую систему (далее ФС) UFS2, включаем Soft Updates и журналирование:

#/sbin/newfs –U –O2 –j /dev/da1p2

Работать с полностью зашифрованным диском намного удобнее, чем отдельно с разделами. На данном этапе смонтируем вновь созданную ФС на разделе и создадим ключ шифрования для всего диска:

#/sbin/mount /dev/da1p2 /mnt
#cd /mnt && /bin/mkdir keys && cd keys
#/bin/dd if=/dev/random of=da0.key bs=512 count=10

Шифруем диск. Флаг -b активирует запрос пароля при начальной загрузке до монтирования корневой файловой системы. Флаг -K определяет файл ключа, -e задает алгоритм шифрования, -l определяет длину ключа, -s изменяет размер дешифруемого сектора, что положительно влияет на производительность при шифровании/дешифровании.

К выбору алгоритма шифрования стоит подходить с осторожностью. Надежность — это чуть ли не самый главный критерий, по которому следует выбирать. Если алгоритм не сможет противостоять криптоанализу, то нет смысла его использовать. По возможности надо выбирать старые алгоритмы, которые испытаны временем, открыты для криптоанализа и проверены миллионами людей по всему миру. Только так можно быть более-менее уверенным, что в алгоритме нет никаких закладок и уязвимостей — иначе можно наткнуться на security through obscurity.

Security through obscurity (рус. «безопасность через неясность») — принцип, используемый для обеспечения безопасности в различных сферах деятельности человека. Основная идея — скрыть внутреннее устройство системы или реализацию для обеспечения безопасности. Почему это плохо и чем это грозит, подробнее смотри тут.

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

 

Результаты тестирования зашифрованных ФС с помощью IOzone

Результаты тестирования зашифрованных ФС с помощью IOzone

#/sbin/geli init -b -K da0.key -e Camellia -l 256 -s 4096 /dev/da0
Enter new passphrase:
Reenter new passphrase:

Теперь, когда диск зашифрован, его можно размечать, но сначала его надо присоединить. Обрати внимание, что работать мы будем с da0.eli. Буквы в конце названия устройства означают, что наш диск зашифрован с помощью криптографической подсистемы geli:

#/sbin/geli attach –k da0.key /dev/da0
Enter passphrase for da0:
#/sbin/gpart create –s gpt /dev/da0.eli
da0.eli created

Почему мы выбрали именно geli, а не другую криптосистему? Поскольку Geli — нативное средство шифрования, повышается производительность и криптостойкость системы в целом. Имеется масса преимуществ: прозрачность работы для конечного пользователя, поддержка целого ряда алгоритмов шифрования, возможность иметь несколько ключей, загрузка с зашифрованного корневого раздела, высокая скорость работы за счет простого криптования сектор — сектор, поддержка одноразовых ключей шифрования и многое другое.

Создаем раздел для корневой файловой системы в 2 Гбайт. Указываем тип freebsd-ufs:

#/sbin/gpart add –t freebsd-ufs –l rootfs –s 2g /dev/da0.eli
da0.elip1 added

По поводу SWAP на сегодняшний день ведется много споров. Нужен или не нужен — решать тебе. Но я считаю, что в наше время выделить под него место не так дорого, как это было лет двадцать назад. В лучшем случае его можно разместить на другом физическом диске, что снизит нагрузку на дисковую подсистему.

Если ты все-таки надумаешь воспользоваться этим вариантом, то у geli есть великолепная возможность зашифровать раздел подкачки временным ключом. Об этом можно почитать в руководстве по FreeBSD на официальном сайте. Формула, по которой я рассчитываю размер подкачки, очень проста: SWAP >= RAM.

#/sbin/gpart add –t freebsd-swap –l swap –s 9g /dev/da0.eli
da0.elip2 added

Под /var отдадим 90 Гбайт места:

#/sbin/gpart add –t freebsd-ufs –l varfs –s 90g da0.eli
da0.elip3 added

Под /tmp — 13 Гбайт, так как некоторые программы при компиляции занимают много места и могут переполнить его. Это сделает невозможным дальнейшее корректное функционирование ОС:

#/sbin/gpart add –t freebsd-ufs –l tmpfs –s 13g /dev/da0.eli
da0.elip4 added

Под /usr выделим 60 Гбайт, а под /home — оставшееся место:

#/sbin/gpart add –t freebsd-ufs –l usrtfs –s 60g /dev/da0.eli
da0.elip5 added
#/sbin/gpart add –t freebsd-ufs –l homefs  /dev/da0.eli
da0.elip6 added

Создаем ФС на наших разделах, кроме SWAP (da0.elip2):

#/sbin/newfs –O2 –U –j /dev/da0.elip1
#/sbin/newfs –O2 –U –j /dev/da0.elip3
#/sbin/newfs –O2 –U –j /dev/da0.elip4
#/sbin/newfs –O2 –U –j /dev/da0.elip5
#/sbin/newfs –O2 –U –j /dev/da0.elip6

Размонтируем /dev/da1p2 и смонтируем корневую ФС в /mnt. Потом создадим точки монтирования для остальных разделов:

#cd && /sbin/umount /mnt
#/sbin/mount /dev/da0.elip1 /mnt
#cd /mnt && /bin/mkdir var && /bin/mkdir tmp && /bin/mkdir usr && /bin/mkdir  home
#/sbin/mount /dev/da0.elip3 var
#/sbin/mount /dev/da0.elip4 tmp
#/sbin/mount /dev/da0.elip5 usr
#/sbin/mount /dev/da0.elip6 home

Теперь нам необходимо создать временный файл fstab для «правильной» установки FreeBSD:

#/usr/bin/vi /tmp/bsdinstall-tmp-fstab
/dev/da0.elip1 /mnt ufs rw 1 1
/dev/da0.elip3 /mnt/var ufs rw 1 1
/dev/da0.elip4 /mnt/tmp ufs rw 1 1
/dev/da0.elip5 /mnt/usr ufs rw 1 1
/dev/da0.elip6 /mnt/home ufs rw 1 1

Проверяем, что ничего не забыли, выходим из shell’а и ждем, когда завершится установка:

#/sbin/gpart show
#/bin/df -h
#exit

После инсталляции системы устанавливаем пароль суперпользователя. По желанию настраиваем сеть, часовой пояс, добавляем пользователей. В меню Final Configuration выбираем Exit => No => LiveCD. Логинимся под root’ом, монтируем устройство, на которое скопируем ядро ОС, и перемещаем туда папку с ключами:

#/sbin/mount /dev/da1p2 /mnt/mnt/ && cd /mnt/mnt
#/bin/cp –R  ../boot . && /bin/mv keys boot

Теперь, для того чтобы ОС загрузилась, нам надо «рассказать» ей, что же мы натворили. Для этого необходимо отредактировать файл /boot/loader.conf:

#/usr/bin/vi boot/loader.conf
geom_eli_loadYES»
vsf.root.mountfromufs:/dev/da0.elip1»
geli_da0_keyfile0_loadYES»
geli_da0_keyfile0_typeda0:geli_keyfile0»
geli_da0_keyfile0_name=«/boot/keys/da0.key»
kern.geom.eli.threads4»
kern.geom.eli.batch1»

Первая строчка загружает модуль crypto.ko, без которого ОС не сможет понять наш диск. Вторая говорит, где находится корневая ФС. Дальнейшие три указывают, где лежит ключ шифрования, и связывают его с диском. Последние относятся к тюнингу подсистемы шифрования и необязательны. Они отвечают за количество процессов ядра, используемых для шифрования. Это дает прирост производительности в многопроцессорных системах за счет групповых операций при шифровании.

На последнем этапе надо привести в порядок файл /etc/fstab для уже установленной системы:

#vi ../mnt/etc/fstab
/dev/da0.elip1 / ufs rw 1 1
/dev/da0.elip2 none swap sw 0 0
/dev/da0.elip3 /var ufs rw 1 1
/dev/da0.elip4 /tmp ufs rw 1 1
/dev/da0.elip5 /usr ufs rw 1 1
/dev/da0.elip6 /home ufs rw 1 1

Post-install

Теперь перезагружаемся и выставляем в BIOS загрузку с нашего USB-устройства, где лежит ядро. При монтировании корневой ФС будет запрошена парольная фраза.

После ввода парольной фразы монтируется файловая система root

После ввода парольной фразы монтируется файловая система root

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

Если у тебя Linux или Windows, значит ли это, что ты не сможешь воспользоваться средствами шифрования? Совсем нет. Для них имеются свои решения. Например, в Linux существует система шифрования LUKS/dm-crypt, на основе подсистемы шифрования ядра, которая позволяет иметь несколько паролей на один раздел и получать доступ к зашифрованным дискам из Windows с помощью FreeOTFE. Управление криптосистемой производится посредством утилиты cryptsetup. Еще один вариант, loop-AES представляет собой модификацию стандартного драйвера loop.ko, который позволяет производить шифрование на лету.

Для Windows существует EFS — компонент ОС, позволяющий сохранять информацию на жестком диске в зашифрованном виде. BitLocker позволяет зашифровать полностью диск, а не отдельные файлы и папки, как это делает EFS. Есть множество сторонних коммерческих и некоммерческих продуктов под эти и другие ОС: PGP, GnuPG, VeraCrypt (форк TrueCrypt), DiskCryptor, Challenger и так далее. Многие из этих продуктов доступны во FreeBSD и могут использоваться совместно.

Loading Completed

В заключение хочется отметить: даже если USB-устройство будет украдено или утеряно, без парольной фразы злоумышленник не сможет получить доступ к данным. Без флешки и пароля жесткий диск для него будет простым куском металла. И как написано в handbook:

Вне зависимости от того, как атакующий завладел жестким диском или выключенным компьютером, криптографическая подсистема geli FreeBSD может защитить данные файловой системы компьютера даже против очень заинтересованной атакующей стороны с достаточными ресурсами.

Также не стоит забывать, что шифрование существенно замедляет дисковую подсистему, и, возможно, каждый читатель сам для себя выберет алгоритм шифрования, длину ключа, количество попыток ввода парольной фразы, чтения ключа из файла по частям и прочее. Для искушенных параноиков можно добавить проверку целостности данных HMAC-SHA и зашифровать SWAP временным ключом уже на зашифрованном диске :).

Не стоит забывать о различных атаках на криптографические алгоритмы. Например, от одной из них — атаки на повторение — geli защитить не может. Об этом и о многом другом рассказано в man geli(8) (Russian man geli(8))

То, что никакая криптография не сможет спасти от человеческого фактора — доказанный факт. Одна маленькая ошибка, и все твои усилия пойдут коту под хвост. Будь бдителен и помни: идеальной защиты не существует

Материал подготовлен специально для Журнала “Хакер

0 likes Research # , , , , , , , ,
Share: / / /

Leave a Reply

Your email address will not be published. Required fields are marked *

Be aware of the first

Материалы, опубликованные в этом блоге, отражают исключительно точку зрения автора и могут не совпадать с мнением и позицией его текущего работодателя.