PTABLES — руководство: часть 1 — основы IPTABLES

IPTABLES — руководство: часть 3 — параметры правил

IPTABLES — руководство: часть 4 — цели для правил

Управление IPTABLES

Просмотр правил

Просмотр текущих правил в таблице filter:

1 # iptables -t filter --list

Тоже самое — для остальных:

1 # iptables -t raw --list
1 # iptables -t nat --list
1 # iptables -t mangle --list

Или с опцией -L:

1 # iptables -t filter -L

Колонки тут:

  • num – номер правила текущей цепочке (см. дальше);
  • target – действие;
  • prot – протокол —  TCP, UDP, ICMP и т.д.;
  • opt – специальные опции для этого правила;
  • source – исходный IP-адрес пакетов;
  • destination –  IP-адрес назначения пакетов.

Далее я буду придерживаться коротких опций, вида -L, вместо длинных вида --list.

Просмотр списка правил и счётчиков:

1 # iptables -L -v
2 Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
3 pkts bytes target     prot opt in     out     source               destination
4 3313  199K DROP       all  --  any    any     37.9.53.253          anywhere

Кроме того, -v (verbose) выводит:

— имена интерфейсов для правил;
— заголовки TOS;
— дополнительные опции правила.

verbose так же можно использовать при создании-удалении правил и т.д.

Не переводить IP в имена хостов (FQDN):

1 # iptables -L -n

Выводить номер правила:

1 # iptables -L --line-numbers

Вывести правила только для INPUT, с отображением счётчиков, IP вместо имён хостов, и номерами правил:

1 # iptables -L INPUT -v -n --line-numbers

Просмотреть только список правил:

1 # iptables -S

Пример:

01 # iptables -S
02 -P INPUT ACCEPT
03 -P FORWARD ACCEPT
04 -P OUTPUT ACCEPT
05 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
06 -A INPUT -p icmp -j ACCEPT
07 -A INPUT -i lo -j ACCEPT
08 -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
09 -A INPUT -j REJECT --reject-with icmp-host-prohibited
10 -A FORWARD -j REJECT --reject-with icmp-host-prohibited

Управление chains

Создать цепочку:

1 # iptables -N new_chain
1 # iptables -L new_chain
2 Chain new_chain (0 references)
3 target     prot opt source               destination

Переименовать цепочку:

1 # iptables -E new_chain old_chain
1 # iptables -L old_chain
2 Chain old_chain (0 references)
3 target     prot opt source               destination

Удалить цепочку:

1 # iptables -X old_chain
1 # iptables -L old_chain
2 iptables: No chain/target/match by that name.

Управление правилами

Добавить правило:

1 <em># iptables -A chain</em>

Выполнит append к указанной chain, добавляя правило в конец списка. Пример:

1 # iptables -A INPUT -s 192.168.1.102 -j ACCEPT
1 # iptables -L INPUT
2 ...
3 ACCEPT     all  --  192.168.1.102        anywhere

Вставить правило:

1 # iptables -I <em>chain</em> <em>rulenum</em>

Добавит правило в цепочку chain под номером rulenum (если такой номер уже есть — то на его место, а существующее — сдвинется «вниз»). Пример:

1 # iptables -I INPUT 1 -s 192.168.1.102 -j ACCEPT
1 # iptables -L --line-numbers
2 Chain INPUT (policy ACCEPT)
3 num  target     prot opt source               destination
4 1    ACCEPT     all  --  192.168.1.102        anywhere

Заменить правило:

1 # iptables -R chain rulenum

Добавит правило в цепочку chain под номером rulenum (если такой номер уже есть — то на его место, а существующее -будет удалено). Пример:

1 # iptables -R INPUT 1 -s 192.168.1.102 -j DROP
1 # iptables -L --line-numbers
2 Chain INPUT (policy ACCEPT)
3 num  target     prot opt source               destination
4 1    DROP       all  --  192.168.1.102        anywhere

Удалить правило — вариант 1:

1 # iptables -D <em>chain</em> <em>rulenum</em>

Удалит правило в цепочке chain с номером rulenum. Пример:

1 # iptables -D INPUT 1
1 # iptables -L --line-numbers
2 Chain INPUT (policy ACCEPT)
3 num  target     prot opt source               destination

Удалить правило — вариант 2:

1 # iptables -D <em>chain</em> <em>rule</em>

Удалит правило, которое соответствует rule. Пример:

1 # iptables -I INPUT 1 -s 192.168.1.102 -j DROP
1 # iptables -L --line-numbers
2 Chain INPUT (policy ACCEPT)
3 num  target     prot opt source               destination
4 1    DROP       all  --  192.168.1.102        anywhere
1 # iptables -D INPUT -s 192.168.1.102 -j DROP
1 # iptables -L --line-numbers
2 Chain INPUT (policy ACCEPT)
3 num  target     prot opt source               destination
4 1    ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED

Другие опции

Изменить правило по-умолчанию:

1 # iptables -P chain target

Например, для INPUT изменить ACCEPT на DROP:

1 # iptables -L
2 Chain INPUT (policy ACCEPT)
1 # iptables -P INPUT DROP
1 # iptables -L
2 Chain INPUT (policy DROP)

(будьте осторожны с этой опцией — можете лишиться доступа к серверу)

Сбросить (удалить) все правила во всех цепочка:

1 # iptables -F

Удалить правила только для цепочки INPUT:

1 # iptables -F INPUT

(будьте осторожны с этой опцией — можете лишиться доступа к серверу)

Обнулить все счётчики во всех правилах:

1 # iptables -Z

Пример:

1 # iptables -L -v
2 Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
3 pkts bytes target     prot opt in     out     source               destination
4 25  2352 ACCEPT     all  --  any    any     anywhere             anywhere            state RELATED,ESTABLISHED
1 # iptables -Z
1 # iptables -L -v
2 Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
3 pkts bytes target     prot opt in     out     source               destination
4 5   356 ACCEPT     all  --  any    any     anywhere             anywhere            state RELATED,ESTABLISHED

Сохранение и восстановление правил

В CentOS правила хранятся в файле /etc/sysconfig/iptables:

01 # head /etc/sysconfig/iptables
02 # Generated by iptables-save v1.4.7 on Thu Oct 16 18:56:56 2014
03 *filter
04 :INPUT ACCEPT [0:0]
05 :FORWARD ACCEPT [0:0]
06 :OUTPUT ACCEPT [66:27636]
07 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
08 -A INPUT -p icmp -j ACCEPT
09 -A INPUT -i lo -j ACCEPT
10 -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
11 -A INPUT -j REJECT --reject-with icmp-host-prohibited

Для сохранения правил — выполните:

1 # service iptables save
2 iptables: Saving firewall rules to /etc/sysconfig/iptables:[  OK  ]

Что бы сохранить правила в отдельный файл — используйте:

1 # iptables-save > /root/iptables_bkp

Что бы восстановить из него:

1 # iptables-restore < /root/iptables_bkp

С помощью опции -c команды iptables-save можно так же сохранить значения счётчиков, а с помощью-t <em>tablename</em> — сохранить определённую таблицу. Подробнее — смотрите тут>>>.

Тут приводятся примеры настройки для различных ситуаций. Про структуруIPTABLES, управление, архитектуру и прочее — смотрите в цикле Linux: IPTABLES — руководство: часть 1 — основы IPTABLES.

Настройка осуществляется на:

# lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 6.0.7 (squeeze)
Release:        6.0.7
Codename:       squeeze

Создаём файл настроек для IPTABLES:

# touch /etc/network/if-up.d/iptables.conf

Разрешаем его запуск:

# chmod +x /etc/network/if-up.d/iptables.conf

ВАЖНО: некоторые опции указываются с двумя тире — хотя в примерах они отображаются как одно! Учтите это, если копируете правила прямо из блога:

— — state
— — dport
— — tcp-flags
— — reject-with

В него добавляем:

#!/bin/bash

# Задаём путь к исполняемому файлу IPTABLES
IPTABLES=’/sbin/iptables’

# Сбрасываем существующие правила для всех таблиц и цепочек
$IPTABLES -F
$IPTABLES -X

# Задаём правила по-умолчанию (если не сработало не одно правило из цепочки — сработает правило отсюда)
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT

# Разрешаем весь трафик по loopback интерфейсу lo0

 $IPTABLES -A INPUT -i lo -j ACCEPT

# Разрешаем трафик уже установленным и создающим новые подключения соединениям:
$IPTABLES -A INPUT -m state —state RELATED,ESTABLISHED -j ACCEPT

# Разрешаем входящий SSH через интерфейс eth0
$IPTABLES -A INPUT -p tcp -i eth0 —dport 22 -j ACCEPT

Теперь разберём созданные правила подробнее.

В IPTABLES используется три вида таблиц:

  1. Mangle — обычно эта цепочка используется для внесения изменений в заголовок пакета, например для изменения битов TOS и пр.
  2. Nat — эта цепочка используется для трансляции сетевых адресов (Destination Network Address Translation). Source Network Address Translation выполняется позднее, в другой цепочке. Любого рода фильтрация в этой цепочке может производиться только в исключительных случаях.
  3. Filter — здесь производится фильтрация трафика. Помните, что все входящие пакеты, адресованные нам, проходят через эту цепочку, независимо от того с какого интерфейса они поступили.

Соответственно, нас интересует третья таблица Filter. В этой таблицы имеются три встроенные цепочки:

  1. INPUT — для входящих пакетов.
  2. FORWARD — для проходящих через данную машину к другой.
  3. OUTPUT — для исходящих.

Пакет, проходящий через эти цепочки, исходя из правила может быть пропущен (ACCEPT) или отброшен (DROP):

  • ACCEPT — пропустить пакет; просмотр таблицы завершается
  • DROP — выбросить молча; просмотр завершается не только для текущей цепочки, но и для других таблиц
  • REJECT — выбросить, известив отправителя (—reject-with тип-извещения)

Первое созданное нами правило для цепочки INPUT задаёт поведение по-умолчанию для пакетов, проходящих через этот фильтр. В случае, если ни одно из правил, заданных ниже не будет применено к пакету — он будет отброшен (DROP) без уведомления отправителя:

$IPTABLES  -P INPUT DROP

Пакеты, проходящие фильтр OUTPUT соответственно будут пропущены:

То же самое касается «транзитных» пакетов:

$IPTABLES  -P OUTPUT ACCEPT

Следующее правило:

$IPTABLES  -A INPUT -i lo -j ACCEPT

Задаёт пользовательское правило (-A) в фильтр INPUT для пакетов, проходящих через интерфейс (-i) loopback (lo) и выполняет цель (-j) «принять» (ACCEPT).

В следующем правиле используется модуль (-m) state, который проверяет состояние устанавливаемого соединения — RELATED или ESTABLISHED и если соединение подходит под это правило — разрешает его:

$IPTABLES -A INPUT -m state —state RELATED,ESTABLISHED -j ACCEPT

Возможные состояния: INVALID — пакет не связан с каким-либо известным соединением, ESTABLISHED— пакет связан с соединением, по которому уже проходили пакеты в обоих направлениях, NEW — пакет инициирует новое соединение, либо связан с соединением, по которому ещё не проходили пакеты в обоих направлениях , RELATED — пакет инициирует новое соединение, но также связан с уже существующим соединением, например при передаче данных по FTP или сообщении об ошибке ICMP, SNAT — виртуальное состояние, положительный результат выдаётся если исходный адрес источника отличен от адреса, который должен получить ответ, DNAT — виртуальное состояние, положительный результат выдаётся если исходный адрес получателя отличен от адреса отправителя ответа.

В следующем правиле для фильтра входящих соединений INPUT мы указываем:

$IPTABLES -A INPUT -p tcp -i eth0 —dport 22 -j ACCEPT

Протокол (-p) TCP, интерфейс (-i) eth0, и порт назначения, т.е. порт на нашем сервере, к которому устанавливается соединение (—dport) 22.

Добавим ещё несколько правил:

#Делаем защиту от DOS атак:
$IPTABLES -A INPUT -p tcp -m tcp —tcp-flags SYN,ACK,FIN,RST RST -m limit —limit 1/s -j ACCEPT

# Разрешаем FTP
$IPTABLES -A INPUT -i eth0 -p tcp —dport 21 -j ACCEPT

# Разрешаем HTTP
$IPTABLES -A INPUT -i eth0 -p tcp —dport 80 -j ACCEPT

# Разрешаем HTTPS
$IPTABLES -A INPUT -i eth0 -p tcp —dport 443 -j ACCEPT

# Разрешаем SMTP только из сети 77.120.***.1/24
$IPTABLES -A INPUT -s 77.120.***.1/24 -i eth0 -p tcp —dport 25 -j ACCEPT

# Разрешаем SMTP всем, но запрещаем отправку для адреса 77.120.***.46
$IPTABLES -A INPUT -s ! 77.120.***.46 -i eth0 -p tcp —dport 25 -j ACCEPT

# РазрешаемPOP3 только с IP 77.120.***.46
$IPTABLES -A INPUT -s 77.120.***.46 -i eth0 -p tcp —dport 110 -j ACCEPT

# Разрешаем DNS
$IPTABLES -A INPUT -i eth0 -p udp —sport 53 -j ACCEPT

# Доступ к портам 8081 и 8082 разрешаем только из сетей 91.***.**.0/24, 195.***.***.0/23 и IP 37.***.**.174
for net in 91.***.**.0/24 195.***.***.0/23 37.***.**.174; do
$IPTABLES -A INPUT -p tcp -m tcp -s $net -m multiport —dports 8081,8082 -j ACCEPT
done
$IPTABLES -A INPUT -p tcp -m tcp -m multiport —dports 8081,8082 -j DROP

# Разрешаем ping
$IPTABLES -A INPUT -p icmp -j ACCEPT

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

# /etc/network/if-up.d/iptables.conf reload

В случае ошибок — будет указано в какой строке какая ошибка. Например:

iptables v1.4.8: unknown protocol `tcp—dport’ specified

Пропущен пробел после tcp.

Посмотреть текущие правила можно с помощью опции —list:

# iptables —list
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  —  anywhere             anywhere
ACCEPT     all  —  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  —  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  —  anywhere             anywhere            tcp flags:FIN,SYN,RST,ACK/RST limit: avg 1/sec burst 5
ACCEPT     tcp  —  anywhere             anywhere            tcp dpt:ftp
ACCEPT     tcp  —  anywhere             anywhere            tcp dpt:www
ACCEPT     tcp  —  anywhere             anywhere            tcp dpt:https
ACCEPT     tcp  —  0.***.***.77.colo.static.dc.volia.com/24  anywhere            tcp dpt:smtp
ACCEPT     tcp  — !0.***.***.77.colo.static.dc.volia.com/24  anywhere            tcp dpt:smtp
ACCEPT     tcp  —  46.***.***.77.colo.static.dc.volia.com  anywhere            tcp dpt:pop3
ACCEPT     udp  —  anywhere             anywhere            udp spt:domain
ACCEPT     tcp  —  91.***.**.0/24  anywhere            tcp multiport dports tproxy,8082
ACCEPT     tcp  —  195.***.***.0/23     anywhere            tcp multiport dports tproxy,8082
ACCEPT     tcp  —  37.***.***.174       anywhere            tcp multiport dports tproxy,8082
DROP       tcp  —  anywhere             anywhere            tcp multiport dports tproxy,8082
ACCEPT     icmp —  anywhere             anywhere            icmp echo-request

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Ещё несколько примеров использования.

Проверить статус IPTABLES:

# iptables -L -n -v
Chain INPUT (policy DROP 176 packets, 36734 bytes)
pkts bytes target     prot opt in     out     source               destination
0     0 ACCEPT     all  —  lo     *       0.0.0.0/0            0.0.0.0/0
179K   40M ACCEPT     all  —  *      *       0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED
1   100 ACCEPT     tcp  —  eth0   *       0.0.0.0/0            0.0.0.0/0           tcp dpt:22
0     0 ACCEPT     tcp  —  eth0   *       0.0.0.0/0            0.0.0.0/0           tcp dpt:21
3   180 ACCEPT     tcp  —  eth0   *       0.0.0.0/0            0.0.0.0/0           tcp dpt:80
1    28 ACCEPT     icmp —  *      *       0.0.0.0/0            0.0.0.0/0
1    60 ACCEPT     tcp  —  *      *       195.191.226.102      0.0.0.0/0           tcp dpt:514
0     0 ACCEPT     tcp  —  *      *       91.218.228.236       0.0.0.0/0           tcp dpt:514

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 180K packets, 12M bytes)
pkts bytes target     prot opt in     out     source               destination

Ключи:

-L: показать список правил;
-v: выводить дополнительную информацию;
-n: отображать ip адрес и порт числами, а не перобразовывать в FQDN-имя.

Вывести текущие правила, только INPUT:

# iptables -L INPUT -n -v

Или только OUTPUT:

# iptables -L OUTPUT -n -v

Добавление и удаление правил.

Вывести текущие правила INPUT с указанием строк (номеров правил):

# iptables -L INPUT -n —line-numbers
Chain INPUT (policy DROP)
num  target     prot opt source               destination
1    ACCEPT     all  —  0.0.0.0/0            0.0.0.0/0
2    ACCEPT     all  —  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED
3    ACCEPT     tcp  —  0.0.0.0/0            0.0.0.0/0           tcp dpt:22
4    ACCEPT     tcp  —  0.0.0.0/0            0.0.0.0/0           tcp dpt:21
5    ACCEPT     tcp  —  0.0.0.0/0            0.0.0.0/0           tcp dpt:80
6    ACCEPT     icmp —  0.0.0.0/0            0.0.0.0/0
7    ACCEPT     tcp  —  195.191.226.102      0.0.0.0/0           tcp dpt:514
8    ACCEPT     tcp  —  91.218.228.236       0.0.0.0/0           tcp dpt:514

Что бы добавить правило перед 5:

# iptables -I INPUT 5 -i eth0 -p tcp —dport 8080 -j ACCEPT

Проверяем:

# iptables -L INPUT -n —line-numbers | grep 80
5    ACCEPT     tcp  —  0.0.0.0/0            0.0.0.0/0           tcp dpt:8080
6    ACCEPT     tcp  —  0.0.0.0/0            0.0.0.0/0           tcp dpt:80

Старое правло «подвинулось» на 6 строку, новое — стало 5.

Заблокировать входящие соединения для IP 8.8.8.8:

# iptables -I INPUT 7 -s 8.8.8.8 -j DROP

Проверяем:

# iptables -L INPUT -n —line-numbers | grep 8.8.8.8
7    DROP       all  —  8.8.8.8              0.0.0.0/0

Заблокировать исходящий ICMP на facebook.com:

# iptables -A OUTPUT -p icmp -d www.facebook.com -j DROP

Пробуем:

# ping 173.252.101.26
PING 173.252.101.26 (173.252.101.26) 56 (84) bytes of data.
ping: sendmsg: Operation not permitted
ping: sendmsg: Operation not permitted

Посмотрим в правилах:

# iptables -L OUTPUT -n —line-numbers
Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination
1    DROP       tcp  —  0.0.0.0/0            173.252.101.26

Использование MAC-адреса в правилах — разрешаем SSH только с MAC 00:60:ef:0b:f6:1a:

# iptables -A INPUT -p tcp —destination-port 22 -m mac —mac-source 00:60:ef:0b:f6:1a -j ACCEPT

Разрешить SSH с адресов начиная от 10.0.0.5 и до 10.0.0.10 включительно:

# iptables -A INPUT -p tcp —destination-port 22 -m iprange —src-range 10.0.0.5-10.0.0.10 -j ACCEPT

Ограничить количество параллельных соединений к серверу для одного адреса

Для ограничений используется connlimit модуль. Чтобы разрешить только 3 SSH соединения на одного клиента:

# iptables -A INPUT -p tcp —syn —dport 22 -m connlimit —connlimit-above 3 -j REJECT

Установить количество запросов HTTP до 20:

# iptables -p tcp —syn —dport 80 -m connlimit —connlimit-above 20 —connlimit-mask 24 -j DROP

Опции:

—connlimit-above 3: указывает, что правило действует только если количество соединений превышает 3;

—connlimit-mask
24: указывает маску сети.

Ссылки по теме:

http://konungr.ru

http://www.doless.ru

http://nikmy.ru

http://www.iptables.ru

http://www.opennet.ru

http://www.opennet.ru

http://rus-linux.net

http://cartmanees.blogspot.com

http://rusua.org.ua

http://www.fullautomatic.ru

2

Чем отличается настройка iptables в Debian от других операционных систем? Тем, что достаточно давно сложилось так, что способ загрузки правил iptables оставался на усмотрение администратора, который администрирует сервер. И хотя позже появились такие решения, как ufw, пришедший из Ubuntu, или iptables-persistent, все равно может потребоваться реализовать автоматическую загрузку таблиц самостоятельно. И есть несколько способов это сделать…

Прежде, чем рассматривать способы загрузки и сохранения таблиц, давайте разберемся, что мы можем использовать. Это три команды:

Команда iptables – это основная команда для изменения текущих таблиц, по ней можно найти много информации на просторах Интернета, поэтому пока не будем подробно рассматривать все ее возможности.

Команда iptables-save выдает на стандартный вывод действующие в данный момент правила iptables, поэтому для сохранения их в файл надо использовать перенаправление потоков:

Команда iptables-restore делает, как вы уже догадались, обратное. То есть восстанавливает правила iptables. Работает она тоже со стандартными потоками, поэтому загрузка правил будет выглядеть так:

А теперь давайте более подробно посмотрим, как же, собственно, организовать загрузку правил автоматически.

Способ 1. Простой способ.

Самый простой способ загрузки таблиц – это вызывать загрузку после поднятия основного сетевого интерфейса при помощи параметра post-up, размещенного в файле /etc/network/interfaces

Что для этого потребуется? В первую очередь нам потребуется директория, в которой будут храниться файлы с таблицами. В соответствии со стандартом FHS, это будет /etc/iptables/, в ней мы будем хранить файлы с правилами, полученными при помощи iptables-save. Перед настройкой правил сначала сбросим содержимое правил по умолчанию:

Теперь посмотрим, что у нас получилось:

У вас должны быть чистые списки правил. Это состояние желательно сохранить на случай необходимости сброса правил.

Детальную настройку правил мы рассматривать не будем, мы сейчас не об этом. После настройки необходимых правил сохраняем их снова в файл. Я предпочитаю включать в название файла дату и время сохранения правил. Во-первых, так понятнее, что когда сохранялось, во-вторых, сортировка при просмотре в файловых менеджерах о именам выстроит список файлов по времени их создания.

Имя получается длинное, но зато при использовании такого шаблона точно можно определить, в какое время этот файл был получен.

Теперь делаем еще одно действие, которое нам позволит не переписывать название файла с правилами для загрузки. Создаем символическую ссылку на файл, в который мы только что сохранили правила. Пусть это будет файл iptables-20130904-223007, тогда делаем так:

И последнее, что надо сделать – изменить файл /etc/network/interfaces, дописав одну строчку. Должно получиться примерно следующее:

И после этого сохраняем.

В общем, вот и всё. Теперь после поднятия интерфейса правила iptables будут загружены автоматически. Какие у этого способа есть минусы? Если кто-нибудь изменит файл /etc/network/interfaces, например, какая-нибудь программа-менеджер сети, то строчка с загрузкой правил может потеряться. Не факт, конечно, но вероятность есть. Второе – если у вас несколько сетевых интерфейсов, то вам надо либо вешать на событие post-up каждого интерфейса, либо точно знать, что выбранный вами интерфейс точно поднимается. Вариация этого способа – размещение скрипта загрузки правил в директории /etc/network/{if-pre-up.d|if-up.d}. В таком случае По соответствующему событию правила будут загружаться автоматически.

Способ 2. Совсем простой способ.

Еще более простой способ, которым многие пользуются – это написать шелл-скрипт загрузки правил и вызывать его из, например, /etc/rc.local или еще из какого-нибудь места при загрузке системы. Минус тут очевиден – для сохранения текущего состояния надо будет править этот самый скрипт, что не есть хорошо и удобно. Предыдущий способ в этом смысле выигрывает.

Способ 3. Самый сложный, но и самый интересный с моей точки зрения.

Третий способ состоит в написании собственного скрипта, делающего вид, что он сервис, и этот сервис будет запускаться при старте системы. Кроме того, мы сможем очищать текущие правила и изменять файл с правилами, который будет загружаться по умолчанию. И для этого всего мы будем использовать только один скрипт. Ну и, конечно же, этот скрипт должен самостоятельно проверять, есть ли у нас необходимые файл и директории и создавать их, если их нет. Но всё по порядку.

Начнем с того, что создадим наш скрипт и поместим его в директорию /etc/init.d, где у нас хранятся скрипты для других сервисов.

Далее в любом удобном вам редакторе редактируем этот файл, вписываем в него следующее:

 

Это наш шаблон скрипта сервиса, который мы с вами сейчас будем доводить до ума.

У нас уже есть обработка параметров и тела всех функций, осталось только написать внутренности этих функций. Начнем со старта, напишем содержимое функции do_start:

Единственная задача этой функции, по идее, — загрузка правил фаервола, но надо также проверить, а существует ли файл, который мы хотим загрузить, и если его не существует, то выдать соответствующее предупреждение. Следующая функция – это отключение фаервола. Смысл ее будет в загрузке пустых правил. Тут мы даже не будем загружать никакого файла, а просто сбросим содержимое цепочек правил и включим разрешительные политики.

После этих действий цепочки iptables будут, но никаких запретов не будет. Следующая функция, которую мы напишем – do_list (). Ее задача – вывести список файлов с правилами. И можно сразу указать, какой из них считается файлом по умолчанию.

Теперь мы можем просмотреть список файлов с правилами и сказать, какой из этих файлов является файлом по умолчанию. Это нам необходимо для того, чтобы в дальнейшем можно было указывать, какой файл с правилами должен быть по умолчанию. Следующая функция – do_makedefault (). Ее задача – сделать некоторый файл с правилами файлом по умолчанию, чтобы он загружался автоматически при старте нашего скрипта. Поскольку файл, который у нас загружается, всегда будет иметь одно и то же название, он всегда будет просто символической ссылкой, а указывать эта ссылка будет на разные файлы. В этой функции у нас будет использоваться еще один параметр скрипта, поэтому добавим значение $2 в вызов функции в структуре case. Должно получиться так:

Итак

В самой функции этот параметр превратится в $1, потому что для скрипта он второй, а для функции – первый. Как вы видите ,мы просто удаляем символическую ссылку с названием iptables.default и делаем новую на тот файл, название которого указано. Указывать надо только имя файла, путь указывать не нужно. А флаг -f мы используем для подавления сообщения об ошибке, если такого файла не существует.

И осталась последняя функция – do_savecurrent (). Она будет тоже выполнять всего одно несложное действие – сохранять текущие правила iptables в файл с включенным в название временем сохранения этих самых правил.

Вот, собственно, сам скрипт почти закончен. Осталось сделать еще одну малость – автоматическое создание директорий, в которых будут храниться правила, если их не существует, и, если файл /etc/iptables/iptables.default не существует, то сбросим правила и политики и создадим файл iptables.clean, после чего создадим символическую ссылку на него с названием iptables.default. Для этого напишем отдельную функцию do_init ():

Эту функцию будем вызывать в самом начале скрипта, еще до выбора выполняемой команды. В итоге у нас получится следующий скрипт:

Осталось теперь включить получившийся скрипт в автозапуск:

Всё. Теперь правила будут загружаться каждый раз после загрузки, после выполнения скрипта networking. Если сеть стартовать при использовании LSBInit не будет, то правила фаервола загружаться тоже не будут. Надеюсь, этот скрипт будет вам полезен. Любые замечания в комментариях приветствуются.