Ключевые слова:freebsd, crypt, disk, geom, (найти похожие документы)
From: Mikhail E. Zakharov <zmey20000@yahoo.com.>
Newsgroups: email
Date: Mon, 5 Feb 2007 14:31:37 +0000 (UTC)
Subject: Шифрование корневого раздела диска во FreeBSD
Вместо введения
"Если у вас нет паранойи, это ещё не значит, что за вами не следят"
Народная мудрость
Когда разговор даже вскользь касается безопасности, люди моментально
делятся на два лагеря: первые очень серьезно относятся к проблеме,
вторые, напротив, легкомысленно и то и дело, в их речи проскакивает
насмешливое словечко "паранойя".
К счастью, ни к паранойе, ни к фобиям или каким-либо другим
расстройствам психики нижеизложенная статья не имеет ровно никакого
отношения, это всего лишь рассказ об одном из многих способов
настройки FreeBSD для хранения данных на жестком диске в зашифрованном
виде.
Итак, вариантов можно придумать множество: например, шифрование
отдельных файлов, использование файловых систем со встроенными
криптографическими механизмами, или шифрование на лету партиций как
по-отдельности, так и всех сразу, шифрование при помощи ключей или
защита паролями и т.д. и т.п.
Ладно, попробуем определиться со всеми pro и contra в том, что хочется
получить в итоге. Шифрование файлов было отринуто сразу, ибо мыслить
надо широко. Во FreeBSD использовать какую-либо файловую систему кроме
UFS2 мы не будем, поскольку любим изящные решения, и хотим обойтись
именно тем, что входит в состав обычного инсталляционного CD.
Шифровать ключами отдельные партиции идея - заманчивая, но не
спортивная, ибо все очень детально объяснено в соответствующей главе
handbook, а какой же смысл настоящим скалолазам ходить проторенными
тропами? Кроме того, сгенерированные ключи придется хранить где-то
отдельно, например, на флэшке (или как говорят иностранцы USB-stick),
а если учитывать достаточно известную особенность этих устройств
неожиданно пропадать из поля зрения обладателя в самый неподходящий
момент, то придется еще и хранить дубликат носителя с ключами в
надежном месте. Ну, вы меня поняли.
Единственным выходом для настоящего мужчины придется признать
следующий вариант: прозрачное посекторное шифрование всего
FreeBSD-слайса только при помощи паролей. Хотя, отказавшись от ключей,
жизнь мы себе упростили, но конечно, несколько ослабили безопасность.
Далее, из двух механизмов шифрования партиций, предложенных в
учебнике, метод gbde (GEOM Based Disk Encryption) придется отбросить,
поскольку он не справится с корневым разделом диска. Остается
GEOM-класс geli, который появился во FreeBSD 6.0 и, что более важно,
умеет работать с зашифрованным корневым разделом. Однако не все так
безоблачно, ведь для того, чтобы смонтировать пресловутую
зашифрованную корневую партицию, необходимо чтобы ядро, к моменту
монтирования, было уже предварительно загружено. Но при этом само
ядро, по идее, находится на зашифрованном диске. Замкнутый круг, что
весьма обидно.
В случае с шифрованием по ключам или ключам и паролю, эту проблему
решали выносом ядра на внешний носитель. Т.е. попросту делали флэшку
загрузочной и клали с ключами рядом каталог /boot. Это нам не
подходит, ведь от использования внешнего носителя мы уже отказались и
чтобы выкрутиться из вышеозначенного замкнутого круга, мы для загрузки
ядра будем использовать отдельный некриптованный загрузочный слайс
FreeBSD. Делать большим этот слайс не имеет смысла, ведь там будет
лежать только /boot и 128Mб будет больше чем достаточно. Как я выяснил
потом, размер директории /boot включающей в себя не сжатое ядро и все
модули, не превысил 30Мб. Соответственно, если мы стремимся уменьшить
эту область, можно воспользоваться опытом построения загрузочных
дискет проекта PicoBSD. А мы меж тем
Поехали.
Итак, загружаем систему с установочного CD FreeBSD 6.х. В моем случае
это оказался свежий дистрибутив FreeBSD 6.2-RELEASE. Дождавшись,
появления sysinstall быстро двигаемся по меню:
Country Selection (я оставил default)->Fixit->CDROM/DVD
пока не появится приятное пожелание Good Luck! и долгожданное
приглашение командной строки:
Fixit#
Попав наконец в командную строчку, начнем наше благородное дело. Для
начала, как предлагает учебник, можно полностью уничтожить всю
информацию на диске:
Fixit# dd if=/dev/random of=/dev/ad0 bs=1m
Или, как это рекомендует Marc Schiesser в документе
Complete Hard Disk Encryption Using FreeBSD's GEOM Framework,
в идеальном варианте данные на диски должны быть перезаписаны несколько
раз. Поэтому, кому не жалко времени, могут повторить команду dd N-раз.
Далее, нарежем диск на два слайса и сделаем первый (ad0s1) активным.
Кое-кто может подумать, что работа с fdisk вместе со всеми этими
расчетами размеров слайсов в цилиндрах занятие уж слишком неприятное,
что ж они смело могут вернуться в sysinstall и выполнить аналогичную
операцию там. Но мы-то ведь, настоящие мужчины, и трудности нас делают
только сильнее. Кроме того, в дальнейшем, когда мы будем создавать
зашифрованную область, sysinstall нам поможет мало.
Итак, на стенде имеется скромного размера ATA-диск со следующей
геометрией:
22192cyls/15 heads/63 sectors = 20971440 sectors (10239Mb)
Тогда операция разбивки этого диска на партиции может выглядеть так:
Fixit# dd if=/dev/zero of=/dev/ad0 bs=512 count=32
Fixit# cat /tmp/fdisk.ad0
p 1 165 63 261702 # слайс ad0s1: ~128М для /boot и kernel
p 2 165 262269 20709171 # слайс ad0s2: ~10Gb будет зашифрован
a 1
Fixit# fdisk -f /tmp/fdisk.ad0 -iv /dev/ad0 # запишем таблицу разделов на диск
Строго говоря команда dd в первой строчке блока команд не является
обязательной, но man bsdlabel(8) рекомендует ее использовать,
утверждая, что иначе не все BIOS'ы смогут потом правильно распознать
диск. Далее, команда cat /tmp/fdisk.ad0 означает, что файл с таким
названием необходимо подготовить, например, при помощи редактора vi.
На этом трепетном моменте мы пока оставим без внимания наш скромный
слайс ad0s1 с его единственной значащей партицией ad0s1a и обратим
свой взор на слайс ad0s2, пространство которого, по нашим коварным
планам будет превращено в [B]зашифрованное хранилище данных[/B].
Поскольку любое чудо, как повторяет один мой друг, требует тщательной
подготовки, нам тоже придется сделать несколько предварительных
действий. Для начала стартуем модуль geli:
Fixit# ln -s /dist/boot/kernel /boot/kernel
Fixit# ln -s /dist/lib /lib
Fixit# kldload geom_eli.ko
Теперь можно инициализировать geli на слайсе ad0s2:
Fixit# geli init -b -s 4096 /dev/ad0s2
После нажатия Enter, вам предложат ввести и подтвердить парольную
фразу.
В этой команде ключ -b указывает на то, что парольную фразу необходимо
спросить перед тем, как корневая файловая система будет смонтирована.
Размер сектора указывается ключом -s, чем больше это значение, тем
быстрее работает механизм шифрования. Смотрите man geli(8) на предмет
ключа -e который задает алгоритм шифрования, по умолчанию,
используется AES.
Теперь, можно подключить нашу зашифрованную партицию:
Fixit# geli attach /dev/ad0s2
После чего вам будет предложено ввести пароль, который вы указали при
выполнении geli init, и если вы справились со своей задачей, в
каталоге /dev появится новое устройство /dev/ad0s2.eli, которое и
является нашим зашифрованным слайсом.
С этим устройством, можно не стесняясь обращаться как с обычным
слайсом, за исключением того, что при инициализации geli, мы
искусственно увеличили размер сектора, который теперь будет равняться
4096 байт, а не 512 как обычно. Поэтому, держа в голове
соответствующую поправку, рассчитываем размеры и размечаем на
ad0s2.eli партиции:
Fixit# bsdlabel -w ad0s2.eli
Fixit# cat /tmp/bsdlabel.ad0s2.eli
# /dev/ad0s2.eli:
8 partitions:
# size offset fstype [fsize bsize bps/cpg]
a: 131072 0 4.2BSD 0 0 0 # / ~512Mb
b: 131072 131072 swap # swap ~512Mb
c: 2588646 0 unused 0 0 # total size
d: 131072 262144 4.2BSD 0 0 0 # /tmp 512Mb
e: 262144 393216 4.2BSD 0 0 0 # /var 1G
f: 1933286 655360 4.2BSD 0 0 0 # /usr все остальное
Fixit# bsdlabel -R ad0s2.elic /tmp/bsdlabel.ad0s2.eli
Наконец, создаем файловые системы. Ключом -U активируем режим
soft-updates везде, кроме корневой файловой системы:
Fixit# newfs /dev/ad0s2.elia
Fixit# newfs -U /dev/ad0s2.elid
Fixit# newfs -U /dev/ad0s2.elie
Fixit# newfs -U /dev/ad0s2.elif
На /dev/ad2s2.elib файловую систему создавать не будем, поскольку на
этой партиции будет располагаться swap.
Теперь, созданные в зашифрованной области файловые системы можно
смонтировать и инсталлировать на них дистрибутив FreeBSD. Сначала
смонтируем корень:
Fixit# mkdir /crypted && mount /dev/ad0s2.elia /crypted
Затем воссоздадим дерево каталогов, для монтируемых партиций:
Fixit# mkdir /crypted/var /crypted/tmp /crypted/usr
И смонтируем в соответствующие точки оставшиеся партиции зашифрованной
области:
Fixit# mount /dev/ad0s2.elid /crypted/tmp
Fixit# mount /dev/ad0s2.elie /crypted/var
Fixit# mount /dev/ad0s2.elif /crypted/usr
Поскольук мы загрузились в режиме fixit дистрибутив FreeBSD уже
доступен в /dist/<VERSION>/base. В нашем случае <VERSION> принимает
значение 6.2-RELESE.
Прежде чем начать процедуру установки, нам необходимо выставить
переменную окружения DESTDIR, чтобы инсталляционный скрипт знал, куда
распаковывать дистрибутив, поэтому запустим его в такой форме:
Fixit# export DESTDIR=/crypted
Fixit# cd /dist/6.2-RELEASE/base
Fixit# ./install.sh
Запустив скрипт, отвечаем, что бесспорно уверены в своих действиях и
ждем, пока операция успешно закончится, а файловые системы в
зашифрованной области диска окажутся заполненными данными из пакета,
который в sysinstall носит название BASE:
Теперь, когда FreeBSD в минимальной своей конфигурации
проинсталлирована, остается лишь создать etc/fstab:
Fixit# cat /crypted/etc/fstab
/dev/ad0s2.elia / ufs rw 1 1
/dev/ad0s2.elib none swap sw 0 0
/dev/ad0s2.elid /tmp ufs rw 2 2
/dev/ad0s2.elie /var ufs rw 2 2
/dev/ad0s2.elif /usr ufs rw 2 2
На этом упражнения с шифрованным разделом подходят к концу и можно
подготовить
Загрузочный раздел
Разобравшись с ad0s2, займемся незашифрованной областью - ad0s1,
которую мы предназначили исключительно для загрузки ядра FreeBSD и
ограничили размером ~128Mb. Поставим на этот слайс BSD-метку и запишем
boot-код:
Fixit# bsdlabel -w -B ad0s1
После этого растягиваем партицию ad0s1a на все доступное пространство
слайса:
Fixit# cat /tmp/bsdlabel.ad0s1
# /dev/ad0s1: 8 partitions:
# size offset fstype [fsize bsize bps/cpg]
a: 261702 0 unused 0 0
c: 261702 0 unused 0 0 # "raw" part, don't edit
Fixit# bsdlabel -R ad0s1c /tmp/bsdlabel.ad0s1
Теперь смело создаем единственную файловую систему на партиции ad0s1a:
Fixit# newfs /dev/ad0s1a
И сразу монтируем ее:
Fixit# mkdir /freeroot && mount /dev/ad0s1a /freeroot
Затем копируем /boot вместе с ядром, модулями и всем остальным:
Fixit# mkdir /freeroot/boot && cp -R /dist/boot/* /freeroot/boot
Кроме того, на загрузочном разделе нам понадобится fstab, перенесем
его из шифрованной области:
Fixit# mkdir /freeroot/etc && cp /crypted/etc/fstab /freeroot/etc/fstab
Поскольку выше по тексту мы стащили каталог boot и loader.conf с
установочного CD, то в loader.conf уже присутствуют ложные в нашем
случае параметры для загрузки корня с mfs, поэтому заключительным
аккордом все что там есть, недрогнувшей рукой следует вытереть:
Fixit# rm /freeroot/boot/loader.conf
Кроме того, по логике вещей, нам остается сделать только последний
штрих. А именно, указать системе на необходимость загрузки модуля ядра
geli при старте машины. Но как это выяснится чуть дальше, мы
скомпилируем ядро с необходимыми опциями, и загрузка этого модуля не
понадобится:
Fixit# echo geom_eli_load=\"YES\" > /newroot/boot/loader.conf
По-хорошему, на этом месте стоило-бы поставить большую жирную точку,
перезагрузить систему и убедится в том, что при загрузке ядра, нас
спросят парольную-фразу на ad0s2a. И тут существует большая
вероятность, что многих ожидает
Разочарование
Дело в том, что если вы не являетесь счастливым обладателем
USB-клавиатуры то, из-за одного неприятного бага, то при загрузке
ядра с поддержкой geli, вы просто не сможете ввести пасс-фразу, когда
на этапе загрузки ядра вам это будет предложено сделать. На моем
стенде, данная проблема к счастью не проявилась, и я связываю это с
тем, что на стенде используется старенькая AT, а не PS/2-клавиатура.
Впрочем, на другой системе с клавиатурой PS/2, проблема
присутствовала, так что, можно констатировать что во FreeBSD
6.2-RELEASE, баг был все еще не устранен, и поэтому, создавая
работоспособный вариант придется прибегнуть к workaround который
заключается в удалении из ядра устройства kbdmux. Правда для этого
ядро придется пересобрать, что конечно не страшно, ведь даже учебник в
одной из своих глав, настоятельно рекомендует это сделать. И раз эту
процедуру каждый честный обладатель FreeBSD будет делать в любом
случае, то этапом раньше или этапом позже, не имеет большого значения.
Поэтому распаковываем исходники ядра хорошо знакомым скриптом
install.sh:
Fixit# cd /dist/6.2-RELEASE/src
Fixit# ./install.sh sys
После этого, исходные коды ядра благополучно распакуются в каталог
/crypted/usr/src. Затем, подготавливаем ядро почти так, как это
описывается в handbook:
Fixit# cd /crypted/usr/src/sys/i386/conf
Fixit# cp GENERIC CR
Далее согласно логике и здравому смыслу редактируем конфигурационный
файл ядра CR, удаляя и добавляя поддержку устройств и изменяя
необходимые опции и параметры ядра. Почти все эти параметры
индивидуальны для конкретной ситуации, но нас интересует как минимум
поддержка geli, поэтому добавляем в ядро следующие строки:
options GEOM_ELI
device crypto
Разумеется, не забываем изменить значение IDENT на CR:
ident CR
Кроме того, из-за того-самого неприятного бага, удалим устройство
kbdmux. Поэтому находим строчку:
device kbdmux
и комментируем или же удаляем ее.
Далее, прежде чем совершить таинство сборки ядра, нам потребуется
создать несколько линков, чтобы файлы оказывались в нужных местах,
когда это потребуется:
Fixit# ln -s /dist/usr/libexec /usr/libexec
Fixit# ln -s /dist/usr/lib /usr/lib
Fixit# ln -s /dist/usr/share/mk /usr/share/mk
Fixit# ln -s /dist/usr/include /usr/include
Кроме того, подключим swap, чтобы избежать нехватки виртуальной памяти
во время компиляции:
Fixit# swapon /dev/ad0s2.elib
И наконец, соберем ядро добрым старым способом:
Fixit# config CR
Fixit# cd ../compile/CR
Fixit# make depend
Fixit# make all
Ведь это самая первая компиляция ядра CR, поэтому без всякого зазрения
совести перед make depend пропускаем команду make cleandepend, которую
утилита config нам так любезно напомнила выполнить.
Ядро готово, однако прежде чем его инсталлировать, поменяем значение
переменной DESTDIR, так чтобы она указывала на корень загрузочной
партиции:
Fixit# export DESTDIR=/freeroot
И еще файл /etc/group на нашем LIVE-CD очень сильно укорочен, поэтому
добавим в него еще одну строчку:
echo "wheel:*:0:root" >> /etc/group
Теперь можно инсталлировать ядро:
Fixit# make install
Теперь следовало-бы перезагрузиться, однако, как показала практика,
мне по крайней мере, гордиться рано. Когда во время загрузки системы в
очередной раз наступил самый ответственный момент, я с огорчением
обнаружил, что та самая пресловутая парольная фраза не вводится и
вообще складывается ощущение, что все ухищрения, связанные с попыткой
обойти баг, пропали даром, ведь все выглядит так будто система не
реагирует на ввод с клавиатуры.
Не буду рассказывать красочную историю о том, как я снова загружался с
инсталляционного CD-ROMа и монтировал файловые системы вручную.
Единственное, что я выяснил, так это то, что моя машина
реагировала-таки на ввод с клавиатуры. Просто делала она это крайне
медленно.
Итак, чтобы, наконец, ввести парольную фразу, я добавил в
/boot/loader.conf на незашифрованном разделе строчку, которая включает
эхо при вводе пасс-фразы:
echo "kern.geom.eli.visible_passphrase=1" > /freeroot/boot/loader.conf
Это, конечно, приведет к тому, что пароль будет явно виден как на
этапе загрузки, так и останется в /var/log/messages:
На этом действительно все, надеюсь только, что баг будет вскоре
устранен, или же с клавиатурой вам повезет гораздо больше чем мне. В
любом случае, желаю вам как можно быстрее насладиться работой FreeBSD
в полностью зашифрованном разделе, избежав при этом выполнение
небезопасной и унизительной процедуры с включением эха.
от кого в таком случае мы шифруемся если для старта системы ничего ненадо, ни пароля ни ключа.
и каким образом предусмотрена защита, от того от кого собственно защищаемся ? конкретно что нельзя сдлать с такой системой?
если получить доступ к винту, то, смонтировав его с правами рута, можно всё с диска поиметь. для этого не надо даже сервак разбирать, достаточно кликнуть резет, загрузиться с USB-накопителя, быстро выполнить руткит, выдернуть USB и снова нажать резет.
эти операции легко может выполнить обслуживающий персонал с вашим сервером collocation. тут как раз и требуется старт системы без паролей и ключей, требуется защитить информацию, если вражина получил физический доступ к диску. система после старта достаточно защищена.
другое дело, что здесь имеют место те же недостатки, что и у систем DRM - ключ хранится вместе с шифрограммой, и если его раскопать, то информация будет прочитана.
http://andr.ru/lib/cyber/articles/doctorow-drm.html
но опять же этого не сделать за несколько минут загрузившись с USB, надо тащить образ диска, а это гигабайты.
короче - нужная и ценная технология, и статья "для чайников" тоже вполне читабельна, ИМХО.
В данном случае, все партиции с данными находятся внутри зашифрованного слайса. Мминус, заключается в том, ядро выложено на отдельную незашифрованную партицию, и злоумышленник может попробовать его подменить. Впрочем, если бы мы грузились только с флэшки, как на это намекает хэндбук, ядро на флэшке тоже можно было бы попробовать подменить.
По хорошему, первым делом после старта кернела, с шифрованой партиции стартуется скрипт, который считает хэш кернела. И если хэш не совпадает с заданным... Ну, дальше по желанию.
to freeseacher
Гражданин с чиво вы решили что систему удастся загрузить просто так без паролей? даже если вы выставите жесткий диск в другой компутер и попытаетесь смонтировать разделы то у вас потребуют пароль :) от сюда выводы что с такой системой незная пароля или не имея ключа ничиво нельзя будет сделать:)
то есть в присутсвии человека знающего пароль такая система загрузится. а в его отстутсвие сервака не будет. очень приятно. тока как то... хотя цена информации бывает разной. иногда и админа не проблемма в 3 часа ночи поднять.
кстати в статье я так и не нашел момента что пароль все таки в водится. рассуждения о том что его будет видно нашел и о том что тормозить при вводе будет нашел. но по наивности понадеялся что его таки запихали в какой нить файл.
статья действительно не плохая. просто я сраза не понял для кого она ? для новичков ? так им лучше сразу привыкать к хорошему(читай флешке).
Разные ситуации бывают... не обязательно так "защищать" сервер. Вполне можно и свой секретный ноутбук.
Если так делать с сервером, то админ, с паролем в конверте, должен находиться в непосредственной близости от сервера, либо флешка должна быть опять-же с админом недалеко от сервера (либо флешка прямо в порту, что - глупо). Т.е. совсем не факт, что "лучше сразу привыкать к хорошему(читай флешке)". Потому, как админу в любом случае придется просыпаться и тащиться черти-куда среди ночи. Кроме того, в случае с сервером, уверен, что баг с паролем скоро пофиксят, и проблем с засвечиванием тогда не будет.
P.S. Пароль будет спрошен в момент загрузки ядра, как только прогрузится geli и сразу перед монтированием корневой ФС (там картинка специально приложена).
пробывал это где-то пол года, год назад, нужно было как раз защитить удаленный сервер от такого рода доступа. доверенный человек был, кому можно было сообщить пароль для загрузки. когда все вроде завелось все замечательно, но тогда ps/2 клава сразу отваливалась, а usb после ввода пароля. что мне и не позволило ввести в строй эту конструкцию. вот и вопрос, если использовать usb клаву она как, после ввода пароля остается в рабочем состоянии? или отваливается?
У меня банг проявлялся в отваливании клавиатуры до ввода пароля; после удаления kbdmux, в том, что буквы пароля вводятяс с сильной задержкой, как-будто буфер клавиатуры то включается то отключается. Думаю, если включить эхо, то костыль срабатывает.
ммм. польза от шифрования / весьма и весьма эфемерна. что там шифровать? /bin/ls? я знаю, что мне сейчас возразят, но, обращаю ваше внимание, господа: нет абсолютно никакой разницы, что может подменить злонамеренный усер из числа персонала, обслуживающего колокейшн-площадку, /бин/лс или /бут/кернель/тот_же_гели.ко Или ещё_что_то.ко Или (оужос) /бут/кернель/кернель. Который потом грузиться будет. И пыссворд спрашивать.
геля вообще-то немного для других целей создавалась (я не спрашивал создателя, но это же очевидно). и для этих:) целей она откровенно рулит. лично я ей обязан несколькими годами жизни на свободе.
p.s. имнсхо, единственно верное решение - именно съёмный носитель (та же флешка). и носить его с собой. и злонамеренным усерам в руки не давать. и куда попало не совать. а в случае чего - съесть.
USB key под Freebsd как правило не имеют дров (типа Alladin, Guardant которые тоже ломают).
Надо чтоб сервер сам стартовал. Подразумеваем что нет доверенного персонала на месте, скорее наоборот.
Шифровать раздел, усб флэшка - это позволяет или склонировать или влезть в систему.
Как защитить коммерческий софт на сервере продаваемом клиенту?
Присоединяюсь к вопросу.
Причем FreeBSD не обязательна, возможна любая ОС, которая позволит грузиться без пароля (на шифрованный раздел, пароль от системы клиенту никто не даст), но только на данном железе. Ну или на любом железе, но чтобы пароль вводить было не нужно (проверку клонирования можно вести через интернет - встроить в софт).
При geli init ... вылазит ошибка geli: cannot store metadata on /dev/ar0s2 input/output error, выяснил, что нормально этот процесс проходит только на первом слайсе, по этому сделал второй слайс загрузочным, хотя с геометрией второго мудрил довольно долго, думал чтото не так указал, а может и из-за райда.