Защищаем FreeBSD (defender +1)

Как и любую другую систему FreeBSD нужно так же защищать от посягательств на нее. Она не так уж защищена, как много людей о ней думают и ее можно так же сломать и крякнуть, как и тот же Windows просто FreeBSD мало распространена и мало есть спецов, которые с ней работают, а тем более которые знают ее в совершенстве, так что чем больше спецов ее ломают тем больше дыр и руткитов будет открыто и использовано.

Да и на будущее я не претендую на аса в построение защиты и т.д. т.п. а лишь попробую (для себя, чтобы не забыть :) и друзей) описать некоторые моменты защиты, а остальное будет дополняться по мере просьб и необходимости.

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

Хотя я знаю такой - это тот, который на глубине 100 метров под землей в фольге и с вырубленным питанием :) Статья будет дополнятся и изменятся по ходу обсуждений.

Ну ладно, попробуем немного защитится от спецов :)

Защиту разделим по двум видам:

I) Защита от внешних атак

II) Защита от внутренних атак

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

Внешняя атака - Все, что на передовой.

Теперь определим фронт защиты:

I) Атака извне:

1.1) Apache - http.conf + mod_security

1.2) PHP - php.ini + mod_security + отключение опасных функций + Ограничения ресурсов

1.3) FTP - Разделение привилегий + chroot + квоты + отдельный HDD

1.4) Firewall - грамотно настроенный фаервол

1.5) Сhroot

II) Атака внутри:

2.1) Ограничения ресурсов - /etc/login.conf + /etc/sysctl.conf

2.2) Разделение привилегий - /etc/sysctl.conf + chmod + структура папок

2.3) Логии (logcheck)

2.4) top/ps

III) Общие меры

3.1) Разбор fstab

3.2) Доступ к серверу

3.3) DNS - chroot + noroot

Теперь пройдем по пунктам (некоторые пункты будут вкратце описаны т.к. обший принцип защиты пересекается с другими пунктами) как и чем можно защитить и ограничить:

I) Прикрытие внешних дыр.

1.1) Apache + виртуальные хосты + mod_security

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

<IfModule mod_php4.c>

# Включаем Safe mode

php_admin_flag safe_mode on

php_admin_flag safe_mode_gid on

php_admin_value open_basedir /home/domain.ru

# Папка, выше которой скрипт не может видеть

php_admin_value safe_mode_exec_dir /home/domain.ru

# Temp диры юзера

php_admin_value upload_tmp_dir /home/domain.ru/tmp

# Не начинать PHP сессию автоматически

php_admin_flag session.auto_start off

# Где сохранять файлы сессий

php_admin_value session.save_path /home/domain.ru/tmp

</IfModule>

Как известно, немалая часть взломов (SQL Injection, XSS атаки, инклюдинг) происходит по сути посредством хитрого HTTP запроса. Логично предположить, что эти самые запросы неплохо было бы фильтровать. Решение проблемы существует в виде модуля к

Апачу, и называется оно mod_security. Ставим:

# cd /usr/ports/www/mod_security/ && make install clean

После установки - идем конфигурировать. Открываем любой конфиг виртуального хоста, например 001.admin.hosting.ru, над которым мы уже экспериментировали. Все значения надо вводить между тегами <Virtualhost *:80> и </Virtualhost>.

# Включаем mod_security

SecFilterEngine On

# Проверяем запросы

SecFilterScanPOST On

# Проверяем ответы

SecFilterScanOutput On

# Проверяем, правильно ли закодирован URL

SecFilterCheckURLEncoding On

# Включаем этот параметр, если сайт в Unicode

SecFilterCheckUnicodeEncoding Off

# Задаем диапазон байтов

SecFilterForceByteRange 1 255

# Сохраняем в лог только срабатывания механизма

SecAuditEngine RelevantOnly

# Где живет лог :)

SecAuditLog logs/audit_log

# Возвращаем ошибку 500 при срабатывании

SecFilterDefaultAction "deny,log,status:500"

# Перекрываем dots-bug

SecFilter "../"

# Не забываем про XSS

SecFilter "<(.| )+>"

# SQL injection, куда же без него :)

SecFilter "<[[:space:]]*script"

SecFilter "delete[[:space:]]+from"

SecFilter "insert[[:space:]]+into"

SecFilter "select.+from"

# Перекрываем возможность передачи переменных PHP

SecFilterSelective ARG_b2inc "!^$"

# Исключаем возможность раскрытия пути

SecFilterSelective OUTPUT "Fatal error:"

Для и для apache 1.x в httpd.conf закоментите:

#SecFilterScanOutput

#OUTPUT

#OUTPUT_STATUS

У этого модуля - на редкость удачная дефолтная конфигурация. К ней мало, что можно добавить, так как большинство настроек - специфичны. Общий принцип составления правил мы рассмотрели, а остальное можно добавить по своему усмотрению.

1.2) PHP

В дополнение смотри пункт - 2.1

Рассмотрим самое уязвимое место хостинговой системы - выполняемые файлы, в частности,

PHP скрипты. Открываем конфиг PHP:

# ee /usr/local/etc/php.ini

Меняем следующие параметры:

magic_quotes_gpc = Off # Экранирование спецсимволов

disable_functions = system, exec, passthru # Выключаем опасные функции:

Выключить эти функции очень важно. Хоть они и недоступны при включенном safe mode, пользователь может без труда провести успешную атаку, указав в файле .htaccess:

php_flag safe_mode off

1.3) FTP

Настройка Proftpd установите далее по разделение привилегий смотрим -2.1 в котором я указал то что вам нужно, а по Chroot см раздел 1.5 Желательно ftp ставить на отдельный HDD чтобы непроизошло переполнения раздела и все шайтан майфун :) а если у вас он на /etc или /var находился все хана логам и тд :)

1.4) IPFW - штатный файрволл FreeBSD

1.5) Chroot

Chroot - песочница это конечно с одной стороны хорошо с другой - потеря производительности, для некоторых программ лишний дополнительный модуль + конфиг к нему. Я считаю грамотный chmod дает тот же результат , но без заморочек и потерь ресурсов. В основном к chroot прибегают, когда нужно обезопасить сервис, который не совсем безопасный как например BIND(о нем ниже).

Jail - мы не будем это рассматривать ось внутри оси довольно заморочено и плохо документировано, а если все вхосты придется загонять в jail то мало непокажется. Я пока небуду jail рассматривать :)

II) Настраиваем тыл внутренние защитные меры.

2.1) Ограничения ресурсов

Бывает так кроме основного действия PHP скрипта функция N зацикливается, попутно вычисляя некое сложное действие. Как результат - высокая загрузка процессора.

Это очень типичная ситуация для хостинга. Чтобы предотвратить подобные ненамеренные (и намеренные) атаки, необходимо ограничивать юзера в плане ресурсов. У *BSD для таких целей существует система профилей пользователей. Это значит, что мы можем легко ограничить ресурсы каждого пользователя в отдельности.

Открываем /etc/login.conf и добавляем:

# Имя профиля

hosting:

:copyright=/etc/COPYRIGHT:

:welcome=/etc/motd:

:setenv=MAIL=/var/mail/$,BLOCKSIZE=K:

:path=~/bin /bin /usr/bin /usr/local/bin:

:manpath=/usr/share/man /usr/local/man:

:nologin=/var/run/nologin:

# Мах время использования процессора

:cputime=1h30m:

# Мах кол-во памяти, выделяемой программе под данные

# Сам код программы и стэк не учитываются

:datasize=10M:

# Сколько выделяем для стека программы

:stacksize=3M:

# Мах размер физической памяти, выделяемой процессу

:memoryuse=16M:

# Мах размер файла

:filesize=50M:

# Мах размер core файлов

:coredumpsize=1M:

# Сколько файлов может открывать каждый процесс

:openfiles=128:

# Сколько процессов может запускать пользователь

:maxproc=64:

# Пускать юзера в систему только если его домашняя дира существует и доступна юзеру

:requirehome:true

# Время устаревания пароля

:passwordtime=90d:

# Остальное берем из профиля default

:tc=default:

Здесь я указал лишь основные параметры.

Список всех параметров и их описание можно найти в Handbook.

Теперь перейдем к настройке операционки. Открываем /etc/sysctl.conf и пишем туда

следующее:

# Запрещает юзерам видеть процессы соседа&root

security.bsd.see_other_uids=0

# Запрещает видеть групповые процессы

security.bsd.see_other_gids=0

# Пускаем запросы на закрытые порты в черные дыры

net.inet.tcp.blackhole=2

net.inet.udp.blackhole=1

# Указываем размер очереди сокета

kern.ipc.somaxconn=1024

# Отрубаем ip-редиректы

net.inet.icmp.drop_redirect=1

net.inet.icmp.log_redirect=1

net.inet.ip.redirect=0

# Назначаем размеры буфера для TCP-подключений. Если на сервер ожидается большая

# нагрузка, и у него много памяти - лучше поставить 65535. Значение выше 65535

# не рекомендуется.

net.inet.tcp.sendspace=32768

net.inet.tcp.recvspace=32768

# Обновляем ARP-таблицу каждые 20 минут

net.link.ether.inet.max_age=1200

# Запрещаем отвечать на все лишние запросы.

net.inet.icmp.maskrepl=0

net.inet.ip.sourceroute=0

net.inet.ip.accept_sourceroute=0

net.inet.icmp.bmcastecho=0

Здесь указаны не все параметры sysctl остальные смотримMAN SYSCTL(8)

Есть статья Некоторые опции sysctl но она еще не совсем дописана (просьба просить lissyara чтобы доконца перевел ;)).

Многие параметры для sysctl можно изменять и динамически:

sysctl <параметр>=<значение>

Например:

sysctl kern.maxprocperuid=1000

Должно быть похоже на

# sysctl kern.maxprocperuid=1000

kern.maxprocperuid: 3546 -> 1000

Теперь необходимо продублировать часть настроек в /etc/rc.conf:

Дублируем настройки sysctl

icmp_drop_redirect="YES"

icmp_log_redirect="YES"

icmp_bmcastecho="NO"

tcp_drop_synfin="YES"

2.3) Логи

Очень важным аспектом системного администрирования является слежение за сервера.

Но ковырять логии самому заморочено тогда для ленивых существует отличная утилита logcheck ее и поставим.

# cd /usr/ports/security/logcheck && make install clean

Утилита написана на sh скриптах, и занимает всего 29 Кб в архиве. После установки в /usr/local/etc у вас появятся четыре конфига: переименуй их,

убрав из названия файла "sample":

logcheck.hacking - о каких странностях сообщать;

logcheck.violations - о каких попытках взлома сообщать;

logcheck.ignore - какие странности игнорировать;

logcheck.violations.ignore - какие попытки взлома игнорировать.

В целом и общем, первый файл от второго ничем не отличается, равно как и третий от четвертого :).Просто разработчики скрипта решили разнести сообщения о подозрительной активности и сообщения о явной атаке в разные конфиги.

Запускаем скрипт по крону, хотя бы раз в сутки. Дописываем в cron:

0 4 * * * /bin/sh /usr/local/etc/logcheck.sh

При большой активности хостящихся сайтов, логи веб-сервера начнут занимать немало места. И в то же время их надо сохранять.

Можно использовать утилиту logrotate

# /usr/ports/sysutils/logrotate && make install clean

III) Общие меры

3.1) HDD

Сделаем в fstab некоторые изменения для предотвращения нехороших действий.

Укажем где и что можно и нельзя делать системе.

/dev/ad4s3b none swap sw 0 0

/dev/ad4s3a / ufs rw 1 1

/dev/ad4s3e /tmp ufs rw,noexec 2 2

/dev/ad4s3f /usr ufs rw 2 2

/dev/ad4s3f /usr/home ufs rw,nosuid,nodev 2 2

/dev/ad4s3d /var ufs rw,nodev 2 2

noexec - эта опция дает понять что на данном разделе запрещено запускать что либо даже правах на файл chmod 777 (Я знаю что некоторые защищенные сервера ломали именно через /tmp :) в последствии админы советовали прикрывать эту дыру.

И незабываем, что в /tmp может писать почти любой сервис в системе)

nosuid - при этом значении система игнорирует suid-биты. Юзер не сможет сделать

#su и подняться до рута, даже если он знает его пароль рута и находится в группе

wheel (но необходимо понять что нужным юзверям которым нужно #su домашняя директория будет /usr, а тем кого нужно ограничит директория будет /usr/home)

nodev - запрещаем созданиесуществование в данном разделе специальных устройств.

3.2) Доступ

Доступ к серверу следует ограничить. Т.е. серверы убрать в недоступное простым смертным людям и закрыть на ключ. В дополнение не забываем, снять с них все причиндалы мониторы клавы мышки и т.д. Для чего это должно быть понятно, например если я вижу общедоступный физически сервер FreeBSD я тут же по любопытности хочу в него залезть и поковыряться в нем. Но вы скажете, а как же пароль root и т.д. то слушаем дальше, если вы забыли чужой пароль :) а так бывает то делаем так:

А) Загружаемся в однопользовательском режиме , для этого в приглашении загрузчика введите boot -s

Б) Смонтируйте командой mount -u / корневой раздел в режим чтения-записи.

Затем с помощью mount -a примонтируем все что есть (т.е. только что указанно в fstab без опции noauto)

B) Теперь меняйте пароль рута. :)

Чтобы люди не cмогли зайти без пароля рута в однопользовательском режиме делаем так:

# ee /etc/ttys

Измените в строчке console пункт secure на insecure. Если вы сделаете это,

FreeBSD даже при загрузке в однопользовательском режиме будет запрашивать пароль root.

Будьте осторожны при изменении этого значения на insecure. Если вы забудете пароль root, загрузка в однопользовательский режим сильно усложнится.

Это все еще возможно, но несколько более сложно.

# name getty type status comments

#

# If console is marked "insecure", then init will ask for the root password

# when going to single-user mode.

console none unknown off insecure

3.3) DNS

Засунем DNS в песочницу

# named -u 53 -t /var/named

-u - значение UID присваемое процессу named

-t - указывает корневой каталог для демона

Незабываем, что корневой каталог недолжен, быть пустым, он должен содержать все файлы необходимые для нормальной работы демона. Если named скомпилирован так чтобы библиотеки компоновались статически и не нужно было думать что ему надо еще в корневую положить чтобы он запустился :) Так же некоторые советуют в конфиге DNS убрать строчку об версии демона дескать оно сможет помочь атакующему и т.д. я не считаю это критически она может подсказкой и самому админу.

Автор: Raven2000.

Обновлено: 12.03.2015