Pull to refresh

Конфигурирование iptables при помощи ferm

Reading time 4 min
Views 18K
Ferm — это низкоуровневая надстройка над iptables, позволяющая организовывать своего рода циклы по спискам параметров iptables. Это оказывается особенно полезно при настройке сложных правил файрвола, для написания которых с использованием одного только iptables приходится повторять до умопомрачения -t filter -A INPUT -p tcp --state NEW ..., потом делать аналогичное для -p udp, в общем кто плавал — знает.

Ferm прекрасен тем, что, сохраняя всю гибкость iptables, позволяет добиваться тех же эффектов меньшими усилиями. Так, например, разрешить новые соединения на порты ftp, ssh и http и запретить все остальное (кроме связанных), можно написать вот такой конфиг:
chain INPUT {
policy DROP;
mod state state (RELATED ESTABLISHED) ACCEPT;
proto tcp dport (http ftp ssh) ACCEPT;
}


Удивительно дело, поиск дает по запросу ferm только одну статью, которая к собственно ferm никакого отношения не имеет. То ли все уже все знают и всем очевидно, то ли наоборот. Исходя из последнего, я решил написать этот топик.



Зачем же это нужно?


Для простых случаев — не нужно совершенно. Но вот у меня есть, например, софтверный роутер с двумя аплинками. Конфигурация файрвола состоит из 102 правил. Многие из них повторяются с разницей в один параметр. Если, не дай Бог, я захочу что-нибудь в нем поменять — меня ждет боль в глазах и по крайней мере минут 20 попыток вспомнить, что, где и как. Согласитесь, неприятно.

Ferm в данном случае спасает не только более читабельным, но и несколько более компактным синтаксисом. Например, на том же сервере ferm.conf (за вычетом комментариев и пустых строк) он составляет 84 строчки, конфигурируя при этом еще и ip6tables. Каждая индивидуальная сточка при этом короче. 8960 символов iptables против 2998 символов ferm.

Учитывая, что при использовании ferm не налагается практически никаких ограничений на возможности iptables, выигрыш налицо.

Кроме прочего, ferm предлагает достаточно продвинутые возможности для написания скриптовых правил, в т.ч. вызов внешних программ и условные операторы. Но это уже немного выходит за рамки топика.

Как это работает?


Ferm представляет из себя, если смотреть в корень, perl-скрипт, конвертирующий формат ferm-конфига в вызовы iptables (или формат iptables-save/restore). Соответственно, работает оно очень просто: читает конфиг в заранее заданных соглашениях и вызывает iptables с соответствующими параметрами. В общем, никакой особой магии не присутствует.

Формат конфига (вкратце)

В общем и целом, конфиг представляет из себя перечисление списков в форме, слегка напоминающей C. Разделитель инструкций — точка с запятой. Вложенные списки организуются посредством фигурных скобок. Простое перечисление — круглых. Пока непонятно? Рассмотрим пример.

Допустим, у нас есть правило iptables
iptables --protocol tcp -j ACCEPT
В ferm оно будет транслироваться как
protocol tcp ACCEPT;
Переносы строк здесь не важны, важна только точка с запятой.

Таблица и цепочка в данном случае по умолчанию (-t filter -A INPUT).

Определение таблицы и цепочки производится с помощью ключевых слов table и chain. Например,
table nat chain PREROUTING protocol tcp dport 12345 DNAT to 1.2.3.4;

В общем, правило состоит из места (table, chain), собственно правила (protocol tcp, dport 12345) и действия (DNAT to 1.2.3.4). На само правило налагаются те же ограничения, что и при использовании «чистого» iptables. Здесь table, chain, protocol, dport и DNAT являются ключевыми словами. То, что идет после них — параметры.

Теперь добавим немного магии. В качестве параметров для ключевых слов можно указывать не только собственно значения, но и списки значений (или функции, или переменные, но это опять выходит за рамки топика):
table nat chain PREROUTING protocol (tcp udp) dport (12345 54321) DNAT to 1.2.3.4;

И теперь еще немного магии — поскольку не всего можно добиться списками параметров, можно определить список ключевых слов:
table nat chain PREROUTING { protocol tcp dport 12345 DNAT to 1.2.3.4; protocol udp dport 54321 DNAT to 1.2.3.4; }

С чего начать?


Если мне удалось Вас заинтересовать, то цель топика выполнена. Начать можно с сайта проекта: ferm.foo-projects.org
В Debian, Gentoo и Fedora ferm ставится из репозитариев.

Стоит почитать man ferm, он очень подробный, что является несомненным плюсом.

Стоит посмотреть примеры (у меня они легли в /usr/share/doc/ferm-*/examples, у вас может быть иначе)

Помимо прочего, есть еще две вещи, о которых стоит знать: импорт существующей конфигурации и параметры командной строки.

Импорт

ferm поставляется с утилитой import-ferm, которая берет вывод iptables-save и записывает его вывод в формате ferm. Если этой утилите подать что-нибудь на стандартный ввод, то она интерпретирует это что-нибудь как вывод iptables-save, и не будет ничего вызывать. Если не подавать — то сама вызовет iptables-save.

На стандартном выводе получим ferm-конфиг, который в последствии можно загрузить обратно. В общем все очень дружелюбно.

Параметры командной строки

Которые могут очень пригодиться.
--noexec
Не вызывает iptables. Имеет смысл вместе с --lines
--lines
Показывает сгенерированный конфиг iptables (и выполняет его! чтобы просто посмотреть, используйте с --noexec)
--interactive
Применяет конфиг и спрашивает ввода пользователя. При отсутствии ввода в течение 30 секунд, возвращает старые настройки. ОЧЕНЬ полезно при редактировании правил на удаленной машине в три часа ночи :)
--fast / --slow
Первое включает режим работы через iptables-restore, второе — режим работы через вызов iptables. С версии 2.0 по умолчанию используется fast, соответственно до — slow. Есть некоторые оговорки касательно экранируемых символов в iptables-restore, поэтому в редких случаях --slow может быть стабильнее. --slow --lines будет выводить строчку непосредственно перед вызовом, что крайне удобно для отладки.

Ну и обязательным параметром идет путь к конфиг-файлу.

Остальные описаны в мануале.

P.S.



Если тема интересна, я могу углубляться дальше в формат конфига ferm. Однако надо иметь ввиду, что это будет в значительной степени вольный перевод/пересказ man ferm и примеров.
Tags:
Hubs:
+45
Comments 18
Comments Comments 18

Articles