Документация по ОС FreeBSD Пятница, 26.04.2024, 00:20
Приветствую Вас Гость | RSS
Меню сайта

Категории каталога
Мои статьи [0]
Установка и настройка [281]
X Window [25]
Man pages [30]
Ports & Packages [26]
cvs [18]
Multimedia [20]
Нововсти в мире Unix [0]
RFC [4]
RFC (Request for Comments, Запрос на комментарии) - серия документов, публикуемая сообществом исследователей и разработчиков, руководствующихся практическими интересами, в которой описывается набор протоколов и обобщается опыт функционирования Интернет.
Безопасность [52]
Работа с железом [58]
Книги по FreeBSD [17]
Сеть [505]
Программирование [40]
FireWall [58]
Темы экзамена BSDA [14]
Официальные темы экзамена BSDA, включая подробноые описания и советы по обучению.

Главная » Статьи » Безопасность

Безопасность сервера [2004]

Всем давно понятно, что фраза "*nix - безопасная ОС" по своей сути некорректна. *nix, если под этим понимать дизайн, реализацию ядра ОС и базовую ее начинку (утилиты), лишь предоставляет отличные предпосылки для построения на своей базе защищенной серверной системы. Но на одном ядре и прикладных утилитах сервер не построишь, нужны сервисы, и безопасность их напрямую не связана с безопасностью операционки. Помнишь известные слова: "Безопасность - это не продукт, а процесс"? Так вот, безопасность как процесс - не свойство системы, а свойство взаимодействия системы и админа, который ее настраивает.

Мы рассмотрим типичный сценарий установки, настройки и сопровождения сервера с точки зрения security-параноиков. Мне не хотелось бы давать разрозненные советы из серии "хозяйке на заметку", поэтому мы пройдем по шагам все этапы от установки ОС до запуска сервисов, обращая внимание на важные моменты. Я не буду предлагать здесь детальное руководство по настройке каждого сервиса, а лишь дам общие советы, которые нужно иметь в виду. По этой же причине я не завязываюсь на конкретную ОС - кто-то любит Linux, кто-то FreeBSD, а кто-то по долгу службы обхаживает Solaris. Замечания по определенной ОС, если таковые встретятся, будут даваться по ходу.

Спасительные флаги

Веселье начинается уже при разметке винчестера на партиции при установке системы. В Linux-мире как-то не принято обращать на это серьезное внимание, и один большой корневой раздел (/) на всю систему там - норма. Иногда, правда, выделяют /home. Но этого все равно мало. Не зря опыт поколений рекомендует иметь как минимум следующие разделы:

/ - корневой;
/home - если сервер будет иметь много пользовательских учетных записей (хостинг, хранение почты, FTP-архив, да практически всегда);
/tmp - обязательно выделяй /tmp в отдельный раздел диска;
/var - для хранения логов, спула почты, бэкапов и прочего мусора;
/usr - для исполняемых файлов, библиотек, исходных текстов системы.

Пользователи BSD могут прочитать более подробное описание исторически сложившейся иерархии в man 7 hier, для остальных систем существует схожий (хотя и спорный) документ Filesystem Hierarchy Standart (FHS, www.pathname.com/fhs). Но какое это имеет отношение к безопасности? Дело в удобстве оперирования флагами монтирования. Любая файловая система позволяет указать набор флагов, с которыми будет примонтирована соответствующая партиция, и некоторые из них имеют непосредственное отношение к безопасности системы. Покажу это на примере FFS (Fast File System), практически все остальные FS имеют схожие по названию флаги (см. "man mount" в своей системе).

noexec - запрещает исполнять файлы;
nosuid - запрещает повышение привилегий для исполняемых suid/sgid файлов. Иными словами, теряется suid-бит и программа выполняется как обычная;
nosymfollow - запрещает использование символических ("мягких") ссылок;
nodev - запрещает использование файлов устройств.
 
В общем случае операционке, безусловно, нужно иметь возможность исполнять файлы. Также в системе обязательно присутствует некоторое количество суидных программ, да и ссылки тоже, как правило, имеются. Но есть ли смысл в суидных файлах, например, в каталоге /tmp? Часто хакеры бросают суидный /bin/sh куда-нибудь в складки /tmp или здесь же компилируют эксплоит, пока еще не имея прав рута, но надеясь их получить. То же касается и пользователей в их домашних каталогах. Вряд ли среднестатистический хостер, дающий своим клиентам доступ по ssh для правки\заливки контента, нуждается в том, чтобы эти клиенты что-то у себя запускали или, тем более, компилировали и затем запускали. Поэтому очень часто на /tmp и /home оправданы флаги nosuid, а нередко и noexec. В некоторых случаях они могут помешать, например, noexec на /tmp не позволит пересобрать мир (make world) на FreeBSD, но это не более чем кратковременное исключение. Нет нужды пояснять, что в случае одного большого раздела (/) такая манипуляция флагами была бы исключена. Сам же корневой раздел, включающий каталоги с конфигурационными файлами системы, базовыми бинарниками, библиотеками и ядром, вполне реально монтировать в режиме read-only.

Не лишен смысла также трюк против злонамеренных операций с ядром (таких, как его перекомпиляция и замена :)), заключающийся вот в чем. Каталог /boot, в котором находятся ядро, в случае BSD и модули с конфигурационным файлом loader.conf, а в случае Linux - файл предварительной загрузки модулей initrd, оформляется в виде отдельного раздела на каком-нибудь съемном носителе (USB-флэшка), с него производится загрузка, а затем, после запуска системы и загрузки всех модулей, раздел размонтируется и носитель вынимается (кладется в сейф :)). Подменить ядро, initrd или подсунуть модуль становится на порядок проблематичней.

Помимо флагов на FS существуют дополнительные атрибуты безопасности на файлы. В BSD атрибуты выставляются и просматриваются командой chflags(1), в Linux - chattr(1)/lsattr(1). Так, из полезных флагов chfags(1) можно выделить:

sappnd - позволяет открывать файл только в режиме "append only";
schg - выставляет флаг "immutable", такой файл нельзя переместить, удалить или переименовать;
sunlnk - запрещает удаление файлов.

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

Выживает сильнейший

При старте системы запускаются всевозможные сервисы. Какие-то системы (OpenBSD) относятся к этому моменту очень ответственно, запрещая по умолчанию практически все, какие-то (большинство дистрибутивов Linux) действуют в лучших традициях Windows-style, запуская все, что может когда-либо понадобиться. "ps wax" ("ps -ef" в Solaris) покажет тебе, кто понапрасну работает, а "sockstat -l" (во FreeBSD) и "netstat -na | grep LISTEN" - кто понапрасну биндит порты, ожидая remote эксплоита по свою душу. Рекомендую также и полезную утилиту lsof (list of open files), которая, сродни bsd'шному sockstat, показывает, какие сокеты или устройства открыты определенными процессами. Ничего нового здесь придумать нельзя - отключаем все, что не нужно, правкой rc.conf в BSD, ковырянием в /etc/init.d/ или /etc/rc.d/ - в Linux и Solaris и т.д. Некоторые демоны по умолчанию слушают сетевой сокет, тогда как вполне могут обойтись без него, например, syslogd(8), который, если нет необходимости принимать логи по сети, рекомендуется запускать с флагом -ss (secure mode).

Те же сервисы, что нам нужны, тоже должны иметь кредит доверия. Тут тебе не Windows, и выбор сравнимых по функциональности демонов имеется. Если с системы не планируется сдувать пылинки, пребывая в боевой готовности пропатчить, скажем, почтовый сервер сразу, как только выйдет secuity advisory, то выбор сервисов с хорошей репутацией и отсутствием истории уязвимостей - первейшее дело. Хотя хороший админ все равно должен уметь быстро реагировать (баги находят везде), ничто не мешает ему снизить шанс форсмажора до минимума (где-то все же их находят существенно чаще). Не буду призывать использовать что-либо конкретное, но если ты не законченный фанат какой-либо одной программы либо тебе не нужна особая функциональность определенного демона, то знай, что гарантированно не доставят тебе головой боли из smtp-серверов qmail и postfix, из ftp-серверов - vsftpd, pureftpd и publicfile, из DNS-серверов - djbdns, из pop3-серверов - все тот же qmail и popa3d. Впрочем, история показывает, что опытные админы, как правило, консервативные фанаты определенного круга программ и предпочтут патчить свое детище раз в неделю, чем перейти на альтернативный продукт ;).

Отдельно хочется сказать про "суперсерверы" inetd и xinetd. Они существуют для поддержки демонов, которые не умеют запускаться в так называемом standalone-режиме, то есть принимать сетевые соединения, самостоятельно ограничивать количество одновременных сессий, использовать возможности tcp-wrappers и т.п. В таком случае inetd/xinetd выступают в качестве посредника между клиентом и сервером, реализуя вышеописанные возможности. При всем удобстве "суперсерверов" их идея не кажется мне замечательной. Во-первых, если "положить" inetd DoS-атакой или эксплоитом, то упадут и все обслуживаемые им демоны. Во-вторых, большинство используемых для работе в агрессивном интернете сервисов умеют самостоятельно отрабатывать почти все, что предлагает inetd. "Суперсервер" - это сложная система, так что лучше не использовать ее там, где без нее можно обойтись. Гуру безопасного программирования Дэн Бернстейн предлагает свой вариант под названием tcpserver (ucsp-tcp), частично выполняющий функции inetd. Если есть необходимость запустить программу, требующую inetd, можно воспользоваться tcpserver, который частично избавляет от неудобств inetd.

Каким бы безопасным ни был демон, существуют механизмы, позволяющие администраторам еще крепче спать по ночам. Процесс, взаимодействующий с пользователем, должен исполняться от имени непривилегированного пользователя. И правда, сегодня найти apache или named, запущенный от рута, довольно сложно ;-). Помимо этого каждый демон можно изолировать в его собственной среде. Образно, все необходимые для работы демона файлы и библиотеки копируются в измененный корневой каталог, и затем в получившуюся иерархию выполняется системный вызов chroot(2). С точки зрения демона, он работает в нормальной среде, ведь все необходимые для него файлы присутствуют, зато взломщик, получив контроль над дырявым сервисом, будет не в состоянии даже получить shell, так как /bin/sh может просто отсутствовать в chroot-директории. Во FreeBSD эту идею развили, и присутствующий там системный вызов и утилита jail(8) совместно с удобным управлением через sysctl-переменные позволяют удобно засадить демона "за решетку", из благих побуждений.

Еще одно веяние времен эпохи параноиков - отслеживание системных вызовов, совершаемых программой, и дальнейшее их ограничение. Любое действие программы (такое, как чтение файла или открытие сетевого сокета) - это системный вызов ядру ОС. Значит, можно ограничить набор легитимных вызовов для каждой программы. Действительно, зачем DNS-серверу биндить какой-либо локальный порт, кроме 53-го, для приема входящих запросов? Механизм systrace (www.citi.umich.edu/u/provos/systrace), присутствующий в стандартной поставке OpenBSD и NetBSD, а также портированный на остальные платформы, занимается тем, что отслеживает системные вызовы программ и сопоставляет их с указанной политикой. Любые аномалии протоколируются, и соответствующий системный вызов запрещается. В идеале это означает, что shell-коду можно помахать платочком.

Наконец, не только бесполезные сервисы следует убирать из системы. Зачем, например, на настроенной и работающей машине компилятор или дизассемблер? Чтобы взломщику было легче скомпилить и применить сплоит? Многие дистрибутивы Linux практикуют исключительно binary upgrade, так что компилятор там может вообще не понадобиться.

Ядро. Без паники

Обезопасив свои сервисы, обратим взор к ядру. Так как обыкновенная подмена системных утилит в два счета детектится системой контроля целостности, то без вариаций на тему модульного руткита не обходится ни один серьезный хакер. Не так уж это и страшно. Самое простое - собрать ядро без поддержки модулей. Для FreeBSD существует патч, позволяющий собрать ядро с опцией NO_KLD (people.freebsd.org/~cjc - не самый, правда, свежий). В Linux достаточно просто не указывать соответствующую опцию CONFIG_MODULES=n. К несчастью, многие производители железа предоставляют драйвера для своей продукции в виде подгружаемых модулей, исключительно в бинарном виде. В BSD эту, а заодно и многие другие проблемы, снимает kernel securelevel(8). В многопользовательском режиме он может принимать значения -1, 1, 2 и 3.

-1 - не накладывает никаких ограничений ("небезопасный режим"). По умолчанию система запускается с таким значением;
1 - "безопасный режим", запрещает снятие флагов immutable и append-only даже root'у, запрещает писать в память ядра или совершать привилегированные операции ввода/вывода на уровне ядра (/dev/mem, /dev/kmem, /dev/io), запрещает загрузку/выгрузку модулей ядра;
2 - "очень безопасный режим", наследует все возможности предыдущего режима, а также не позволяет ничего писать на примонтированные файловые системы;
3 (присутствует во FreeBSD) - "сетевой безопасный режим", наследует возможности безопасного, а также не позволяет менять конфигурацию правил пакетного фильтра (удалять или добавлять правила).

Значение securelevel выставляется утилитой sysctl (переменная kern.securelevel) после запуска системы и загрузки всех модулей и демонов и во время работы системы может быть только увеличено. Практически всегда сервер без графической системы X-Window или прочей экзотики обязан без проблем работать со значением kern.securelvel=1; если же он по совместительству является фаерволом с постоянным набором правил фильтрации, то со значением kern.securelvel=3. Очень многие пренебрегают это полезной возможностью, а ведь в таком случае, чтобы загрузить вредоносный модуль или добавить свое правило в цепочку пакетного фильтра, взломщику придется перезагрузить машину, что не может остаться незамеченным.

Помнится, один известный в определенных кругах хакер временно залочил мне аккаунт на его FreeBSD-боксе, мотивировав это тем, что "там сейчас крутится много важных процессов", видимо, опасаясь команды "ps -a" с моей стороны. Однако если бы он знал о существовании sysctl-переменной kern.ps_showallprocs (security.bsd.see_other_uids для FreeBSD 5), то, возможно, не стал бы принимать столь крайние меры. Выставление этой переменной в 0 позволит пользователям любоваться списком исключительно своих процессов, скрывая чужие. Это незаменимо на хостингах, где много пользователей имеют shell-аккаунт.

Часто хакеры запускают на взломанной машине снифер, особенно если эта машина - пограничный маршрутизатор, через который проходит весь трафик. В Linux для этого необходима библиотека libpcap, а вот в BSD пакеты ловятся через псевдоустройство bpf(4) (berkeley packet filter), вкомпилированное в ядро или загруженное как модуль. Часто отсутствие bpf(4) в системе (в любом виде) может быть оправдано с точки зрения безопасности. Без него снифинг пакетов в BSD невозможен. Но, правда, невозможна и, например, корректная работа пакетного фильтра OpenBSD PF, так что всегда есть исключения.

Еще одна вещь, которая может помочь при расследовании инцидентов, да и вообще полезна в качестве контроля за системой, это аккаунтинг процессов (во FreeBSD включается установкой переменной accounting_enable="YES" в /etc/rc.conf, в Linux - CONFIG_BSD_PROCESS_ACCT=y в конфиге ядра). Будучи включенным, он протоколирует в /var/account/acct (в Linux - /var/log/pacct) запуск всех процессов, позволяя посмотреть, когда, что и от имени какой учетной записи было запущено (lastcomm(1)), а также позволяет выдать статистику по выполненным процессам (sa(8)).

Аудит системы

Хорошая система должна требовать минимум внимания. В идеале, около трех секунд в день - ровно столько нужно времени, чтобы пробежать глазами ежедневный отчет и убедиться в отсутствии аномалий. В отчет должны включаться как минимум мониторинг создания новых учетных записей (если взломщик имел неосторожность добавить пользователя или сменить пароль существующему, ты это заметишь), появление новых суидных программ, количество заблокированных фаерволом пакетов и количество попыток неудачного входа в систему. Все эти меры призваны обнаружить атаки на ранней их стадии. В BSD подобный отчет генерируется по умолчанию, утилитой periodic(8). По сути, она выполняет последовательность скриптов, запускаясь по расписанию из crontab(1), результат работы сваливается администратору в почту. В /etc/periodic.conf можно определить указанные в /etc/defaults/periodic.conf опции составления отчета - помимо репорта periodic(8) может выполнять скрипты очистки /tmp, бэкапа важных файлов и т.п.

Помимо самой системы уязвимости находят и в софте, инсталлируемом из пакетов/портов. Полезно, конечно, читать адвайзори от вендоров, но наиболее удобный способ - положиться на автоматизированный аудит безопасности. Так, во FreeBSD имеется утилита portaudit (/usr/ports/security/portaudit). Она скачивает базу уязвимостей и анализирует установленные пакеты на предмет присутствия их в текущем списке проблемных программ.

Пропиши скачивание свежей базы в crontab(5) (корректнее: установи daily_status_security_portaudit_enable="YES" в /etc/periodic.conf) и любуйся ежедневными отчетами.

Нетрадиционные методы

Если ты заметил, BSD больше подходит для организации защищенной системы в рамках классической модели безопасности UNIX. Тому способствуют как защитные механизмы системы (kernel securelevel, jail, systrace), так и средства аудита (accounting, periodic), доступные, что называется, "из коробки". Но можно пойти дальше и радикально поменять саму модель защиты, вместо традиционной дискреционной модели доступа применив одну из мандатных моделей. Это уже серьезно и требует хотя бы поверхностного знакомства с моделями безопасности. И здесь выигрывает Linux, для которого существуют такие проекты, как RSBAC (www.rsbac.org) и SELinux (www.nsa.gov/selinux). Они делают из Linux мощную систему с поддержкой Role Based Access Control (RBAC), Domain Type Enforcement (DTE) и кучей другого. Во FreeBSD 5, правда, тоже появилась возможность контроля доступа по расширенным атрибутам файлов (Mandatory Access Control), но это капля в море. Мандатные модели доступа - отдельная, серьезная тема, сложная в реализации применительно к конкретному production серверу и требующая внимательной эксплуатации.

Напоследок процитирую известную фразу: "If you fuck up OpenBSD it gets unsecure. Linux must be fucked up to be secure. Windows must be secure erased to be secure". Доля правды в ней есть, но помни, что главное для безопасности системы - не операционка, а тот, кто ей управляет.

Бойся жестких ссылок

Такая с виду безобидная вещь, как хардлинк, может стать причиной компрометации системы. Представь, что в системе есть некая суидная программа. Права на нее, как на любой исполняемый файл, 755. Затем в программе нашли дыру, позволяющую с ее помощью получить локального рута. Ты вовремя обновился, но через пару дней тебя все равно хакнули. Как?

Посмотри полный вывод команды ls:

ЛИСТИНГ

[(3:47)(85.32%)(p3):~ ] ls -al rfc2818.txt

-rw-r--r-- 1 toxa toxa 15170 15 июл 19:54 rfc2818.txt

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

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

Почему же просто не скопировать программу себе в каталог? А потому, что потеряются первоначальные права на файл и владельцем вместо рута станет хакер, после чего наличие на ней suid-бита станет бессмысленным.

Следи за паролями

Если заглянуть в /etc/shadow (/etc/master.passwd в BSD), то можно увидеть массу системных учетных записей, но все они залочены - в поле пароля вместо хэша у них символ "*" или "!!", а вместо шелла - что-то вроде /sbin/nologin или /bin/false. Если у системного пользователя (не реального юзера) ты увидишь прописанный реальный шелл и хэш пароля, бей тревогу.

Безопасность - это не продукт, а процесс.

При желании ядро можно убрать в ящик в прямом смысле слова :).

Еще одно веяние времени эпохи параноиков - отслеживание системных вызовов, совершаемых программой, и дальнейшее их ограничение.

Изначальный подсчет контрольных сумм (MD5-хэшей) системных утилит и файлов и дальнейшая их проверка с помощью утилит типа tripwire или aide может избавить от сильной головной боли в дальнейшем. В случае изменения файла утилита найдет расхождение в MD5-отпечатке и поднимет тревогу.

Хардлинки работают только в пределах одной файловой системы (одной партиции).

Найти все suid/sgid бинарники в системе можно следующей командой:

# find / -type f \( -perm -4000 -o -perm -2000 \) -ls

цифра 4 в маске означает suid, 2 - sgid.



Источник: http://www.xakep.ru/magazine/xs/047/070/1.asp
Категория: Безопасность | Добавил: oleg (07.05.2008) | Автор: Антон Карпов
Просмотров: 1186 | Рейтинг: 0.0/0 |
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа

Beastie

Друзья сайта

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
links

Copyright MyCorp © 2024