Текст книги "Iptables Tutorial 1.1.19"
Автор книги: Oskar Andreasson
Жанр:
ОС и Сети
сообщить о нарушении
Текущая страница: 8 (всего у книги 14 страниц)
Действие ULOG предоставляет возможность журналирования пакетов в пользовательское пространство. Оно заменяет традиционное действие LOG, базирующееся на системном журнале. При использовании этого действия, пакет, через сокеты netlink, передается специальному демону который может выполнять очень детальное журналирование в различных форматах (обычный текстовый файл, база данных MySQL и пр.) и к тому же поддерживает возможность добавления надстроек (плагинов) для формирования различных выходных форматов и обработки сетевых протоколов. Пользовательскую часть ULOGD вы можете получить на домашней странице ULOGD project page.
Таблица 6-25. Действие ULOG
(Ключ – Пример – Описание)
Ключ: –ulog-nlgroup
Пример: iptables -A INPUT -p TCP –dport 22 -j ULOG –ulog-nlgroup 2
Описание: Ключ –ulog-nlgroup сообщает ULOG в какую группу netlink должен быть передан пакет. Всего существует 32 группы (от 1 до 32). Если вы желаете передать пакет в 5-ю группу, то можно просто указать –ulog-nlgroup 5. По-умолчанию используется 1-я группа.
Ключ: –ulog-prefix
Пример: iptables -A INPUT -p TCP –dport 22 -j ULOG –ulog-prefix "SSH connection attempt: "
Описание: Ключ –ulog-prefix имеет тот же смысл, что и аналогичная опция в действии LOG. Длина строки префикса не должна превышать 32 символа.
Ключ: –ulog-cprange
Пример: iptables -A INPUT -p TCP –dport 22 -j ULOG –ulog-cprange 100
Описание: Ключ –ulog-cprange определяет, какую долю пакета, в байтах, надо передавать демону ULOG. Если указать число 100, как показано в примере, то демону будет передано только 100 байт из пакета, это означает, что демону будет передан заголовок пакета и некоторая часть области данных пакета. Если указать 0, то будет передан весь пакет, независимо от его размера. Значение по-умолчанию равно 0.
Ключ: –ulog-qthreshold
Пример: iptables -A INPUT -p TCP –dport 22 -j ULOG –ulog-qthreshold 10
Описание: Ключ –ulog-qthreshold устанавливает величину буфера в области ядра. Например, если задать величину буфера равной 10, как в примере, то ядро будет накапливать журналируемые пакеты во внутреннем буфере и передавать в пользовательское пространство группами по 10 пакетов. По-умолчанию размер буфера равен 1 из-за сохранения обратной совместимости с ранними версиями ulogd, которые не могли принимать группы пакетов.
Глава 7. Файл rc.firewall
В этой главе мы рассмотрим настройку брандмауэра на примере сценария rc.firewall.txt. Мы будем брать каждую базовую настройку и рассматривать как она работает и что делает. Это может натолкнуть вас на решение ваших собственных задач. Для запуска этого сценария вам потребуется внести в него изменения таким образом, чтобы он мог работать с вашей конфигурацией сети, в большинстве случаев достаточно изменить только переменные.
ПРИМЕЧАНИЕ: Примечательно, что есть более эффективные способы задания наборов правил, однако я исходил из мысли о большей удобочитаемости сценария, так, чтобы каждый смог понять его без глубоких познаний оболочки BASH.
7.1. Пример rc.firewall
Итак, все готово для разбора файла примера rc.firewall.txt (сценарий включен в состав данного документа в приложении Примеры сценариев). Он достаточно велик, но только из-за большого количества комментариев. Сейчас я предлагаю вам просмотреть этот файл, чтобы получить представление о его содержимом и затем вернуться сюда за более подробными пояснениями.
7.2. Описание сценария rc.firewall
Первая часть файла rc.firewall.txt является конфигурационным разделом. Здесь задаются основные настройки брандмауэра, которые зависят от вашей конфигурации сети. Например IP адреса – наверняка должны быть изменены на ваши собственные. Переменная $INET_IP должна содержать реальный IP адрес, если вы подключаетесь к Интернет через DHCP, то вам следует обратить внимание на скрипт rc.DHCP.firewall.txt, Аналогично $INET_IFACE должна указывать ваше устройство, через которое осуществляется подключение к Интернет. Это может быть, к примеру, eth0, eth1, ppp0, tr0 и пр.
Этот сценарий не содержит каких либо настроек, специфичных для DHCP, PPPoE, поэтому эти разделы не заполнены. То же самое касается и других «пустых» разделов. Это сделано преднамеренно, чтобы вы могли более наглядно видеть разницу между сценариями. Если вам потребуется заполнить эти разделы, то вы можете взять их из других скриптов, или написать свой собственный.
Раздел Local Area Network должен содержать настройки, соответствующие конфигурации вашей локальной сети. Вы должны указать локальный IP адрес брандмауэра, интерфейс, подключенный к локальной сети, маску подсети и широковещательный адрес.
Далее следует секция Localhost Configuration, которую изменять вам едва ли придется. В этой секции указывается локальный интерфейс lo и локальный IP адрес 127.0.0.1. За разделом Localhost Configuration, следует секция Iptables Configuration. Здесь создается переменная $IPTABLES, содержащая путь к файлу iptables (обычно /usr/local/sbin/iptables). Если вы устанавливали iptables из исходных модулей, то у вас путь к iptables может несколько отличаться от приведенного в сценарии (например /usr/sbin/iptables), однако в большинстве дистрибутивов iptables расположена именно здесь.
В первую очередь, командой /sbin/depmod -a, выполняется проверка зависимостей модулей после чего производится подгрузка модулей, необходимых для работы сценария. Старайтесь в ваших сценариях загружать только необходимые модули. Например, по каким то причинам мы собрали поддержку действий LOG, REJECT и MASQUERADE в виде подгружаемых модулей и теперь собираемся строить правила, использующие эти действия, тогда соответствующие модули необходимо загрузить командами:
/sbin/insmod ipt_LOG /sbin/insmod ipt_REJECT /sbin/insmod ipt_MASQUERADE
ОСТОРОЖНО: В своих сценариях я принудительно загружаю все необходимые модули, во избежание отказов. Если происходит ошибка во время загрузки модуля, то причин может быть множество, но основной причиной является то, что подгружаемые модули скомпилированы с ядром статически. За дополнительной информацией обращайтесь к разделу Проблемы загрузки модулей.
В следующей секции приводится ряд модулей, которые не используются в данном сценарии, но перечислены для примера. Так например модуль ipt_owner, который может использоваться для предоставления доступа к сети с вашей машины только определенному кругу пользователей, повышая, тем самым уровень безопасности. Информацию по критериям ipt_owner, смотрите в разделе Критерий Owner главы Как строить правила.
Мы можем загрузить дополнительные модули для проверки «состояния» пакетов (state matching). Все модули, расширяющие возможности проверки состояния пакетов, именуются как ip_conntrack_* и ip_nat_*. С помощью этих модулей осуществляется трассировка соединений по специфичным протоколам. Например: протокол FTP является комплексным протоколом по определению, он передает информацию о соединении в области данных пакета. Так, если наш локальный хост передает через брандмауэр, производящий трансляцию адресов, запрос на соединение с FTP сервером в Интернет, то внутри пакета передается локальный IP адрес хоста. А поскольку, IP адреса, зарезервированные для локальных сетей, считаются ошибочными в Интернет, то сервер не будет знать что делать с этим запросом, в результате соединение не будет установлено. Вспомогательный модуль FTP NAT выполняет все необходимые действия по преобразованию адресов, поэтому FTP сервер фактически получит запрос на соединение от имени нашего внешнего IP адреса и сможет установить соединение. То же самое происходит при использовании DCC для передачи файлов и чатов. Установка соединений этого типа требует передачи IP адреса и порта по протоколу IRC, который так же проходит через трансляцию сетевых адресов на брандмауэре. Без специального модуля расширения работоспособность протоколов FTP и IRC становится весьма сомнительной. Например, вы можете принимать файлы через DCC, но не можете отправлять. Это обусловливается тем, как DCC «запускает» соединение. Вы сообщаете принимающему узлу о своем желании передать файл и куда он должен подключиться. Без вспомогательного модуля DCC соединение выглядит так, как если бы мы потребовали установление соединения внешнего приемника с узлом в нашей локальной сети, проще говоря такое соединение будет «обрушено». При использовании же вспомогательного модуля все работает прекрасно. поскольку приемнику передается корректный IP адрес для установления соединения.
ПРИМЕЧАНИЕ: Если у вас наблюдаются проблемы с прохождением mIRC DCC через брандмауэр, но при этом другие IRC-клиенты работают вполне корректно – прочитайте раздел Проблемы mIRC DCC в приложении Общие проблемы и вопросы.
Дополнительную информацию по модулям conntrack и nat читайте в приложении Общие проблемы и вопросы. Так же не забывайте о документации, включаемой в пакет iptables. Чтобы иметь эти дополнительные возможности, вам потребуется установить patch-o-matic и пересобрать ядро. Как это сделать – объясняется выше в главе Подготовка.
ПРИМЕЧАНИЕ: Заметьте, что загружать модули ip_nat_irc и ip_nat_ftp вам потребуется только в том случае, если вы хотите, чтобы преобразование сетевых адресов (Network Adress Translation) производилось корректно с протоколами FTP и IRC. Так же вам потребуется подгрузить модули ip_conntrack_irc и ip_conntrack_ftp до загрузки модулей NAT.
Здесь мы запускаем пересылку пакетов (IP forwarding), записав единицу в файл /proc/sys/net/ipv4/ip_forward таким способом:
echo "1" > /proc/sys/net/ipv4/ip_forward
ПРЕДУПРЕЖДЕНИЕ: Наверное стоит задуматься над тем где и когда включать пересылку (IP forwarding). В этом и в других сценариях в данном руководстве, мы включаем пересылку до того как создадим какие либо правила iptables. От начала работы пересылки (IP forwarding) до момента, когда будут созданы необходимые правила, при нашем варианте, может пройти от нескольких миллисекунд до минут, все зависит от объема работы, выполняемой сценарием и быстродействия конкретного компьютера. Понятно, что это дает некоторый промежуток времени, когда злоумышленник может проникнуть через брандмауэр. Поэтому, в реальной ситуации запускать пересылку (IP forwarding) следует после создания всего набора правил. Здесь же я поместил включение пересылки в начале исключительно в целях удобочитаемости.
Если вам необходима поддержка динамического IP, (при использовании SLIP, PPP или DHCP) вы можете раскомментарить строку:
echo "1" > /proc/sys/net/ipv4/ip_dynaddr
Если вам требуется включить любые другие опции, вы должны обращаться к соответствующей документации по этим опциям. Хороший и лаконичный документ по файловой системе /proc поставляется вместе с ядром. Ссылки на на другие документы вы найдете в приложении Ссылки на другие ресурсы.
ПРИМЕЧАНИЕ: Сценарий rc.firewall.txt и все остальные сценарии в данном руководстве, содержат небольшую по размерам секцию не требуемых (non-required) настроек /proc. Как бы привлекательно не выглядели эти опции – не включайте их, пока не убедитесь, что достаточно четко представляете себе функции, которые они выполняют.
Здесь мы поговорим о пользовательских цепочках, в частности – о пользовательских цепочках, определяемых в сценарии rc.firewall.txt. Мой вариант разделения правил по дополнительным цепочкам может оказаться неприемлемым в том или ином конкретном случае. Я надеюсь, что смогу показать вам возможные «подводные камни». Данный раздел тесно перекликается с главой Порядок прохождения таблиц и цепочек и совершенно нелишним будет еще раз, хотя бы бегло, просмотреть ее.
Распределив набор правил по пользовательским цепочкам, я добился экономии процессорного времени, без потери уровня безопасности системы и читабельности сценариев. Вместо того, чтобы пропускать TCP пакеты через весь набор правил (и для ICMP, и для UDP), я просто отбираю TCP пакеты и пропускаю их через пользовательскую цепочку, предназначенную именно для TCP пакетов, что приводит к уменьшению нагрузки на систему. На следующей картинке схематично приводится порядок прохождения пакетов через netfilter. В действительности, эта картинка выглядит несколько ограниченно по сравнению со схемой, приведенной в главе Порядок прохождения таблиц и цепочек.
Основное назначение рисунка – освежить нашу память. В целом, данный пример сценария основан на предположении, что мы имеем одну локальную сеть, один брандмауэр (firewall) и единственное подключение к Интернет, с постоянным IP адресом (в противоположность PPP, SLIP, DHCP и прочим). Так же предполагается, что доступ к сервисам Интернет идет через брандмауэр, что мы полностью доверяем нашей локальной сети и поэтому не собираемся блокировать траффик, исходящий из локальной сети, однако Интернет не может считаться доверительной сетью и поэтому необходимо ограничить возможность доступа в нашу локальную сеть извне. Мы собираемся исходить из принципа «Все что не разрешено – то запрещено». Для выполнения последнего ограничения, мы устанавливаем политику по-умолчанию – DROP. Тем самым мы отсекаем соединения, которые явно не разрешены.
А теперь давайте рассмотрим что нам нужно сделать и как.
Для начала – позволим соединения из локальной сети с Интернет. Для этого нам потребуется выполнить преобразование сетевых адресов (NAT). Делается это в цепочке PREROUTING(Я полагаю, что здесь автор просто допустил опечатку, поскольку в тексте сценария заполняется цепочка POSTROUTING, да и мы уже знаем, что SNAT производится в цепочке POSTROUTING таблицы nat прим. перев.), которая заполняется последней в нашем сценарии. Подразумевается, также, выполнение некоторой фильтрации в цепочке FORWARD. Если мы полностью доверяем нашей локальной сети, пропуская весь траффик в Интернет, то это еще не означает доверия к Интернет и, следовательно необходимо вводить ограничения на доступ к нашим компьютерам извне. В нашем случае мы допускаем прохождение пакетов в нашу сеть только в случае уже установленного соединения, либо в случае открытия нового соединения, но в рамках уже существующего (ESTABLISHED и RELATED).
Что касается машины-брандмауэра – необходимо до минимума свести сервисы, работающие с Интернет. Следовательно мы допускаем только HTTP, FTP, SSH и IDENTD доступ к брандмауэру. Все эти протоколы мы будем считать допустимыми в цепочке INPUT, соответственно нам необходимо разрешить «ответный» траффик в цепочке OUTPUT. Поскольку мы предполагаем доверительные взаимоотношения с локальной сетью, то мы добавляем правила для диапазона адресов локальной сети, а заодно и для локального сетевого интерфейса и локального IP адреса (127.0.0.1). Как уже упоминалось выше, существует ряд диапазонов адресов, выделенных специально для локальных сетей, эти адреса считаются в Интернет ошибочными и как правило не обслуживаются. Поэтому и мы запретим любой траффик из Интернет с исходящим адресом, принадлежащим диапазонам локальных сетей. И в заключение прочитайте главу Общие проблемы и вопросы.
Так как у нас работает FTP сервер, то правила, обслуживающие соединения с этим сервером, желательно было бы поместить в начало цепочки INPUT, добиваясь тем самым уменьшения нагрузки на систему. В целом же, надо понимать, что чем меньше правил проходит пакет, тем больше экономия процессорного времени, тем ниже нагрузка на систему. С этой целью я разбил набор правил на дополнительные цепочки.
В нашем примере я разбил пакеты на группы по их принадлежности к тому или иному протоколу. Для каждого типа протокола создана своя цепочка правил, например, tcp_packets, которая содержит правила для проверки всех допустимых TCP портов и протоколов. Для проведения дополнительной проверки пакетов, прошедших через одну цепочку, может быть создана другая. В нашем случае таковой является цепочка allowed. В этой цепочке производится дополнительная проверка отдельных характеристик TCP пакетов перед тем как принять окончательное решение о пропуске. ICMP пакеты следуют через цепочку icmp_packets. Здесь мы просто пропускаем все ICMP пакеты с указанным кодом сообщения. И наконец UDP пакеты. Они проходят через цепочку udp_packets, которая обрабатывает входящие UDP пакеты. Если они принадлежат допустимым сервисам, то они пропускаются без проведения дополнительной проверки.
Поскольку мы рассматриваем сравнительно небольшую сеть, то наш брандмауэр используется еще и в качестве рабочей станции, поэтому мы делаем возможным соединение с Интернет и с самого брандмауэра.
И в завершение о цепочке OUTPUT. Мы не выполняем каких либо специфичных блокировок для пользователей, однако мы не хотим, чтобы кто либо, используя наш брандмауэр выдавал в сеть «поддельные» пакеты, поэтому мы устанавливаем правила, позволяющие прохождение пакетов только с нашим адресом в локальной сети, с нашим локальным адресом (127.0.0.1) и с нашим адресом в Интернет. С этих адресов пакеты пропускаются цепочкой OUTPUT, все остальные (скорее всего сфальсифицированные) отсекаются политикой по-умолчанию DROP.
Прежде, чем приступить к созданию набора правил, необходимо определиться с политиками цепочек по-умолчанию. Политика по-умолчанию устанавливается командой, подобной приводимой ниже
iptables [-P {chain} {policy}]
Политика по-умолчанию представляет собой действие, которое применяется к пакету, не попавшему под действие ни одного из правил в цепочке. (Небольшое уточнение, команда iptables -P применима ТОЛЬКО К ВСТРОЕННЫМ цепочкам, т.е. INPUT, FORWARD, OUTPUT и т.п., и не применима к пользовательским цепочкам. прим. перев.).
ОСТОРОЖНО: Будьте предельно осторожны с установкой политик по-умолчанию для цепочек из таблиц, не предназначенных для фильтрации, так как это может приводить к довольно странным результатам.
Итак, у вас перед глазами наверняка уже стоит картинка движения пакетов через различные цепочки, и как эти цепочки взаимодействуют между собой! Вы уже должны ясно представлять себе цели и назначение данного сценария. Давайте начнем создавать цепочки и наборы правил для них.
Прежде всего необходимо создать дополнительные цепочки с помощью команды -N. Сразу после создания цепочки еще не имеют ни одного правила. В нашем примере создаются цепочки icmp_packets, tcp_packets, udp_packets и цепочка allowed, которая вызывается из цепочки tcp_packets. Входящие пакеты с интерфейса $INET_IFACE (т.е. из Интернет), по протоколу ICMP перенаправляются в цепочку icmp_packets, пакеты протокола TCP перенаправляются в цепочку tcp_packets и входящие пакеты UDP с интерфейса eth0 идут в цепочку udp_packets. Более подробное описание вы найдете в разделе Цепочка INPUT. Синтаксис команды для создания своей цепочки очень прост:
iptables [-N chain]
Эта цепочка предназначена для отфильтровывания пакетов с «неправильными» заголовками и решения ряда других проблем. Здесь отфильтровываются все пакеты, которые распознаются как NEW, но не являются SYN пакетами, а так же обрабатываются SYN/ACK-пакеты, имеющие статус NEW. Эта цепочка может быть использована для защиты от вторжения и сканирования портов. Сюда, так же, добавлено правило для отсеивания пакетов со статусом INVALID.
Если вы пожелаете почитать более подробно об этой проблеме, то смотрите раздел Пакеты со статусом NEW и со сброшенным битом SYN в приложении Общие проблемы и вопросы. Разумеется, не всегда справедливо будет просто сбрасывать пакеты с признаком NEW и сброшенным битом SYN, но в 99% случаев это оправданный шаг. Поэтому мой сценарий заносит информацию о таких пакетах в чичтемный журнал, а затем «сбрасывает» их.
Причина, по которой для SYN/ACK-пакетов со статусом NEW применяется действие REJECT, достаточно проста. Она описывается в разделе SYN/ACK – пакеты и пакеты со статусом NEW приложения Общие проблемы и вопросы. Общепринятой считается необходимость отправления пакета RST в подобных случаях (RST в ответ на незапрошенный SYN/ACK). Тем самым мы предотвращаем возможность атаки «Предсказание номера TCP-последовательности» (Sequence Number Prediction) на другие узлы сети.
TCP пакет, следуя с интерфейса $INET_IFACE, попадает в цепочку tcp_packets, если пакет следует на разрешенный порт, то после этого проводится дополнительная проверка в цепочке allowed.
Первое правило проверяет, является ли пакет SYN пакетом, т.е. запросом на соединение. Такой пакет мы считаем допустимым и пропускаем. Следующее правило пропускает все пакеты с признаком ESTABLISHED или RELATED. Когда соединение устанавливается SYN пакетом, и на этот запрос был отправлен положительный ответ, то оно получает статус ESTABLISHED. Последним правилом в этой цепочке сбрасываются все остальные TCP пакеты. Под это правило попадают пакеты из несуществующего соединения, пакеты со сброшенным битом SYN, которые пытаются запустить соединение. Не SYN пакеты практически не используются для запуска соединения, за исключением случаев сканирования портов. Насколько я знаю, на сегодняшний день нет реализации TCP/IP, которая поддерживала бы открытие соединения иначе, чем передача SYN пакета, поэтому на 99% можно быть уверенным, что сброшены пакеты, посланные сканером портов.