Содержание статьи
Простая фильтрация пакетов по портам и IP-адресам уже давно никому не интересна, да и эффективной ее не назовешь. Продвинутые межсетевые экраны умеют обрабатывать протоколы верхнего уровня, принимая решение на основе содержимого, а списки IP генерируются динамически. Все это умеет и iptables, нужно лишь его немного докрутить.
Блокируем злоумышленников с помощью fail2ban
Не секрет, что стоит только засветиться в Сети новому сервису, как сразу к нему потянутся нити брутфорсеров, пытающихся подобрать учетные данные. Остановить злоумышленников можно разными способами, один из них — утилита Fail2ban (fail2ban.org). Идея проста: демон, сканируя логи, проверяет наличие записей о неудачных попытках ввода пароля или попытке входа в запрещенную область сети. Если таковые будут найдены, то подозрительный IP блокируется средствами iptables/ipwf или TCP Wrapper (/etc/hosts.allow|deny). Со временем бан может сниматься автоматически, без вмешательства юниксоида, что очень удобно, ведь под раздачу может попасть и легитимный хост. О блокировке пользователь/админ получает сообщение по e-mail. Изначально Fail2ban разрабатывался для защиты SSH, сегодня это уже фреймворк, который можно легко настроить под любые приложения и события, в том числе и прописать свои методы блокировки IP. Удобно также, что один процесс может защищать сразу несколько сервисов.
На странице закачки Fail2ban предлагаются собственные сборки пакетов для большинства дистрибутивов Linux, но для установки лучше выбрать вариант из репозитория. Мэйнтейнеры учитывают особенности конкретного дистра плюс добавляют от себя файлы запуска и правила блокировки.
В Ubuntu/Debian установка очень проста:
$ sudo apt-get install fail2ban
Демон стартует с установками по умолчанию, защищая только SSH. Все настройки производятся в нескольких файлах, размещенных в каталоге /etc/fail2ban (для Debian/Ubuntu). В fail2ban.conf хранятся параметры запуска демона, внутри ничего интересного в плане настроек для нас нет. Начиная с версии 0.7, фильтры и действия прописываются в разных файлах. После установки их можно найти соответственно в подкаталогах filter.d и action.d. Файлы внутри этих директорий могут иметь расширения .conf и .local. Параметры из второго замещают установки из первого, то есть чтобы что-то переопределить, вносить изменения непосредственно в .conf не нужно. Таким образом облегчается последующее обновление и возврат к дефолтным настройкам. Правила поиска довольно просты.
Предусмотрено использование переменных, причем имеются уже встроенные. Так, HOST соответствует регулярному выражению, используемому для поиска IP или имени узла:
(?:::f{4,6}:)?(?P<host>[w-.^_]+)
Вот, например, правило для поиска попыток DDOS-атаки на SSH:
$ grep -v '^#' /etc/fail2ban/fi lter.d/sshd-ddos.conf
[Defi nition]
failregex = sshd(?:[d+])?: Did not receive identifi cation
string from <HOST>$
ignoreregex =
Строка failregex описывает, что искать. В ignoreregex — значения, которые должны игнорироваться. В одном файле может быть несколько таких строк. Кто хоть немного разбирается в регулярных выражениях, легко создаст свое правило, используя имеющиеся примеры. Для разбора лог-файла демон вызывает утилиту fail2ban-regex, которую обычно применяют и для проверки нового фильтра.
Например, в поставке нет правила для Asterisk или другого подобного сервера, но сегодня атаки на VoIP не редки, и в логах можно увидеть записи вроде:
NOTICE[3309] chan_sip.c: Registration from
'sip:XXX@1.2.3.4' failed for '9.8.7.6' — No matching
peer found
Правило будет следующее:
failregex = NOTICE.* .*: Registration from '.*'
failed for '' — No matching peer found
И так для каждого случая. Проверяем:
$ fail2ban-regex /var/log/asterisk.log 'NOTICE.* .*:
Registration from '.*' failed for '' — No matching
peer found'
Если все нормально, записываем фильтры в новый файл asterisk.conf, взяв за пример любой из каталога filter.d.
С тем, что искать, разобрались. Осталось указать, где искать, и что делать с находкой. Описания всех действий собраны в подкаталоге action.d. Здесь несколько файлов под каждое приложение/задачу, как правило, там уже все настроено, и менять ничего не требуется. Но чтобы новые фильтры увидел Fail2ban, необходимо объявить их в /etc/bail2ban/ jail.conf. Внутри этого конфига находим несколько секций с описанием разных сервисов.
$ sudo nano /etc/bail2ban/jail.conf
[DEFAULT]
// IP-адреса, которые не будут блокироваться, здесь можно указать подсеть или DNS-имя
ignoreip = 127.0.0.1
// Время блокировки узла, при отрицательном значении блокировка постоянная
bantime = 600
// Промежуток времени и количество неудачных попыток, необходимых для блокировки
maxretry = 3
fi ndtime = 600
[asterisk-iptables]
enabled = true
В fi lter и action прописываем имя файла без расширения из соответствующих подкаталогов плюс дополнительные параметры
fi lter = asterisk
action = iptables-allports[name=ASTERISK,
protocol=all]
sendmail-whois[name=ASTERISK, dest=root,
sender=fail2ban@example.org]
Логи Asterisk
logpath = /var/log/asterisk/messages
Переопределяем дефолтные значения
maxretry = 5
bantime = 6000
Проверяем, запущены ли сервисы:
$ sudo service iptables start
$ sudo service fail2ban start
Работу Fail2ban можно отследить, просмотрев журнал /var/log/fail2ban.log или правила iptables.
$ sudo iptables -L -v | grep fail2ban
Коллекция аддонов Xtables-addons
Проект patch-o-matic (-ng), предлагавший различные расширения для iptables, уже некоторое время не развивается, его место занял Xtables-addons (xtables-addons.sf.net). Главная его особенность — для установки модулей не требуется пересборка ядра и/или iptables. В итоге добавление новых функций происходит очень просто, нет проблем и при обновлении ядра. Если ядро собиралось вручную, проверь наличие CONFIG_NETFILTER_XTABLES в параметрах:
$ grep -i xtables /boot/confi g-
uname -r
CONFIG_NETFILTER_XTABLES=m
В одних дистрибутивах основные модули уже включены в базовый состав, в других — размещены в репозиториях пакетов. В Ubuntu команда:
$ sudo apt-cache search xtables-addons
...выдаст два пакета: один с инструментами и библиотеками, другой — с исходниками.
$ sudo apt-get build-dep xtables-addons-common
Как правило, в репе находится не самая актуальная версия, поэтому качаем с сайта архив с исходными текстами, распаковываем и даем стандартную последовательность команд: «./configure; make; make install».
Проверяем загрузку модуля:
$ lsmod x_tables
Теперь можно создавать правила. В состав пакета входит более 20 модулей и утилит различного назначения. Документации на сайте как таковой нет, но практически все, что нужно для старта, описано в «man xtables-addons». Разберем самые популярные из них.Отфильтровать шныряющих сканеров и ботов вручную по IP-адресам невозможно, но можно существенно уменьшить поток, отрезав страны, имеющие «скверную репутацию». Модуль GeoIP позволяет применять правила к пакетам на основании страны источника/ назначения. Но чтобы фильтр работал, необходимо скачать и установить базы. Для этой цели используются два скрипта, лежащие в каталоге /usr/ libexec/xtables-addons (или /usr/lib/xtables-addons). Для обработки CSV потребуется соответствующий модуль Perl:
$ cd /usr/libexec/xtables-addons/
$ sudo ./xt_geoip_dl
$ sudo mkdir /usr/share/xt_geoip
$ sudo apt-get install libtext-csv-xs-perl
$ sudo ./xt_geoip_build -D /usr/share/xt_geoip *.csv
После выполнения последней команды будет выведена таблица стран, которые затем указываются через запятую в параметрах '--src-cc' (страна источник), '--dst-cc' (назначение). Все параметры можно узнать, выполнив «iptables -m geoip –help».
// Блокируем азиатских друзей
$ sudo iptables -A INPUT -m geoip
--src-cc CN, TW, KR -j REJECT
// Блокируем анонимные прокси
$ sudo iptables -A INPUT -m geoip
--src-cc A1 -j REJECT
// Подключаться к SSH можно только из России
$ sudo iptables -A INPUT -p tcp –dport 22
-m geoip ! –src-cc RU -j REJECT
// Запрет исходящих ICMP в некоторые страны
$ sudo iptables -A OUTPUT -p icmp -m geoip
–dst-cc ES -j REJECT
Используя GeoIP, можно маркировать трафик, чтобы его обрабатывать по-другому или считать отдельно:
iptables -A INPUT -p tcp --dport 80 -m geoip
--src-cc RU -j MARK --set-mark 1
Все привыкли, что атакуемый хост отражает нападение, просто блокируя IP-адрес, и никак активно не противодействует злоумышленнику. В комплекте аддонов доступно несколько модулей, позволяющих ответить или ввести в заблуждение. Самый известный из них носит название TARPIT. Работает он просто: при подключении соединение открывает, но вот закрыть «забывает» (посылает в ответ пакет с размером TCP окна равным нулю). Удаленная система правильно обработать такой посыл не может и отправляет в ответ сообщение о закрытии соединения, которое игнорируется. В итоге соединение «висит» около двадцати минут, потребляя ресурсы удаленной системы. Например, SSH-сервер часто подвешивают на порт, отличный от 22. Это спасает от некоторых сканеров, для остальных ставим ловушку:
$ sudo iptables -A INPUT -p tcp -m tcp
-dport 22 -j TARPIT
Теперь все, кто попробует подключиться к 22 порту, попадут в расставленные сети.
Модуль DELUDE позволяет ввести в заблуждение сканер, показывая, что запрашиваемый порт открыт и принимает подключения. Если ты еще не решил, какой лучше, TARPIT или DELUDE, используй CHAOS, который в ответ на запрос применяет в основном DROP (по умолчанию к большинству пакетов), но иногда — TARPIT, DELUDE или REJECT. Поведение модуля можно изменить, установив параметры при загрузке при помощи '--delude'/'--tarpit' или в процессе выполнения в файле /sys/modules/ xt_CHAOS/parameters.
Проект IPP2P прекратил свое существование, но в аддонах доступен соответствующий модуль, позволяющий распознавать P2P-трафик, который затем можно блокировать или ограничить. В качестве доппараметров можно указать один из P2P-протоколов, либо все сразу:
$ sudo iptables -A FORWARD -m ipp2p --ipp2p -j DROP
Анализируем трафик с OpenDPI
Межсетевые экраны, работающие на втором и третьем уровнях, давно уже перестали удовлетворять современным требованиям обеспечения безопасности. Например, блокировка портов, используемых ICQ, ничего не даст. Пользователь может обойти запрет, подключившись через прокси, работающий на разрешенных портах вроде 80. Только поднявшись выше, проанализировав данные прикладного уровня, можно действительно ограничить нежелательный трафик. Стандартными средствами iptables этого добиться нельзя, поэтому юниксоиды взяли на вооружение L7-filter и IPP2P. Но говорить о них не будем, так как им на смену пришло более интересное решение — OpenDPI (opendpi.org, code.google.com/p/opendpi).
Распространяемый под лицензией LGPLv3, OpenDPI построен на коде коммерческого продукта PACE, который разрабатывается компанией Ipoque. То есть основа солидная, так как PACE позиционируется как средство классификации трафика и управления пропускной способностью сетей уровня интернет-провайдера. Все возможности по определению протоколов перешли от PACE к OpenDPI: P2P, Skype, VoIP, IM, потоковое видео и аудио, сетевые игры и прочее.
Ставим необходимые для сборки пакеты:
$ sudo apt-get install make gcc libpcap-dev
Скачиваем с сайта проекта opendpi-1.2.0.tar.gz и opendpi-netfilterwrapper1.1.tar.gz, а затем устанавливаем в соответствии с инструкциями внутри, не забыв наложить два патча:
$ tar -xzf opendpi-netfi lter-wrapper-1.1.tar.gz
$ cd opendpi-netfi lter-wrapper-1.1
$ tar -xzf ../opendpi-1.2.0.tar.gz
$ cd opendpi-1.2.0
$ patch -p0 < ../ipq_main.h.diff
$ patch -p0 < ../ipq_protocols.h.diff
Устанавливаем переменную среды:
$ export OPENDPI_PATH=$(pwd)
Но здесь есть проблемы. В документации сказано, что поддерживается ванильное ядро (2.6.27-33), в остальных случаях OpenDPI может не собраться или работать не так. На форуме проекта можно найти патчи для некоторых новых версий кернела. Например, по адресу clck.ru/DWl8 доступен патч для 2.6.35 (такое ядро используется в последнем LTS Ubuntu). Кроме этого в ядре должны быть установлены опции CONFIG_ NF_CONNTRACK_EVENTS и CONFIG_NF_CT_NETLINK. В большинстве современных дистрибутивов так сделано по умолчанию. В Ubuntu и некоторых других .config-файл лежит в каталоге /boot. Можно легко проверить. Берем патч, копируем его в opendpi-netfilter-wrapper, применяем, а затем выполняем сборку:
$ cd ../wrapper
$ patch -p3 < ../opendpi-netfi lter-wrapper-1.1_2.6.35_v3.patch
$ make
Если все равно получаем ошибку, тогда пробуем ванильное ядро версии 2.6.33. Ставим модуль:
$ sudo make modules_install
$ sudo cp ipt/libxt_opendpi.so /lib/xtables
Загружаем и можем использовать:
$ sudo modprobe xt_opendpi
Все доступные параметры можно получить, введя:
$ sudo iptables -m opendpi --help
Выбираем нужный протокол (они также описаны в файле ipq_protocols_osdpi.h) и блокируем его:
iptables -A FORWARD -m opendpi --bittorrent -j DROP
Это самый простой вариант, можно маркировать нужный трафик, чтобы затем использовать в шейпере.
Заключение
Используя сторонние наработки, можно легко расширить стандартные возможности iptables, существенно снизив риски для хоста или целой сети. Конечно, некоторое время придется затратить на создание и отладку необходимых правил, но это впоследствии окупится сполна.
Links
- Сайт Fail2ban — fail2ban.org.
- Ресурсы OpenDPI — opendpi.org, code.google.com/p/opendpi.
- Сайт Xtables-addons — xtables-addons.sf.net.