Всем хорош iptables, да только синтаксис правил у него достаточно неочевидный (куча всяческих опций и прочее). Сейчас, конечно, появился его потомок, nftables, но пока что он не очень распространен и поддерживает не все возможности предшественника. Для iptables же за время его существования было создано немало фронтендов и конфигураторов, один из которых, Shorewall, мы и рассмотрим.

 

Введение

Разработка Shorewall началась, когда автор осознал негибкость предыдущего варианта фронтенда, Seawall, который сам же разработал в 1999-м. Возможности Shorewall весьма широки:

  • поддержка и автоматическое определение доступных особенностей Netfilter/iptables. Это крайне полезно, поскольку его версии могут разниться от дистрибутива к дистрибутиву;
  • деление сетей на зоны. При этом как несколько сетевых интерфейсов могут соответствовать одной зоне, так и один интерфейс может соответствовать нескольким зонам. Есть также поддержка вложенных и пересекающихся зон;
  • поддержка всевозможных видов NAT;
  • возможность простого использования на одном брандмауэре/роутере нескольких провайдеров;
  • централизованное управление несколькими брандмауэрами с установленным Shorewall Lite;
  • возможность написания собственных расширений, если основной функциональности почему-либо окажется недостаточно,
    и многие другие.

На данный момент в репозиториях Ubuntu 15.04 имеется версия 4.6.4, которую мы и рассмотрим.

 

Установка и архитектура

Перед установкой стоит удалить ufw — стандартный фронтенд iptables в Ubuntu, а уже потом устанавливать Shorewall. Для этого набираем следующие команды:

$ sudo apt-get remove ufw
$ sudo apt-get install shorewall

Установка Shorewall
Установка Shorewall

Перед настройкой стоит описать его архитектуру. У Shorewall есть шесть пакетов: Shorewall Core, Shorewall/Shorewall6, Shorewall-lite/Shorewall6-lite и Shorewall-init. Первый пакет используется всеми остальными, вторые два предоставляют Shorewall для IPv4/IPv6 соответственно, следующие два предлагают версию, которую нужно устанавливать на брандмауэрах при непосредственном управлении ими, и, наконец, последний предоставляет некоторые возможности для upstart. Мы будем говорить только о собственно Shorewall.

Shorewall, в свою очередь, состоит из нескольких компонентов. Рассмотрим их подробнее.

/sbin/shorewall — утилита для администрирования, через которую и выполняется всяческое обслуживание, включая загрузку правил при запуске системы. На самом деле это shell-скрипт.

В каталоге /usr/share/shorewall/ лежат уже основные компоненты Shorewall:

  • compiler.pl — «сердце» Shorewall, скрипт на Perl, который и компилирует правила Shorewall в правила iptables; когда-то была альтернативная версия Shorewall, целиком написанная на Shell, но от нее отказались из-за проблем с быстродействием;
  • action.template — шаблон для создания действий. «Действия» — некий набор правил для iptables, который, в свою очередь, тоже можно представить как шаблон. Для знакомых с iptables это можно выразить проще — цепочка (chain) в таблице filter;
  • action.* — файлы, содержащие стандартные действия;
  • actions.std — файл, содержащий список стандартных действий;
  • configfiles/ — каталог, содержащий файл для создания каталога экспорта в Shorewall-lite;
  • configpath — файл, содержащий дистрибутивоспецифичные пути;
  • firewall — shell-скрипт, обрабатывающий команды add и delete, предназначенные для добавления хостов и подсетей в динамические зоны, которые, как правило, применяются при создании VPN, и удаления их. Также этот скрипт обрабатывает команды stop и clear, когда в системе нет текущего скомпилированного набора правил;
  • functions — символическая ссылка на lib.base, предназначенная для сохранения совместимости со старыми версиями Shorewall;
  • init — символическая ссылка на init-скрипт;
  • lib.* — библиотеки функций, используемые в shell-скриптах;
  • macro.* — стандартные макросы для Shorewall. Макросы позволяют задавать имена для наборов из одного или нескольких правил iptables;
  • modules и modules.* — файлы, управляющие загрузкой модулей. Причем если первый оперирует сразу группами модулей и его можно переопределить, скопировав в каталог конфигов, то остальные эти группы определяют, и их трогать не нужно;
  • prog.* — фрагменты shell-скриптов, использующиеся в качестве входных данных для компилятора правил;
  • Shorewall/ — каталог, содержащий модули Perl, используемые этим компилятором;
  • version — файл, содержащий сведения о текущей версии Shorewall;
  • wait4ifup — Shell-скрипт, который может использоваться скриптами расширения для ожидания доступности какого-либо интерфейса.
Файл actions.std
Файл actions.std
compiler.pl — сам компилятор, который и генерирует правила Netfilter
compiler.pl — сам компилятор, который и генерирует правила Netfilter

В каталоге /etc/shorewall лежат файлы конфигурации для IPv4-версии фронтенда.

/var/lib/shorewall используется для хранения информации о состоянии. Там могут находиться, например, файлы:

  • .iptables-restore-input — файл, передаваемый в iptables-restore и предназначенный для ускорения восстановления правил при запуске/перезапуске и для отладки;
  • .modules — список модулей, использовавшихся при последнем запуске/перезапуске;
  • restore — скрипт, используемый при выполнении команды shorewall restore;
  • .restore — опять же скрипт, использовавшийся во время последнего удачного выполнения команд shorewall start, shorewall restart или shorewall refresh;
  • save — создается по команде shorewall save и служит для восстановления динамического черного списка после запуска/перезапуска;
  • state — записывается состояние брандмауэра.

Посмотрим вкратце, как все это работает, на примере. При компиляции (shorewall compile) вызывается скрипт /sbin/shorewall, подключающий библиотеку функций lib.cli и вызывающий функцию shorewall_cli, которая парсит аргументы. Затем в данной функции из lib.cli-std вызывается функция compile_command, также парсящая аргументы (уже свои), и в итоге она выполняет очередную функцию — compiler. В конечном счете вызывается скрипт на Perl, в свою очередь компилирующий shell-скрипт, выполняемый уже другой командой (к примеру, shorewall start).

При запуске указанной выше команды первый этап парсинга выполняется аналогично. Затем вызывается функция get_config из файла lib.cli-std, устанавливающая переменные, получаемые из файла конфигурации. Следом выполняется функция start_command, которая, в свою очередь, вызывает функцию run_it, уже и выполняющую скомпилированный из набора правил скрипт.

Стоит заметить, что Shorewall жестко привязан к суперпользователю (в скриптах зашиты проверки на UID = 0), так что при использовании Capabilities администраторы оказываются в пролете.

Посмотрим, как данный фронтенд настраивать, в том числе синтаксис правил.

 

Конфигурирование Shorewall

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

/etc/shorewall/shorewall.conf — файл, управляющий глобальными настройками Shorewall. Посмотрим некоторые его интересные места:

# Допускается ли запуск Shorewall?
STARTUP_ENABLED=Yes
# Вывод сообщений при запуске. 0 — вообще не выводить, 1 — выводить только важные сообщения, 2 — максимальный уровень
VERBOSITY=1
# <...>
# Логирование «марсианских пакетов» (адреса источника/назначения которых зарезервированы) на всех интерфейсах. Даже если его здесь отключить, всегда можно включить для конкретного интерфейса. Может принимать значения Yes, No и Keep — оставить как есть
LOG_MARTIANS=Yes
# Уровень логирования поведения при запуске в файл, указанный в параметре STARTUP_LOG? -1 — отключено, 0 — только ошибки, 1 — логировать основные сообщения, 2 — логировать все
LOG_VERBOSITY=2
# Местонахождение лог-файла, который команды для просмотра информации (такие как shorewall dump или shorewall show log) будут обрабатывать
# <...>
# Файл лога запуска
STARTUP_LOG=/var/log/shorewall-init.log
# <...>
# Следующие строки описывают действия по умолчанию для политик. Эти действия применяются до применения к соединению основных политик. Список встроенных действий можно получить в файле /usr/share/shorewall/actions.std
ACCEPT_DEFAULT=none
DROP_DEFAULT=Drop
NFQUEUE_DEFAULT=none
QUEUE_DEFAULT=none
REJECT_DEFAULT=Reject
# <...>
# Поддержка учета трафика
ACCOUNTING=Yes
# Таблица для учета. Возможно использовать либо filter, либо mangle
ACCOUNTING_TABLE=filter
# Автоматически связывать хелперы с приложениями. Начиная с ядра 3.5 их, однако, рекомендуется включать вручную
AUTOHELPERS=Yes
# Файлы с именами, как у цепочек, интерпретируются как скрипты. Это было необходимо до появления возможности inline-вставок BEGIN PERL...END PERL в файлах конфигурации, сейчас же опционально
CHAIN_SCRIPtS=Yes
# <...>
# Использование таблицы MANGLE при генерации правил
MANGLE_ENABLED=Yes
# <...>
# Оптимизация генерируемых правил. Тут допустимы категории 0, 1, 2, 4, 8 и 16, их комбинации, достигаемые обычным сложением, а также значения All и None (последнее аналогично нулевой категории). В частности, категория 2 означает, что все правила ACCEPT будут объединяться в одну цепочку. Остальные оптимизации более сложны
OPTIMIZE=0
# <...>

/etc/shorewall/zones описывает сетевые зоны, представляет собой таблицу. Кратко расскажем про ее столбцы и приведем пример.

Столбец ZONE определяет имя зоны. Имя должно начинаться с буквы, может содержать буквы, цифры и подчеркивания и, при формате логирования по умолчанию, быть не более шести символов. Имена all, any, none, DEST и SOURCE зарезервированы. Порядок, в котором Shorewall определяет соответствие пакетов зонам, соответствует порядку определения зон. Допустимо также определение вложенных зон, но это выходит за рамки данной статьи.

Столбец TYPE определяет тип зоны и может быть одним из следующих:

  • ipv4 — стандартный тип, если в данном столбце ничего не задано или стоит прочерк, то применяется по умолчанию. Соединение с некоторыми хостами зоны может быть зашифрованным.
  • ipsec или ipsec4 — соединение со всеми компьютерами зоны шифровано.
  • firewall — описывает собственно зону брандмауэра.

Есть еще и другие типы, но смысла рассматривать их нет.

OPTIONS, IN OPTIONS и OUT OPTIONS — определяют опции (в основном относящиеся к IPSec, например proto указывает протокол инкапсуляции) для двунаправленного, входящего и исходящего трафика соответственно.

Пример файла:

#ZONE   TYPE        OPTIONS     IN OPTIONS      OUT OPTIONS
fw      firewall
net     ipv4

Файл /etc/shorewall/interfaces содержит описание сетевых интерфейсов, которые могут использоваться в Shorewall, и сопоставляет их с зонами. Существует два формата данного файла — со столбцом BROADCAST, используемым для предоставления интерфейсу широковещательного адреса, и без него. Формат без данного столбца задается строкой ?FORMAT 2. Перечислим вкратце доступные столбцы:

  • ZONE — указывается зона, присутствующая в файле zones;
  • INTERFACE — логическое имя интерфейса; каждый интерфейс может быть указан в данном файле только один раз. Виртуальные интерфейсы указывать нельзя. Допустимо использовать и символы подстановки — например, ppp+ соответствует и ppp0, и ppp5, но не ppp;
  • OPTIONS — список различных опций, разделенных запятыми. К примеру, опция dhcp используется чаще всего для указания того, что интерфейс получает адрес по DHCP, а опция net предоставляет возможность ограничить список подсетей для конкретной зоны.

Пример файла interfaces:

?FORMAT 2
#ZONE       INTERFACE       OPTIONS
-           lo              ignore
net         all             dhcp,physical=+,routeback

Файл /etc/shorewall/policy определяет общие политики для соединений между зонами, если пакет или соединение не соответствует ни одному правилу. Порядок строк в этом файле имеет значение. Посмотрим, какие в этом файле столбцы:

  • SOURCE — источник. Может быть именем зоны, $FW (самим брандмауэром), all и all+ — последнее значение переопределяет внутризоновую политику;
  • DEST — назначение. Значения аналогичны SOURCE;
  • POLICY — политика. Тут используются те самые значения, которые были указаны в файле shorewall.conf. Через двоеточие можно задать конкретное действие из списка действий /usr/share/shorewall/actions.std или макрос. Если стоит NONE, над пакетом не будет произведено никакое действие. Нужно отметить, что NONE не может использоваться, если в качестве источника/назначения указан $FW или all;
  • LOG LEVEL — позволяет определить уровень логирования для соединений, соответствующих данной политике. Может быть от debug до emerg, плюс возможно указывать ULOG иди NFLOG для направления логов в соответствующий демон;
  • BURST:LIMIT — позволяет задать ограничения на количество соединений за единицу времени как для адреса источника, так и для адреса назначения.

Пример:

#SOURCE DEST    POLICY  LOG LEVEL   BURST:LIMIT
$FW     net     ACCEPT
net     all     DROP

Тут разрешаются все исходящие соединения от компьютера брандмауэра в зону net и запрещаются все соединения, приходящие из данной зоны.

Наконец, файл /etc/shorewall/rules содержит собственно правила. Этот файл делится еще и на секции. Рассмотрим их. В cекции ALL задаются правила, которые будут применяться независимо от состояния соединения для пакета. Для создания правил на пакеты с учетом состояний ESTABLISHED и RELATED предназначены секции ESTABLISHED и RELATED соответственно. В качестве действий для них допустимы лишь ACCEPT, DROP, REJECT, LOG и QUEUE. Правила для пакетов в состоянии INVALID задаются в секции с соответствующим именем. Доступные действия аналогичны тем же, что описывались чуть выше. UNTRACKED применяется для тех пакетов, чье состояние нельзя отследить. Доступные действия опять же идентичны предыдущим.

В секции NEW указываются правила не только для пакетов с соответствующим состоянием. Правила, указанные в ней, применяются и для пакетов с состояниями INVALID и UNTRACKED, если они отсутствуют в нужных секциях. Также, если в файле не указана ни одна секция, подразумевается, что есть только описываемая. Имена столбцов в данном случае говорят сами за себя или аналогичны тем, что были описаны ранее, поэтому их рассматривать не будем, а приведем сразу пример:

#ACTION         SOURCE      DEST        PROTO       DEST PORT       SOURCE PORT(S)
?SECTION ALL
?SECTION ESTABLISHED
?SECTION RELATED
?SECTION INVALID
?SECTION UNTRACKED
?SECTION NEW
Invalid(DROP)   net         $FW         tcp
SSH(ACCEPT)     net         $FW
Ping(ACCEPT)    net         $FW

Возможно, этот пример покажется удивительным, но на самом деле действия, указанные в нем, либо соответствуют одному из действий в файле action.std (как в случае с действием Invalid(DROP), запрещающим пакеты в состоянии Invalid), либо являются макросами, как в случае с SSH(ACCEPT) и Ping(ACCEPT), разрешающими, соответственно, SSH и Ping. Во всех правилах в данном примере в качестве источника указывается зона net, а в качестве назначения сам компьютер с брандмауэром.

Nftables

Nftables представляет собой нечто аналогичное bpf: утилита nft компилирует правила в байт-код и передает его в ядро. Это позволяет не только значительно улучшить гибкость, но и уменьшить количество кода ядра. Так, отпадает надобность в реализации расширений режима ядра для поддержки всякого вновь появляющегося протокола. В качестве же базовых «кирпичиков» выступают элементы старого доброго Netfilter, такие как хуки.

Синтаксис утилиты nft, однако, отличается от синтаксиса старых утилит и представляет собой иерархический язык, более подходящий для описания правил, нежели линейный стиль iptables. Парсер для этого языка сгенерирован с помощью BISON.

 

Shorewall на ноутбуке

Модифицируем базовый пример для ноутбука. Для простоты предположим, что дома ноутбук подключен кабелем к локальной сети и владелец его считает эту сеть доверенной, а «на выезде» он пользуется беспроводной сетью, которая, понятно, недоверенная.

Определим зоны home и wifi, для чего в файл zones добавляем строчки:

home    ipv4
wifi    ipv4

Затем добавляем зоны в файл interfaces:

home    eth0    dhcp
wifi    wlan0   dhcp

И настраиваем политики (предварительно закомментировав уже существующие):

$FW     home    ACCEPT
home    $FW     ACCEPT
$FW     wifi    ACCEPT
wifi    $FW     DROP

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

Invalid(DROP)    home   $FW    tcp
Ping(ACCEPT)     wifi   $FW

Проверяем, компилируем и запускаем:

# shorewall check
# shorewall compile && shorewall start
Проверка конфигов
Проверка конфигов
Компиляция правил и запуск Shorewall
Компиляция правил и запуск Shorewall

Все, ноутбук защищен.

 

Заключение

Shorewall остается очень мощным инструментом даже сейчас, с появлением nftables. Оно, впрочем, неудивительно, поскольку это более высокоуровневый инструмент. Конфигурировать его тоже легче, что мы и увидели из примеров. Но как Shorewall можно сравнить с языком высокого уровня, так и iptables можно сравнить с ассемблером — а, как известно, в некоторых случаях (хотя и далеко не во всех) код на ассемблере, написанный человеком, более быстрый, нежели сгенерированный машиной.

Сгенерированные Shorewall правила iptables
Сгенерированные Shorewall правила iptables
Часть вывода команды shorewall dump. Виден список возможностей нижнего уровня
Часть вывода команды shorewall dump. Виден список возможностей нижнего уровня

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

Таким образом, Shorewall подходит очень большому кругу пользователей. Скорее всего, подойдет он и тебе.

3 комментария

  1. Аватар

    itjunky

    30.12.2015 в 17:16

    «Всем хорош iptables, да только синтаксис правил у него достаточно неочевидный»
    А вот конфигурить стопицот конфигов типа сильно более очевидно, да у меня мозг впал в бесконечный цикл ещё на описании последовательности того как эта балалайка запускается, а когда я дошёл до слов:

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

    Так вообще статью читать перехотелось…

  2. Аватар

    l0l1t4

    11.01.2016 в 02:44

    После установки shorewall

    /etc/shorewall$ ls
    conntrack params shorewall.conf

    файлы конфигурации находятся в другом месте

    /usr/share/shorewall/configfiles$ ls
    accounting init params.annotated scfilter tcfilters
    accounting.annotated initdone policy secmarks tcfilters.annotated
    actions interfaces policy.annotated secmarks.annotated tcinterfaces
    actions.annotated interfaces.annotated providers shorewall.conf tcinterfaces.annotated
    arprules isusable providers.annotated shorewall.conf.annotated tcpri
    arprules.annotated lib.private proxyarp start tcpri.annotated
    blrules maclist proxyarp.annotated started tcrules
    blrules.annotated maclist.annotated refresh stop tcrules.annotated
    clear Makefile refreshed stopped tos
    conntrack masq restored stoppedrules tos.annotated
    conntrack.annotated masq.annotated routes stoppedrules.annotated tunnels
    ecn nat routes.annotated tcclasses tunnels.annotated
    ecn.annotated nat.annotated rtrules tcclasses.annotated zones
    findgw netmap rtrules.annotated tcclear zones.annotated
    hosts netmap.annotated rules tcdevices
    hosts.annotated params rules.annotated tcdevices.annotated

  3. Аватар

    andrewbutov

    13.02.2017 в 02:31

    Для тех кто хочет удалить это чудо инженерной мысли, для начала выполните очищение
    shorewall clear

    И только после этого уже удаляйте
    udo apt-get purge shorewall

Оставить мнение