Hardened Gentoo

Ссылка на оригинал: 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 это просто объединение нескольких разных, часто независимых друг от друга, проектов:

  1. Hardened toolchain - специальные патчи на gcc/glibc/binutils:

    PIE и SSP не зависят друг от друга, и их можно использовать вместе и по отдельности (после компиляции hardened toolchain можно будет через gcc-config переключаться между всеми вариантами - PIE+SSP, только PIE, только SSP, ничего (т.е. обычный gcc) - например, если какая-то прога не будет компилироваться.

  2. Патчи на ядро. Их бывает много, и разных, :) но в Gentoo есть поддержка только четырёх из них - PaX, SeLinux, GrSecurity и RSBAC. Функциональность они добавляют трех типов:

    Эти три "фичи" тоже не зависят одна от другой. Но сами патчи - SeLinux, GrSecurity и RSBAC обычно между собой не совместимы и нужно использовать только один из них. Впрочем, в Gentoo сумели объединить SeLinux и GrSecurity вместе. Часть GrSecurity, которая занимается третьей фичей (ограничением прав) называется RBAC, и её использовать вместе с SeLinux нельзя - или-или.
    Итого, варианты есть, например, следующие:

    Я выбрал первый (PaX+GrSecurity) т.к. во-первых настройка SeLinux обещает быть кошмаром, в отличие от GrSecurity/RBAC; во-вторых на мой взгляд поддержка RSBAC в Gentoo ещё сыровата; и в-третьих ну понравился мне GrSecurity, понравился. :))





Установка

Процесс установки Hardened Gentoo (точнее, апгрейда текущей Gentoo системы в Hardened) выглядит примерно так:

  1. переключаемся на hardened toolchain и пересобираем им всю систему, чтобы все бинарники использовали PIE и SSP (после этого система становится защищена SSP)

  2. устанавливаем hardened-sources (они содержат патчи PaX + GrSecurity + SeLinux + дополнительные от Gentoo) и компилируем их с поддержкой PaX, GrSecurity и GrSecurity/RBAC

  3. перегружаемся с новым ядром (после этого система становится защищена ещё и PaX+PIE и GrSecurity)

  4. некоторое время настраиваем и отлаживаем ограничения доступа (после чего система становится защищена ещё и GrSecurity/RBAC)



Ожидаемые проблемы:


Ну что, поехали... :)

Слишком сильная оптимизация (-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 состоит из двух частей: настройка ядра, и настройка ролей (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 и сутки машинного времени (пока будет полностью пересобираться система).

"Думайте сами, решайте сами - иметь, или не иметь." :)