Данная статья не претендует на полное пособие или для профессионалов, это лишь попытка обьяснить тем, кто первый раз с фаерволом работает, дать понимание, что все на самом деле просто и логично. Некоторые названия умышленно искажены для более удобного восприятия информации.
Итак, поскольку я работаю исключительно с RHEL-based дистрибутивами, то на их примере и будут рассказывать (это не имеет принципиальной разницы между большинством дистрибутивов линукса, кроме работы с самим демоном iptables). Первое – конфиг лежит – /etc/sysconfig/iptables
Для начала попытаемся понять как это все работает, первое есть несколько таблиц – все правила запретов/разрешений строить лучше всего в таблице фильтр. По умолчанию должно быть три таблицы – mangle – она обрабатывается самой первой, filter – она обрабатывается второй и nat – последняя.
И так, нужно начнем с того что в каждой таблицы есть “глобальные” правила – они задаются в первых строках таблицы вида:
:INPUT ACCEPT
:PREROUTING ACCEPT
:FORWARD ACCEPT
:OUTPUT ACCEPT
:POSTROUTING ACCEPT
PREROUTING и POSTROUTING – используются в таблицах raw, mangle и nat, о них я напишу в следующей части.
Начнем с того, что правильный подход – это глобальные политики ставить запрет всего, а уже правилами разрешать нужный трафик – лучше что-то забыть и потом добавить, чем разрешить все, а правила строить на запрет. Т.е., если мы ставим глобальные политики DROP то должны писать правила чтоже мы принимаем. Мой совет начинающим – ставьте таблицы mangle и nat – все в разрешение, таблица filter – INPUT, FORWARD в DROP, а вот OUTPUT – ACCEPT, так будет проще в начале, чтобы не писать на каждое действие еще и цепочки “ответов”, потом вы всегда успеете переделать.
Первое, что нужно запомнить – регистр имеет значение. т.е. -A и -a это не одно и то же.
Рассмотрим синтаксис комманд – первым делом мы должны указать тип действия -A(добавить правило) или -D(удалить) если мы правим напрямую конфиг – то только -A, затем мы должны сказать какой тип трафика – INPUT(приходящий на сервер, и обращенный напрямую к серверу), FORWARD(приходящий на сервер, но после этого он должен “уйти” куда-то дальше) , OUTPUT (собственно исходящий с сервера). После этого мы уже можем сортировать по критериям:
по интерфейсу (сетевому адаптеру), например -i eth1 – так мы говорим что это сетевая плата(interface) с именем eth1
по отправителю пакетов, например -s 192.168.0.1 – так мы говорим что если отправитель(source) с адресом 192.168.0.1, то…
по получателю, например -d 10.10.10.1 – так мы говорим, что если получатель имеет адрес 10.10.10.1, то…
дальше указываются модули – их пока трогать не будем,
и в конце указывается действие -j DROP или -j ACCEPT или иные.
Минимум, необходимый, для того чтобы правило было принято на обработку – действие, тип трафика, политика:
-A INPUT -j ACCEPT
Что по сути своей будет дубликатом обьявления глобальной политики таблицы.
Итак возьмем простейшие примеры для таблицы filter
-A INPUT -s 192.168.0.1 -j ACCEPT
Таким образом мы разрешаем весь траффик с компьютера 192.168.0.1 к данному серверу.
или же:
-A INPUT -d 10.10.10.10 -j DROP
Запрещаем весь трафик к адресу 10.10.10.1, но(!) это не корректно, не забывайте что INPUT – это все, что пришло на сервер и получателем в конечном итоге является этот сервер, а не кто-то иной. В противном случае надо использовать FORWARD.
Итак, иначе будет
-A FORWARD -d 10.10.10.1 -j DROP
Вот теперь поподробнее рассмотрим что такое FORWARD – это транзитный трафик, который не относится к серверу, но должен проходить через него и идти куда-то дальше к получателю. Это все хорошо, мы можем написать пачку правил типа FORWARD, но по умолчанию они работать не будут, для того чтобы они заработали – надо поменять ключик net.ipv4.ip_forward = 0 в файле /etc/sysctl.conf на net.ipv4.ip_forward = 1. Это можно сказать защита от “дурака” – чтобы по умолчанию нельзя было гонять через ваш сервер трафик. Теперь будет работать 🙂
Думаю это понятно и не сложно, теперь пришло время поговорить немного о модулях. Есть куча модулей, которые позволяют нам вводить дополнительные критерии проверки трафика.
Их примеры
-m mac –mac-source XX:XX:XX:XX:XX:XX – указываем мак, если мак не соответствует указанному будет произведено действие.
-A INPUT -s 192.168.1.1 -m mac –mac-source 11:22:33:44:55:66 -j DROP
Важно так же помнить что есть принцип отрицания
-A INPUT -s 192.168.1.1 -m mac –mac-source ! 11:22:33:44:55:66 -j DROP – отклонять все соединения с адреса 192.168.1.1 если мак-адрес отличен от 11:22:33:44:55:66.
Дальше есть модули для протоколов – tcp udp icmp
И вот тут уже мы можем добавлять критерии по портам подключения: по исходящему порту(–sport) и по порту назначения (–dport). как пример:
-A INPUT -p tcp –dport 21 -j ACCEPT
данная строка означает что принимать все соединения с любых компьютеров на порт 21 по протоколу tcp. Комбинировать можно вместе и –sport и –dport. Порты можно перечислять по одному, либо если они идут подряд через : Пример –dport 137:139
Если хотите описать в одном правиле сразу несколько портов, но они идут не подряд – это тоже возможно, для этого используется модуль multiport
-p tcp -m multiport –dports 139,445,6060
Но он имеет ограничене, только 15 портов, если больше указать – правило будет обработано, но не весь список портов будет учитываться.
Итак я вам привел практически все модули, которые вам нужны будут при ознакомлении, их существует еще большое количество, но это будет выходить за рамки статьи.
В конце я вам просто напомню, что не забывайте никогда в ваших правилах добавлять эти два:
-A INPUT -i lo -j ACCEPT
Это правила говорить что принимать все соединения с localhost (т.е. от самих себя, облегчит вам жизнь)
и второе правило:
-A INPUT -p all -m state –state RELATED,ESTABLISHED -j ACCEPT
Что говорит отвечать на все уже установленные и родственные соединения, что сбережет ваши нервы в последствии.
Вопросы как работать с NAT-ом, строить собственные цепочки постараюсь описать во второй части статьи.
Читать интересно, но вот на опечатках спотыкаюсь.
Прогнал спелл-чекером. В статье много всего:
принпициальной, полателем, соотвествует, ограние …
Во! Так лучше. Спасибо!
“-i eth1” – здесь “-i” не интерфейс, а скорее input interface,
потому как может существовать запись “- o eth1”, что будет означать output interface
Если уж быть точным, то –in-interface. Спасибо за замечание, все никак не найду время вычитать и дописать. Наверное удалю данные “опусы” (: