Настройка автозагрузки правил iptables в Debian

Чем отличается настройка 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 не будет, то правила фаервола загружаться тоже не будут. Надеюсь, этот скрипт будет вам полезен. Любые замечания в комментариях приветствуются.


Понравилась статья?

Подпишитесь на новости сайта и получайте новые статьи на свой почтовый ящик (один раз в неделю).


Настройка автозагрузки правил iptables в Debian: 6 комментариев

  1. Александр

    Спасибо большое за скрипт! =) Очень приятное решение!

    Единственное, изменил «makedefault» на «mkdef», потому что короче и потому что в первый раз опечатался =)

    P.S. Ещё интересно было бы увидеть статью с примером хорошего шаблона правил iptables для «боевых» веб-серверов.

  2. Александр

    Большое спасибо за Ваш труд!

    Теперь понятно с чего начать и как внедрить. Действительно, это даже лучше.

  3. Вася

    Очень хорошая статья.
    Описано что, как и почему работает, а не просто набор команд

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *