Делаем FreeBSD безопасной
Сергей Можайский aka techniX
Xakep, номер #069, стр. 069-116-1
(technix@frenzy.org.ua)
FreeBSD: Top Security
Итак, ты решил построить сервер на базе FreeBSD. Хороший выбор. Однако любой сервер является лакомым кусочком для хакера, и даже не стоит сомневаться в том, что рано или поздно он подвергнется атаке. Поэтому в первую очередь стоит заняться не настройкой различных сервисов, а защитой системы от взлома. Конечно, в системе, установленной с настройками по умолчанию, защита находится на достаточном уровне. Однако мы можем сделать наш сервер настоящим крепким орешком. Ну что, начнем строить защиту своей FreeBSD-системы?
Консольные твики
Как известно, загрузившись в однопользовательском режиме, можно изменить пароль суперпользователя. Нам следует устранить эту досадную недоработку. Отредактируем файл /etc/ttys таким образом, чтобы при загрузке с опцией boot -s система запрашивала пароль
Код:
console none unknown off insecure
Также следует запретить прямой вход с консоли пользователя root. Для этого в том же файле нужно сменить статус консоли на insecure. Вот пример для нулевой консоли:
Код:
ttyv0 "/usr/libexec/getty Pc" cons25 on insecure
Для того чтобы только пользователь root мог видеть все запущенные процессы, добавь в /etc/sysctl.conf следующую запись:
Код:
kern.ps_showallprocs=0
Ваши права?
Права доступа к файлам - одна из отличительных особенностей UNIX-систем. Давай назначим эти права как следует. На некоторые системные файлы стоит установить такие флаги доступа, чтобы они были доступны только суперпользователю. Вот примерный список:
Код:
# chmod 700 /root
# cd /etc
# chmod 600 syslog.conf rc.conf newsyslog.conf hosts.allow login.conf
Некоторые системные файлы стоит защитить даже от суперпользователя. Для этого существуют модификационные флаги, установить которые можно командой chflags. К ним относятся флаг appnd, который переводит файл в режим добавления данных, и флаг chg, делающий файл изменяемым только для пользователя root. Подробности по использованию этой команды можно прочесть на странице руководства, посвященного chflags (man chflags).
Файловую систему с пользовательскими каталогами лучше смонтировать с параметром -nosuid, который игнорирует suid-биты на файлах. Вот пример строчки из /etc/fstab, монтирующий /usr/home с флагом nosuid (nodev здесь также не помешает - прим.ред.):
/dev/ad0s1h /usr/home ufs rw,nosuid 2 2
Утилита suidcontrol (www.watson.org/fbsd-hardening/suidcontrol.html) поможет установить правильную политику в отношении suid/sgid-файлов в системе.
Чтобы при загрузке удалялось содержимое каталога /tmp, добавляем в /etc/rc.conf строку
clear_tmp_enable="YES"
Уровни защиты ядра
Ядро FreeBSD может работать на нескольких уровнях защиты (securelevel). Значение этого уровня варьируется от -1 до 3. Для нас интересны последние три режима. В режиме 1 (безопасный режим) нельзя снимать модификационные флаги с файлов, а смонтированные дисковые устройства и файлы устройств /dev/mem, /dev/kmem не могут быть открыты для записи. В режиме 2 (режим повышенной безопасности), в дополнение к предыдущему, запрещена прямая запись на диски, независимо от того, смонтированы они или нет. В режиме 3 (режим безопасности сети), кроме ограничений второго режима, запрещено изменение правил файрволов и ограничений скорости канала. Для включения уровней защиты следует добавить в
/etc/rc.conf строки
Код:
kern_securelevel_enable="YES"
kern_securelevel="2"
Текущий уровень защиты можно посмотреть командой
$ sysctl kern.securelevel
А повысить его без перезагрузки -
Код:
# sysctl -w kern.securelevel=2
Отмечу, что при уровне защиты 1 или выше пересобрать userland и ядро тебе не удастся, поскольку на важных системных файлах стоят модификационные флаги.
Меняем алгоритм шифрования
Заменим алгоритм шифрования паролей с md5 на еще более надежный Blowfish. Делаем исправления в файле
/etc/login.conf в секции default:
Код:
// заменяем алгоритм шифрования на Blowfish
:passwd_format=blf:\
// устанавливаем период устаревания паролей
:passwordtime=52d:\
// предупреждаем о том, что пароли должны содержать разные символы
:mixpasswordcase=true:\
// задаем минимальную длину пароля
:minpasswordlen=9:\
Теперь обновляем базу (login.conf.db):
# cap_mkdb /etc/login.conf
Проверим, получилось ли у нас. Посмотри содержимое
/etc/master.passwd. Если зашифрованный пароль теперь начинается с
"$2", все ОК. Осталось сделать так, чтобы пароли новых пользователей шифровались алгоритмом Blowfish. Редактируем файл /etc/auth.conf:
crypt_default=blf
Шифруем файловую систему
Файлы, которые могут представлять интерес для взломщиков, надежнее всего зашифровать. Нет, не думай, что я опять буду рассказывать про PGP. Для создания зашифрованных дисков можно обойтись стандартными средствами FreeBSD - GEOM и BDE. Что такое GEOM? Это новая система работы с дисками, появившаяся в 5-й ветке FreeBSD. Благодаря своей модульной структуре, она позволяет делать с файловой системой все что угодно. Нас интересует один из ее модулей - BDE (block device encryption) - поддержка шифрования файловой системы. Для начала добавим в ядро опцию
options GEOM_BDE
Создадим новый каталог, в котором будут лежать конфиги GBDE:
Код:
# mkdir /etc/gbde
Инициализируем зашифрованный диск:
# gbde init /dev/ad4s1c -i -L /etc/gbde/ad4s1c
Откроется редактор, в котором можно указать различные настройки. Для файловых систем UFS1 и UFS2, используемых в FreeBSD, следует указать значение переменной sector_size равным 2048. Не забудь выбрать хороший пароль для доступа к диску. Подключаем диск:
Код:
# gbde attach /dev/ad4s1c -l /etc/gbde/ad4s1c
Система попросит ввести ключевую фразу для доступа к зашифрованному диску. Теперь содержимое этого диска доступно при обращении к файлу устройства /dev/ad4s1c.bde. Создадим на нем новую файловую систему и монтируем его:
Код:
# newfs -U -O2 /dev/ad4s1c.bde
# mount /dev/ad4s1c.bde /mnt
Теперь можно работать с содержимым зашифрованного диска. Обрати внимание, что скорость файловых операций с зашифрованными разделами почти в 4 раза ниже, чем при работе с обычными дисками. Если ты пользуешься утилитой sysinstall, имей в виду, что она несовместима с зашифрованными разделами и их нужно отключать перед запуском этой утилиты. Также заметь, что зашифрованные диски невозможно подключать автоматически из /etc/fstab, потому не стоит применять шифрование к системным разделам (
/, /usr, /var).
По окончании работы с зашифрованным разделом размонтируем устройство и отключим шифрованный диск:
Код:
# umount /dev/ad4s1c.bde
# gbde detach /dev/ad4s1c
IP-протоколы
Теперь займемся защитой от атак, связанных с недостатками протокола TCP/IP. Начнем с фильтрации SYNFIN-пакетов. Это TCP-пакеты с одновременно установленными флагами начала и завершения соединения, пользы от них практически никакой, зато они часто используются при хакерских атаках. Одновременно займемся ICMP-протоколом и включим в ядро еще парочку полезных опций:
Код:
// ох уж эти SYNFIN-пакеты
options TCP_DROP_SYNFIN
// ограничиваем количество ICMP-ответов, что помогает при защите от DoS атак
options ICMP_BANDLIM
// генерируем случайный идентификатор IP-пакетов
options RANDOM_IP_ID
// блокируем RST-пакеты
options TCP_RESTRICT_RST
Но этого еще недостаточно, добавляем в /etc/rc.conf:
// отбрасываем SYNFIN-пакеты
tcp_drop_synfin="YES"
// отключаем прием и отправку переадресовывающих ICMP-пакетов
icmp_drop_redirect="YES"
// в системном журнале регистрируем переадресовывающие ICMP-пакеты
icmp_log_redirect="YES"
// предотвращаем springboarding и smurf-атаки
icmp_bmcastecho="NO"
Далее прописываем в /etc/sysctl.conf строчки
net.inet.tcp.blackhole=2
net.inet.udp.blackhole=1
С помощью этих переменных мы превращаем нашу систему в так называемую "черную дыру". Отныне она не будет реагировать на пакеты, поступающие на закрытые порты, и они будут просто пропадать. Этот прием позволяет защититься от флуда и от скрытого сканирования портов.
Огненная стена
Естественно, без фильтрации сетевого трафика нам не обойтись. Встроенный файрвол ipfw позволит нам фильтровать пакеты по заданным критериям и вести учет. Для того чтобы включить файрвол, нужно добавить в ядро вот эти опции:
Код:
options IPFIREWALL
options IPFIREWALL_VERBOSE
После чего добавить в /etc/rc.conf строки
firewall_enable="YES"
firewall_type="open"
Однако тип файрвола "open" подходит для чего угодно, но только не для защищенного сервера. Поэтому для более надежной защиты можно выбрать одну из стандартных конфигураций:
Код:
// защита только сервера
firewall_type="client"
// защита сервера и локальной сети
firewall_type="simple"
или же написать свой файл с правилами файрвола. Немного разберемся с созданием правил. Общий формат правила ipfw такой:
<действие> <протокол> from <откуда> to <куда> <дополнительные условия>
В качестве выполняемого действия файрвол может разрешить (allow, pass, accept, permit) прохождение пакета или запретить (deny, drop, reject) его, а также посчитать (count), перенаправить по нужному адресу (fwd, forward) или другой программе (divert). Протоколы могут быть ip или all (для всех протоколов стека TCP/IP), а также tcp, udp, icmp и т.п.
Формат поля источника (from) и приемника (to) пакета может быть записан в различных формах: доменное имя, ip-адрес, подсеть в формате IP:MASK (192.168.1.0:255.255.255.0) или IP/LENGTH (192.168.1.0/24), а также в виде специального слова any (любой адрес) или me (все адреса локальной машины). Для tcp и udp протокола после адреса источника или приемника можно через пробел указать еще и порт. И, наконец, из дополнительных условий самыми полезными являются направление пакета (in или out - входящий и исходящий соответственно), интерфейс, через который будет проходить пакет (например, via fxp0), и даже идентификатор пользователя (uid) или группы (gid), для которых это правило будет работать. Теперь не составит труда разобраться, что правило deny tcp from any to 192.168.1.0/24 in via fxp0
запрещает прохождение любых входящих tcp-пакетов через интерфейс fxp0 к сети 192.168.1.0/24, а правило
count ip from 192.168.1.0/24 to me uid 1001
будет вести учет трафика, который получит из сети 192.168.1.0/24 пользователь с UID, равным 1001.
Каждое правило файрвола должно иметь свой уникальный номер. Правила проверяются в порядке возрастания своих номеров. Для управления файрволом существует команда ipfw. Чтобы добавить правило, воспользуйся командой
Код:
# ipfw add <номер> <правило>
а чтобы его удалить:
# ipfw delete <номер>
Для просмотра списка правил есть команда ipfw list, а ipfw show покажет трафик и количество пакетов, обработанных каждым из правил. В качестве примера для настройки файрвола можно посмотреть файл /etc/rc.firewall, а также ознакомиться с руководством по ipfw. Напоследок добавим в /etc/rc.conf строчку
log_in_vain="YES"
Теперь все попытки подключения к закрытым портам твоего сервера будут занесены в логи.
Демонов - под контроль
Не ко всем службам, запущенным на твоем сервере, стоит давать доступ. Если заблокировать доступ к отдельным портам можно с помощью правильной настройки файрвола, то доступ к службам проще ограничить с помощью файла /etc/hosts.allow. Для примера ограничим доступ по ssh только несколькими сетями:
Код:
# vi /etc/hosts.allow
sshd : localhost : allow
sshd : 192.168.1. : allow
sshd : 10.1.1.0/255.255.255.240 : allow
sshd : ALL : deny
Формат файла, как видишь, достаточно простой. Сначала мы указываем имя службы, затем имя или адрес хоста или сети, затем действие. Правило ALL указывает, как поступать в случаях, не предусмотренных предыдущими правилами.
Теперь займемся демоном inetd, который играет весьма важную роль в обеспечении безопасности системы. Через него работают telnetd, ftpd, talk и прочие службы. Если никакие из демонов, запускаемых из inetd, тебе не нужны, отключи его. Для этого надо указать в /etc/rc.conf:
inetd_enable="NO"
Если тебе все же нужен inetd и службы, которые запускаются из него, то стоит включить протоколирование событий и при большой нагрузке увеличить количество одновременных обращений к inetd (по умолчанию это число равно 256). Для этого добавь в /etc/rc.conf строчку
inetd_flags="-l -R 1024"
Последние штрихи
Вот мы и закончили, все изменения в конфигурационные файлы внесены, настройки сделаны. Осталось пересобрать ядро и перезагрузить систему. Посмотрим, чего мы добились.
$ netstat -na | grep LISTEN
Эта команда покажет нам, на каких портах висят сервисы. Чем их меньше, тем лучше. Также попробуй просканить свою машину nmap'ом. Итак, теперь твоя система намного более защищена, чем раньше. Не забывай регулярно обновлять ее и следить за логами. Удачи!
Система безопасности TrustedBSD MAC
В FreeBSD 5 появилась новая система безопасности ядра, TrustedBSD MAC Framework. MAC расшифровывается как Mandatory Access Control - принудительный контроль доступа. Система MAC с помощью установки так называемых меток на различные компоненты системы ограничивает доступ к ним на основе созданных администратором политик. Например, с помощью MAC вполне реально создать систему контроля доступа к файловой системе, аналогичной файрволу ipfw, разграничить видимость процессов и многое другое. Если тебя заинтересовала эта тема, обратись к соответствующему разделу FreeBSD HandBook, а также страницам руководства (man 4 mac).
DANGER
Используй SSH для удаленного управления сервером, иначе никакие рекомендации по безопасности тебе не помогут. Никогда не пользуйся telnet для удаленного доступа.
WWW
www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/security.html
www.freebsd.org/security/security.html
www.watson.org/fbsd-hardening/
www.antioffline.com/deviation/bsd.html
defcon1.org/html/Security/Secure-Guide/secure-guide.html