IPTABLES

Iptables — утилита для работы с правилами, которые использует сетевой фильтр netfilter.

Netfilter — компонент ядра, а iptables — утилита, работающая в пользовательском пространстве.

-F — удалить все правила (можно указать цепочку, иначе очистятся все);

-A — добавить правило (критерий и цель) в заданную цепочку;

-D — удалить правило (критерий и цель, либо порядковый номер в заданной цепочке);

-P — установить политику по умолчанию для заданной цепочки;

-I — вставка нового правила в цепочку;

-L — посмотреть список правил (можно указать цепочку, иначе выводятся все);

N — создать новую цепочку с заданным именем в таблице;

-X — удалить заданную цепочку (но сначала нужно удалить в ней правила, и на нее не должны ссылаться правила из других цепочек);

Другие команды посмотрите самостоятельно.

Пример:

`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*

*root@user-virtual-machine:~#*

Видим цепочки в выводе команды. Вспомним про этапы обработки пакетов на уровне ядра. Обратите внимание, что политика по умолчанию — ACCEPT, то есть все пакеты по умолчанию пропускаются.

Существуют и другие политики (например, DROP).

Пример:

`iptables -P INPUT DROP`

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

`iptables -P INPUT ACCEPT`

Политика по умолчанию задает порядок работы с пакетами, для которых нет ни одного правила. Если в цепочке правил ни одно не подошло, в итоге применяется действие по умолчанию, которое и задается политикой. Если правило подошло, действие по умолчанию не выполняется.

Цепочка — это набор правил, которые проверяются по пакетам поочередно (напоминает язык программирования). В таблице filter видим цепочки INPUT, FORWARD и OUTPUT. Но есть и другие таблицы (их нужно указывать явно): таблица nat, когда нам необходима трансляция адресов и портов, и mangle — когда требуется внести изменения в пакет (например, установить ttl в 64 и скрыть от провайдера использование подключения как шлюза к собственной сети).

`iptables -t nat -L`

*Chain PREROUTING (policy ACCEPT)

target prot opt source destination

Chain INPUT (policy ACCEPT)

target prot opt source destination

Chain OUTPUT (policy ACCEPT)

target prot opt source destination

Chain POSTROUTING (policy ACCEPT)

target prot opt source destination*

Для критериев можно использовать следующие параметры:

-p — тип протокола: tcp,udp, icmp (полный список здесь: cat /etc/protocols);

-s — IP-адрес отправителя (можно использовать адреса сетей с маской 10.0.0.0/255.0.0.0 или 10.0.0.0/8). Можно применять логическое отрицание, поставив символ ! перед адресом;

-d — IP-адрес получателя (синтаксис аналогичный);

-i — сетевой интерфейс, с которого получен пакет (по умолчанию пакеты обрабатываются независимо от того, с какого интерфейса они пришли);

-o — сетевой интерфейс, в который предполагается отправка пакета. Может применяться только в цепочках OUTPUT, FORWARD и POSTROUTING;

-m — лимит, устанавливает предельное число пакетов в единицу времени, которое способно пропустить правило;

–sport — порт (или диапазон портов) отправителя;

–dport — порт назначения (куда предназначен пакет).

Остальные параметры изучите самостоятельно.

В качестве цели можно использовать следующий действия:

* ACCEPT — принять пакет;
* REJECT — отбросить пакет, но выдать сообщение об ошибке на хост отправителя;
* DROP — отбросить пакет, не уведомляя отправителя;
* SNAT (для таблицы NAT) — преобразовать IP-адрес отправителя в заголовке пакета, подменив адрес, указанный в критерии, на свой «белый» IP-адрес, указанный после SNAT ( –to-source=…);
* DNAT (для таблицы NAT) — destination NAT (когда надо перенаправить пакеты с одной машины на несколько разных в зависимости от критериев);
* MASQUERADE (для таблицы NAT) — преобразовать IP-адрес отправителя в заголовке пакета, подменив адрес, указанный в критерии, на свой (например, если он динамический);
* LOG — журналировать пакеты и события;
* MARK (для таблицы mangle) — пометить пакет;
* TTL (для таблицы mangle) — изменить TTL (например, установить его снова в 64, скрыв движения по локальной сети от провайдера);

Обратите внимание: имеет значение порядок правил в цепочке. Сравните:

`iptables -A INPUT -p tcp -j DROP`

`iptables -A INPUT -p tcp –dport=22 -j ACCEPT`

Этот вариант полностью отрежет компьютер от внешнего мира. Несмотря на то, что второе правило разрешает порт 22 (ssh), до него дело не дойдет, так как при срабатывании правила (а оно сработает на любой пакет с TCP-сегментом), будет переход на DROP и завершение движения в цепочке.

А такой вариант сначала разрешит порт 22 и дальше проверять не будет. Те, кто не 22, пойдут дальше и будут отброшены:

`iptables -A INPUT -p tcp –dport=22 -j ACCEPT`
`iptables -A INPUT -p tcp -j DROP`

Рассмотрим примеры. Установим для таблиц по умолчанию политики DROP.

Примечание: не делайте так, работая по ssh. Сначала по ssh настройте правила, дающие доступ к машине, а уже потом применяйте политики. На локальной машине можно сразу.

`iptables -P INPUT DROP`

`iptables -P OUTPUT DROP`

`iptables -P FORWARD DROP`

Таким способом мы запретим и межпроцессный обмен, и обмен через локальную петлю. Не будет действовать локальный DNS-сервер (в Ubuntu он работает по адресу 127.0.1.1), PHP не сможет обратиться к MySQL и так далее. Поэтому:

`iptables -A INPUT -i lo -j ACCEPT`

`iptables -A OUTPUT -o lo -j ACCEPT`

Запрет ICMP — это неправильно. ICMP — часть механизма IP и служит для нормальной работы стека TCP/IP. Машины, у которых полностью запрещен ICMP, создают проблемы при конфигурации сетей, являясь своего рода «черными дырами».

`iptables -A INPUT -p icmp -j ACCEPT`

`iptables -A OUTPUT -p icmp -j ACCEPT`

Далее следует разрешить локальные соединения с динамических портов (мы уже знаем, где их посмотреть):

`cat /proc/sys/net/ipv4/ip_local_port_range 32768 61000`

`iptables -A OUTPUT -p TCP –sport 32768:61000 -j ACCEPT`

`iptables -A OUTPUT -p UDP –sport 32768:61000 -j ACCEPT`

Разрешить только те пакеты, которые мы запросили:

`iptables -A INPUT -p UDP -m state –state ESTABLISHED,RELATED -j ACCEPT`

`iptables -A INPUT -p TCP -m state –state ESTABLISHED,RELATED -j ACCEPT`

Но если работаем как сервер, следует разрешить и нужные порты:

`iptables -A INPUT -i eth0 -p TCP –dport 22 -j ACCEPT`

`iptables -A OUTPUT -o eth0 -p TCP –sport 22 -j ACCEPT` # Разрешили ssh. Если работали через него, теперь можно применять политики по умолчанию.

Аналогично откройте доступ на порты веб-сервера 80 и 443. Проверьте порты настроенной машины с помощью nmap самостоятельно (просканируйте порты с другой машины).

Примеры проброса порта в контейнер:

`iptables -t nat -A PREROUTING –dst 1.2.3.4 -p tcp –dport 80 -j DNAT –to-destination 10.0.0.2`

Пример проброса с одного порта на другой:

`iptables -t nat -D PREROUTING -p tcp –dport 80 -j REDIRECT –to-port 8080`

Более подробно смотрите в официальной документации.

`man iptables`

**Сохранение значений**

Обратите внимание, что все значения, вводимые через iptables, не будут сохранены при перезагрузке.

Для сохранения можно воспользоваться двумя способами:

* Установить демон iptables-persistent, который будет сохранять введенные значения;
* Использовать утилиты iptables-save и iptables-restore. Но вызывать их нужно самостоятельно и при сохранении, и при старте.

По умолчанию iptables-save выводит список правил в stdout, а iptables-restore читает из stdin. Потому надо перенаправить в файл:

`iptables-save > /etc/iptables.rules​​​​​​​`

Чтобы восстановить, нужно вызвать iptables-restore:

`iptables-restore < /etc/iptables.rules`Поднятые сетевые интерфейсы, маршруты тоже не сохранятся. Для сохранения в Ubuntu используйте файл /etc/network/interfaces либо iptables-persistent, или можно добавить iptables-restore < /etc/iptables.rules в /etc/rc.local.

Пример настройки interfaces — в /usr/share/doc/ifupdown/examples/network-interfaces.gz.

Так можно настроить статический сетевой интерфейс /etc/network/interfaces:

address 192.168.200.2

network 192.168.200.0

netmask 255.255.255.0

broadcast 192.168.200.255

dns-nameservers 192.168.200.1 8.8.8.8

up route add -net 192.168.220.0 netmask 255.255.255.0 gw 192.168.200.220

up route add default gw 192.168.200.1

down route del default gw 192.168.200.1

down route del -net 192.168.220.0 netmask 255.255.255.0 gw 192.168.200.220

pre-up iptables-restore < /etc/iptables.rules

post-down iptables-restore < /etc/iptables.downrules

Или так — для динамического интерфейса:

iface ens33 inet dhcp

pre-up iptables-restore < /etc/iptables.rules

post-down iptables-restore < /etc/iptables.downrules

Файл /etc/reslov.conf в /etc/resolv.conf.d использовать не следует. Настройки DNS теперь находятся в вышеописанном файле.

Обратите внимание, что в RedHat-подобных системах (centos) сетевые настройки хранятся совсем в других файлах и форматах.