Введение.
Все пакеты приходящие на сетевую карту проходят все 5(7) уровней модели OSI, iptables начинает обработку пакетов с 3-го(сетевого) уровня, после того как пакет по кабелю попал на сетевую карту, он передается в ядро ОС, а именно в netfilter, далее пакет проходит ряд таблиц и только после этого попадает в приложение(или не попадает, если пакет шел транзитом), которому он был адресован. Именно таблицами и правилами netfilter`а управляет утилита iptables.
Таблицы и цепочки.
В iptables существуют 3 таблицы:
filter - Используется для фильтрации входящего, транзитного и исходящего трафика, имеет 3 цепочки
INPUT - сюда попадает все входящие пакеты
FORWARD - сюда попадают пакеты предназначенные другой машине в сети
OUTPUT — все исходящие пакеты
Над пакетамми проходящими в таблице filter можно делать следующие действия:
DROP — блокировать пакет
ACCEPT - разрешить(пропустить далее) пакет.
Это таблица используется по умолчанию.
nat - Используется для трансляции сетевых адресов(NAT)
PREROUTING — используется для DNAT(трансляция адреса назначения)
POSTROUTING - тут происходит SNAT(Изменение Сетевого Адреса Отправителя)
OUTPUT — Все исходящие из этой цепочки пакеты
Действия, используемые в этой цепочке:
DNAT - как уже упоминалось, используется для трансляции адреса назначения, использую это действие, мы можем пробросить порт, либо целую машину в другую сеть.
SNAT - изменяет исходные адреса пакетов, используется для того, чтобы машины в локальной сети имели доступ в интернет(в случае если наш компьютер — роутер)
MASQUERADE — по сути тоже самое, что и SNAT, только считается что больше нагружает систему. Если у вас выделенный ip — динамический, то нужно использовать именно его, если не хотите каждый раз переписывать правила SNAT.
mangle — Таблица для изменения заголовков пакетов. Имеет цепочки: PREROUTING, FORWARD, OUTPUT, POSTROUTING. У всех цепочек роль одна — вносить изменения в заголовок пакета на различных стадиях движения этого пакета через цепочки iptables. Над этими пакетами можно проводить действия TOS, TTL, MARK.
С точки зрения iptables трафик бывает 3х типов:
Входящий
Транзитный
Исходящий
Движение пакета происходит в следующей последовательности:
=iptables
После прохождения nat(PREROUTING), основываясь на записях в mangle(PREROUTING) и nat(PREROUTING), ядро принимает решение какой будет трафик, входящим или транзитным. Если трафик оказался транзитным, то идем в цепочку mangle(FORWARD),
если входящим, то в mangle(INPUT).
1. Входящий трафик — данные, которые принимает приложение запущенное на компьютере
2. Исходящий трафик — трафик, который передает приложение через сеть
3. Транзитный трафик — трафик, который проходит через наш компьютер другим(в случае если наш компьютер работает как маршрутизатор)
Работа с iptables.
Теперь после того, как мы имеем представление как течет через нас трафик, мы можем что-нибудь с ним сделать.
Основные ключи iptables:
-t (--table) <таблица> — правило указывает таблицу, в которую будут вноситься изменения, без указания этого ключа используется таблица filter
-A (--append) <цепочка> — добавление новой записи в конец цепочки
-D (--delete) <цепочка> — удаление правила
-I (--insert) <цепочка> <номер> — вставляет правило над цепочкой с указанным номером
-R (--replace) <цепочка> <номер> — заменяет определенные критерии цепочки с номером <номер>
-L (--list) <цепочка> — листинг правил цепочки
-F (--flush) <цепочка> — удаление всех правил из цепочки
-P (--policy) <цепочка> — задать действие по умолчанию, действие будет выполняться на все пакеты, которые не подошли по каким-либо параметрам в другие правила.
Ключи классификации и выделения пакетов
-p (--protocol) — используется для указания конкретного протокола для обработки, список всех протоколов можно посмотреть в /etc/protocols/
-s(--src, --source) — адрес исходящих пакетов для фильтрации.
-d (--dst, --destination) — адрес назначения пакетов для фильтрации.
-i (--in-interface) — интерфейс с которого приходит пакет
-o (--out-interface) — интерфейс на который уходит пакет
--sport (--source-port) (может использоваться с ключами -p tcp и -p udp) — порт с которого был отправлен пакет
--dport (--destination-port) (может использоваться с ключами -p tcp и -p udp) — порт на который отправляется пакет
Так же есть ключ, который указывается, когда мы работаем с протоколом icmp (-p icmp):
--icmp-type <тип icmp пакета> — указывается над каким конкретно типом ICMP пакета проводить операцию. Типы ICMP описаны в RFC 792.
На всех ключах классификации возможно применения специального символа !, который буквально означает “кроме”, например:
правило
iptables -A -p tcp -s 192.168.1.7/32 --dport 80 -j DROP
указывает, что все пакеты поступающие с IP-адреса 192.168.1.7 на 80 TCP порт(обычно веб-сервер) необходимо блокировать. А правило:
iptables -A -p tcp -s 192.168.1.7/32 --dport !80 -j DROP
указывает, что все пакеты поступающие с IP-адреса 192.168.1.7 кроме 80 TCP порта необходимо блокировать.
Строим свои правила iptables.
С теорией покончено, переходим к практике. Попробуем настроить фаерволл(цепочка filter) Первым делом, когда вы настраиваете фаервол с нуля, необходимо убедиться, что все правила пусты, сделать это можно командой:
iptables -L
Если картина примерно следующая, то можно приступать к написанию своих правил фильтрации:
debian:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
debian:~#
Если в какой-то из цепочек присутствуют правило, удалим их по одной или воспользуемся ключом -F и очистим цепочку полностью
пример:
iptables -F INPUT
Теперь правила пусты, но прежде чем писать новые необходимо установить политики, как уже было написано, политики это правила, которые обрабатывают пакет неподходящие не под одно из описанных правил в таблицах.
Какой действие(ACCEPT или DROP) должно выполнятся над этими пакетами решать вам, однако хочу предостеречь, если вы настраиваете фаерволл удаленно по ssh, то прежде чем поставить политику DROP на цепочку INPUT, напишите правило, разрешающие соединения к 22 порту TCP:
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
После чего можно смело применять политику DROP на цепочку INPUT:
iptables -P INPUT DROP
После наших манипуляций, цепочка INPUT должна выглядеть следующим образом:
debian:~# iptables -L INPUT
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
debian:~#
Допустим мы имеем сеть 192.168.1.0/24, внешний ip-адрес: 65.25.2.83. Причем локальная сеть подключена к интерфейсу eth0, а интернет к eth1.
Теперь поставим задачу нашему фаерволлу: Максимальная безопасность(политику DROP мы уже поставили), доступ к Веб-серверу могут иметь только IP-адрес 192.168.1.170, доступ к IMAP могут иметь все, однако доступ к smtp-серверу разрешить только локальным пользователям(сеть 192.168.1.0/24).
Незабываем, что цепочка INPUT равно обрабатывает все интерфейсы, если конкретный не указан в параметре -i.
Для доступа к веб-серверу напишем следующие правило:
iptables -A INPUT -p tcp --dport 80 -s 192.168.1.170 -j ACCEPT
Сервер IMAP работает на 143 TCP-порту, следовательно правило будет выглядеть следующим образом:
iptables -A INPUT -p tcp --dport 143 -j ACCEPT
Правило для обработки SMTP входящх пакетов выглядит так:
iptables -A INPUT -p tcp --dport 25 -s 192.168.1.0/32 -j ACCEPT
С поставленной задачей мы разобрались, теперь наш входящий трафик фильтруется и сервер вполне безопасен, единственное, чего бы я поменял, это входящие соединения по SSH. Если вы не планируете заходить на ваш сервер из любой точки планеты, то я бы поменял правило следующим образом:
iptables -R INPUT 1 -p tcp --dport 22 -s 34.1.63.169 -j ACCEPT
где 34.1.63.169 — ip-адрес, с которого мы собираемся заходить на сервер по SSH
Таким образом наша цепочка INPUT таблицы filter выглядит следующим образом:
debian:~# iptables -t filter -L INPUT
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- 34.1.63.169 anywhere tcp dpt:ssh
ACCEPT tcp -- 192.168.1.170 anywhere tcp dpt:www
ACCEPT tcp -- anywhere anywhere tcp dpt:imap2
ACCEPT tcp -- 192.168.1.0 anywhere tcp dpt:smtp
debian:~#
Как видим простые правила фильтрации писать очень легко имея небольшую теоретическую основу.
Поставим следующую задачу: нам необходимо организовать доступ в интернет из локальной сети по портам 80 и 110 и компьютеру с ip-адресом 192.168.1.2 по всем портам.
Первым делом установим политику по умолчанию для цепочки FORWARD в DROP:
iptables -P FORWARD DROP
Затем нам необходимо, чтобы пакеты проходящие через цепочку FORWARD таблицы filter фильтровались таким образом, чтобы все пользователи сети 192.168.1.0/24 имели доступ к 80 и 110 портам tcp:
iptables -A FORWARD -s 192.168.1.0/24 -p tcp -m multiport -dports 80,110 -i eth0 -j ACCEPT
здесь -m multiport -dports указывает, что мы будем перечислять порты через запятую, а -i eth0 что трафик будет идти из интерфейса локальной сети.
Следующее правило разрешает хождение в обратную сторону, когда клиенты локальной сети будут получать данные из интернета:
iptables -A FORWARD -d 192.168.1.0/24 -p tcp -m multiport --sports 80,110 -i eth1 -j ACCEPT
Теперь правила для хоста 192.168.1.2:
iptables -A FORWARD -s 192.168.1.2 -i eth0 -j ACCEPT
iptables -A FORWARD -d 192.168.1.2 -o eth1 -j ACCEPT
И теперь добавляем самое волшебное правило, правило маскарада в цепочку POSTROUTING таблицы nat:
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
Под конец опубликую получившиеся таблицы filter и nat:
debian:~# iptables -t filter -L
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- 34.1.63.169 anywhere tcp dpt:ssh
ACCEPT tcp -- 192.168.1.170 anywhere tcp dpt:www
ACCEPT tcp -- anywhere anywhere tcp dpt:imap2
ACCEPT tcp -- 192.168.1.0 anywhere tcp dpt:smtp
Chain FORWARD (policy DROP)
target prot opt source destination
ACCEPT tcp -- 192.168.1.0/24 anywhere multiport dports www,pop3
ACCEPT tcp -- anywhere 192.168.1.0/24 multiport sports www,pop3
ACCEPT all -- 192.168.1.2 anywhere
ACCEPT all -- anywhere 192.168.1.2
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
debian:~# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
debian:~#
Теперь пользователи довольствуются интернетом, а мы заслуженной банкой пива :)
В статье конечно описаны далеко не все возможности программы iptables, пожалуй только самые “популярные”, в статье не описано как работать с состояниями пакета(NEW, RELATED, ESTABLISHED), не описана работы с таблицей mangle да и еще много всего, я оставляю изучение этого на вас, в добавок кину пару ссылок: