Ссылка на оригинал: http://www.habrahabr.ru/blog/linux/22815.html
Автор: powerman.
С версии: 1.5.
Для начала расскажу, зачем я публикую эту статью. Дело в том, что большинство пользователей Gentoo Linux до сих пор не использует Hardened Gentoo. И вызвано это обычно тем, что они либо не знают, что это такое, либо считают что это слишком сложно, либо считают что от этого пострадает стабильность, функциональность или производительность системы. Вот эти опасения я и хочу попытаться развеять.
Hardened Gentoo - это несколько изменений в компиляторе и ядре, которые увеличивают общую защищенность системы от взлома. Например, hardened-ядро умеет блокировать массу потенциально опасных операций, а hardened-gcc позволяет защитить компилируемые им программы от взлома типовыми методами а-ля переполнение буфера. Грубо говоря, если у вас стоит "дырявая" версия программы X, и её пытается взломать хакер, то в обычной системе у него это получится, а в hardened - не получится, да ещё и в лог запись пойдёт.
Для установки Hardened на обычный Gentoo нужно будет полностью перекомпилировать всю систему - иначе защиты предоставляемые hardened-gcc не будут использоваться. Hardened - это ещё одна система, которую нужно аккуратно настраивать - переборщишь с защищённостью - ничего работать не будет вообще, недоборщишь - зачем тогда вообще Hardened ставить? Некоторые проги с hardened не уживаются (обычно это бинарные пакеты: дрова nVidia/ATI, Java плюс почему-то такой софт как mplayer/xmms) - это не смертельно, просто приходится для этих прог индивидуально отключать часть защит (для этого есть утилитки)... что огорчает. Ядро используется из пакета hardened-sources, и оно обычно на пару версий отстаёт от gentoo-sources.
Итак, Hardened Gentoo это просто объединение нескольких разных, часто независимых друг от друга, проектов:
Hardened toolchain - специальные патчи на gcc/glibc/binutils:
SSP - добавляет в бинарник защиту от переполнения буфера, т.е. прога откомпилированная с SSP сама проверяет что у неё не переполнили буфер и киляет сама себя если обнаруживает переполнение (как следствие бага в самой программе или попытки её взломать эксплойтом).
PIE - не увеличивает защищённость сам по себе, но приводит к генерации более гибкого кода, благодаря чему его можно будет защитить на уровне ядра через PaX.
PIE и SSP не зависят друг от друга, и их можно использовать вместе и по отдельности (после компиляции hardened toolchain можно будет через gcc-config переключаться между всеми вариантами - PIE+SSP, только PIE, только SSP, ничего (т.е. обычный gcc) - например, если какая-то прога не будет компилироваться.
Патчи на ядро. Их бывает много, и разных, :) но в Gentoo есть поддержка только четырёх из них - PaX, SeLinux, GrSecurity и RSBAC. Функциональность они добавляют трех типов:
Защита от переполнения буфера (а-ля SSP но со стороны ядра и другими методами, так что они друг друга дополняют): PaX. Например, PaX позволяет запретить выполнение кода в страницах памяти с данными (софтварная реализация NX-бита, которые появился только в 64-битных процах Intel) - PaX просто кильнёт процесс если он попытается нарушить эту защиту; при загрузке программы в память грузит все её функции по случайным адресам, чтобы эксплойту было очень сложно узнать на какой адрес передавать управление (это становится возможным благодаря компиляции с PIE).
Отключение потенциально опасных "фич" ядра: GrSecurity, RSBAC. Пример: запрет выполнять mount внутри chroot - чтобы хакер взломавший chroot-нутый демон и получивший root-а не смог выйти из chroot.
Ограничение прав процессов и юзеров, в т.ч. (я бы даже сказал - в основном) юзера root: SeLinux, GrSecurity/RBAC, RSBAC. Здесь идея в том, что админу (вам :)) нужно подготовить список с указанием какие проги/юзеры что имеют право делать. Пример: можно ограничить root-овый процесс apache из всех прав root-а только возможностью садиться на 80-й порт и читать файлы в /etc/apache2/. В этом случае даже если его и взломают, и хакер получит "root", то ЭТОТ "root" сможет делать только вышеперечисленные операции... хакер будет крайне разочарован. :)
Эти три "фичи" тоже не зависят одна
от другой. Но сами патчи - SeLinux, GrSecurity и
RSBAC обычно между собой не совместимы и
нужно использовать только один из них.
Впрочем, в Gentoo сумели объединить SeLinux
и GrSecurity вместе. Часть GrSecurity, которая
занимается третьей фичей (ограничением
прав) называется RBAC, и её использовать
вместе с SeLinux нельзя - или-или.
Итого,
варианты есть, например, следующие:
PaX + GrSecurity
PaX + GrSecurity (без RBAC) + SeLinux
PaX + SeLinux
PaX + RSBAC
... etc ...
Я выбрал первый (PaX+GrSecurity) т.к. во-первых настройка SeLinux обещает быть кошмаром, в отличие от GrSecurity/RBAC; во-вторых на мой взгляд поддержка RSBAC в Gentoo ещё сыровата; и в-третьих ну понравился мне GrSecurity, понравился. :))
Процесс установки Hardened Gentoo (точнее, апгрейда текущей Gentoo системы в Hardened) выглядит примерно так:
переключаемся на hardened toolchain и пересобираем им всю систему, чтобы все бинарники использовали PIE и SSP (после этого система становится защищена SSP)
устанавливаем hardened-sources (они содержат патчи PaX + GrSecurity + SeLinux + дополнительные от Gentoo) и компилируем их с поддержкой PaX, GrSecurity и GrSecurity/RBAC
перегружаемся с новым ядром (после этого система становится защищена ещё и PaX+PIE и GrSecurity)
некоторое время настраиваем и отлаживаем ограничения доступа (после чего система становится защищена ещё и GrSecurity/RBAC)
Ожидаемые проблемы:
не всё может скомпилироваться с PIE+SSP - возможно отдельные пакеты нужно будет патчить или компилировать без одной или обоих из них (мне пока потребовалось через gcc-config переключаться на vanilla gcc только для компиляции X-ов чтобы они работали с ATI-дровами)
не всё может нормально работать, т.к. некоторые программы (обычно упоминают X-ы и java) используют выполнение динамически сгенерированного кода для вполне легальных целей, а теперь при попытке это делать они будут киляться либо SSP либо PIE+PaX - для этих программ нужно будет индивидуально отключать часть защит PaX (для этого есть специальные утилиты, например paxctl) и/или компилировать их без SSP
не всё может работать из-за ограничений "фич" ядра GrSecurity - в этом случае нужно будет часть защит GrSecurity отключать (глобально, в make menuconfig)
настроить ограничения прав доступа может оказаться не просто, и в любой момент когда какая-нить прога сделает что-то, что мы при настройке её прав не учли - она будет прибита ядром... и придётся эти правила в срочном порядке фиксить
Ну что, поехали... :)
Слишком сильная оптимизация (-O3) вместе с hardened toolchain может приводить к разным глюкам и сбоям компиляции, поэтому нужно в /etc/make.conf заменить -O3 на -O2, и убрать все прочие -f* оптимизаторские флаги.
Переходим на hardened-профайл. (Теоретически вместо этого можно было просто добавить в USE-флаги: "hardened pie ssp".)
ln -snf ../usr/portage/profiles/hardened/x86/2.6/ /etc/make.profile
После переключения профайла на hardened/x86/2.6/ выключилось несколько нужных мне USE-флагов, которые в обычных профайлах включены автоматически - я их дописал в make.conf (у вас флаги могут быть другие, просто не забудьте этот момент проследить):
avi encode gtk2 jpeg mpeg oss quicktime spell truetype xv bitmap-fonts truetype-fonts type1-fonts
Компиляция hardened-toolchain и пересборка им всех остальных пакетов:
emerge binutils gcc glibc emerge -e world
dispatch-conf
Далее, нужно поставить ещё несколько пакетов:
emerge paxtest paxctl gradm
paxtest можно было поставить и раньше, до перехода на hardened toolchain. Эта утилитка пытается делать разные опасные операции (типа переполнения стека с выполнением кода), которые обычно выполняют эксплойты. Если система защищена, то все её попытки будут пресечены, о чём она и сообщит. В общем, можно её погонять до установки hardened toolchain, после а так-же после перезагрузки с ядром где включён PaX, по приколу. :)
paxtest как свою зависимость так-же установит прогу chpax - это старый способ управлять PaX, вместо которого лучше использовать paxctl. Но некоторые проги, распространяемые без исходников, скомпилированы так, что paxctl с ними работать не может, и приходится юзать chpax.
Ну а gradm нужен для настройки RBAC в GrSecurity - тех самых ограничений прав для процессов и юзеров.
Что касается настроек ядра. Я для начала настроил всё так, как описано в доке Gentoo и GrSecurity - при этом не все защиты включены, но большинство софта при таких настройках будет работать. В процессе разбора с настройками возникло несколько теоретических предположений:
Если загрузить hardened ядро ДО перекомпилирования системы, то могут возникнуть проблемы если включена эта опция:
PaX -> Non-executable pages -> Disallow ELF text relocations
На сервере, где нет X-ов, можно дополнительно включить: (не забыть перед этим проверить, что от этого не перестало работать что-то кроме X-ов, в частности hwclock):
Grsecurity -> Address Space Protection -> Disable privileged I/O
Кроме того, ещё есть предположение, что некоторые ограничения chroot могут помешать операциям типа инсталляции Gentoo (которая идёт внутри chroot) или попытке починки системы (если, например, для этого загрузиться с CD с таким hardened ядром):
Grsecurity -> Filesystem Protections -> Deny mounts
Grsecurity -> Filesystem Protections -> Deny double-chroots
Grsecurity -> Filesystem Protections -> Deny (f)chmod +s
Grsecurity -> Filesystem Protections -> Deny mknod
Настройка Hardened состоит из двух частей: настройка ядра, и настройка ролей (RBAC или SELinux). Пример настройки ядра 2.6.20 я сейчас покажу. А RBAC/SELinux я пока не настраивал.
Думаю, будет нагляднее всего привести настройки так, как они выглядят в make menuconfig - это за одно позволит оценить "на глаз" возможности PaX и GrSecurity тем, кто с ними до сих пор не сталкивался.
Между разными версиями ядра они немного меняются, но не значительно.
PaX --->
. [*] Enable various PaX
features....... PaX Control --->
......... [ ] Support soft
mode
......... [*] Use legacy ELF header marking
......... [*]
Use ELF program header marking
............. MAC system
integration (none) --->
....... Non-executable pages
--->
......... [*] Enforce non-executable pages
.........
[*] . Segmentation based non-executable pages
......... [ ]
Emulate trampolines
......... [*] Restrict mprotect()
.........
[ ] . Disallow ELF text relocations
......... [ ] Enforce
non-executable kernel pages
....... Address Space Layout
Randomization --->
......... [*] Address Space Layout
Randomization
......... [*] . Randomize kernel stack
base
......... [*] . Randomize user stack base
......... [*] .
Randomize mmap() base
..... Miscellaneous hardening features
--->
....... [ ] Sanitize all freed memory
....... [*]
Prevent invalid userland pointer dereference
Grsecurity --->
.
Security Level (Custom) --->
. Address Space Protection
--->
... [*] Deny writing to /dev/kmem, /dev/mem, and
/dev/port
... [ ] Disable privileged I/O
... [*] Remove
addresses from /proc//[smaps|maps|stat]
... [*] Deter exploit
bruteforcing
... [*] Runtime module disabling
... [*] Hide
kernel symbols
. Role Based Access Control Options --->
...
[*] Hide kernel processes
... (3) Maximum tries before password
lockout
... (30) Time to wait after max password tries, in
seconds
. Filesystem Protections --->
... [*] Proc
restrictions
... [*] . Restrict /proc to user only
... [*]
Additional restrictions
... [*] Linking restrictions
... [*]
FIFO restrictions
... [*] Chroot jail restrictions
... [*] .
Deny mounts
... [*] . Deny double-chroots
... [*] . Deny
pivot_root in chroot
... [*] . Enforce chdir("/") on
all chroots
... [*] . Deny (f)chmod +s
... [*] . Deny fchdir
out of chroot
... [*] . Deny mknod
... [*] . Deny shmat() out
of chroot
... [*] . Deny access to abstract AF_UNIX sockets out
of chroot
... [*] . Protect outside processes
... [*] .
Restrict priority changes
... [*] . Deny sysctl writes
... [*]
. Capability restrictions
. Kernel Auditing --->
... [ ]
Single group for auditing
... [ ] Exec logging
... [*]
Resource logging
... [ ] Log execs within chroot
... [ ] Chdir
logging
... [*] (Un)Mount logging
... [ ] IPC logging
...
[*] Signal logging
... [*] Fork failure logging
... [ ] Time
change logging
... [*] /proc//ipaddr support
... [ ] ELF text
relocations logging (READ HELP)
. Executable Protections --->
...
[*] Enforce RLIMIT_NPROC on execs
... [*] Destroy unused shared
memory
... [*] Dmesg(8) restriction
... [ ] Trusted Path
Execution (TPE)
. Network Protections --->
... [*] Larger
entropy pools
... [ ] Socket restrictions
. Sysctl support
--->
... [*] Sysctl support
... [*] . Turn on features by
default
. Logging Options --->
... (10) Seconds in between
log messages (minimum)
... (4) Number of messages in a burst
(maximum)
[ ] Enable access key retention support
[ ] Enable
different security models
Абсолютное большинство этих фич работает прозрачно для пользователя. Но есть пара, которые вы можете заметить: во-первых обычные пользователи перестанут видеть процессы других пользователей, а во-вторых они потеряют доступ к некоторым файлам в /proc/, из-за чего вывод команд ifconfig, route, etc. запущенных обычными пользователями станет значительно скромнее.
Надо отметить, что большая часть этих фич может управляться через sysctl. Что, как правило, плохо. А что хорошего в том, что хакер ломает систему наполовину, получает возможность отключить эти защиты через sysctl, после чего доламывает её уже окончательно? К счастью, есть возможность заблокировать изменение настроек GrSecurity через sysctl. Для этого нужно добавить в /etc/sysctl.conf:
kernel.grsecurity.disable_modules = 1
kernel.grsecurity.grsec_lock = 1
Где первая команда запрещает подгрузку модулей ядра (лучше всего на серверах поддержку модулей даже не включать в ядре, но если это не возможно, то теперь есть выход: подгрузить нужные модули при загрузке системы, а потом с помощью kernel.grsecurity.disable_modules запретить подгрузку модулей - чтобы никто случайно руткит не подгрузил :)), а вторая запрещает изменение любых настроек GrSecurity.
Недостаток этого в том, что если вам нужно будет таки подгрузить модуль или отключить часть фич GrSecurity (например, защиту chroot для сборки нового Gentoo), то придётся редактировать /etc/sysctl.conf и перегружаться.
Собственно, настройка на этом окончена.
В качестве резюме, приведу полный набор команд, которые отконвертируют ваш Gentoo в Hardened:
emerge hardened-sources
6
# Теперь настройте
это ядро (пока не включая фичи
#
hardened), скомпилируйте и перегрузитесь
в него.
ln -snf
../usr/portage/profiles/hardened/x86/2.6/ /etc/make.profile
#
Уберите все флаги оптимизации из CFLAGS
в /etc/make.conf
# и установите -O2.
# Пример:
CFLAGS="-march=pentium-m -O2 -pipe"
# Очистите
ваш $PKGDIR (обычно /usr/portage/packages/) для
#
ускорения времени пересборки системы
используя
# опции -b и -k команды
emerge.
emerge -C linux-headers
emerge linux-headers
glibc binutils gcc-config gcc
# Проделайте все
дополнительные операции, которые
могут
# требоваться при обновлении
gcc (см. GCC Upgrade Guide).
emerge -b glibc binutils
gcc portage
emerge -bke system
emerge -ke world
glsa-check
-l | grep '\[N\]'
# Ручками обновите
пакеты, которые мог выдать glsa-check.
emerge
-a --depclean
emerge -uDNa world
emerge paxtest
paxctl gradm
revdep-rebuild
dispatch-conf
#
Теперь включите в ядре все фичи
Hardened,
# соберите его и перегрузитесь.
Я начал с того, что выразил желание развеять распространённые опасения в том, что Hardened - это слишком сложно, либо от этого cтрадает стабильность, функциональность или производительность системы. Я уже продемонстрировал, что такое Hardened Gentoo в общих чертах, а теперь пройдёмся детальнее по этим опасениям.
Я пока не занимался настройкой
системы ролей (RBAC/SELinux) как раз из-за
сложности. Возможно, конечно, только
кажущейся, и на самом деле там тоже всё
просто, не знаю... :) Я, всё-таки, в основном
программист, и на администрирование
времени вечно не хватает. В общем, если
в Hardened и есть что-то сложное и требующее
кучу времени и внимания - это настройка
ролей.
А вот всё, что я описал до этого, настраивается очень просто, быстро, один раз, и даёт достаточно сильный эффект в виде усиления безопасности системы!
Я уже много лет использую Hardened в описанном виде и дома на workstation, и на всех серверах. Никаких проблем со стабильностью их работы из-за Hardened за это время не возникало, и я не видел жалоб в maillist на эту тему.
Что касается стабильности сборки Gentoo, ведь пакеты постоянно обновляются и компилируются. Пару лет назад была необходимость использовать некоторые workaround-ы - например, чтобы XWindow работали с дровами ATI приходилось их собирать не-hardened gcc (для автоматического переключения gcc в процессе компиляции пакетов был написан простейший скрипт). Ну и ещё по мелочи проблем возникало, но ни одной критичной. Сейчас проблем такого рода нет в принципе. Т.е. вы систему на Hardened перевели, и забыли - можете продолжать всё делать так, как будто ничего не произошло. Только хакать ваш сервер стало сложнее гораздо. :)
Да, для того, чтобы работали некоторые пакеты, до сих пор необходимо использовать утилиты chpax/paxctl, для отключения части hardened-защит для конкретных приложений. Но в Gentoo эта операция давно автоматизирована: для этих приложений chpax/paxctl выполняется на этапе установки пакета. Так что вам об этом беспокоиться уже не нужно. А за исключением этого нюанса (что для некоторых приложений часть защит выключена), все приложения работают в Hardened Gentoo без проблем (по крайней мере с теми настройками ядра, которые я привёл в предыдущей части).
Честно скажу - сам я не мерял.
Да и что и как мерять - не совсем понятно.
Насколько я понял из инета - можно ожидать
до 3-4% потери производительности в худшем
случае, а обычно это будет меньше
процента. Но, опять-же, смотря какие
"фичи" включать. Если врубить
SeLinux или RBAC - тогда можно эти 3-4% потерять,
но до их настройки я пока не добрался.
:( Визуально - после перехода на Hardened
разницы никакой, ни на домашней машине,
ни на серверах. Конечно, сколько-то
производительности, вероятно, было
потеряно из-за перехода на -O2. Ещё я
сталкивался с тем, что при выборе
"неправильной" опции при настройке
ядра из этих двух:
[ ] Paging based non-executable pages
[*]
Segmentation based non-executable pages
возникали
заметные тормоза. Сейчас я в ядре вообще
не вижу первого варианта (который любил
потормозить на некоторых типах
процессоров).
В общем, у вас есть реальная возможность значительно увеличить безопасность своих машин, потратив один раз пару часов вашего времени на переход на Hardened и сутки машинного времени (пока будет полностью пересобираться система).
"Думайте сами, решайте сами - иметь, или не иметь." :)