Определение правил
Определение правил
Для создания правил используется опция --append (или -А) программы iptables. После этой опции задается один или несколько критериев, затем указывается опция --jump (или -j), за которой следует действие ACCEPT, DROP или REJECT. Вызов iptables, предназначенный для создания действия, выглядит следующим образом:
# iptables --append CHAIN критерий_выбора --jump действие
Сокращенно та же команда может быть записана так:
# iptables -A CHAIN критерий_выбора -j действие
Вместо --append при вызове iptables могут быть указаны следующие опции.
• --delete, или -D. Эта опция удаляет правило из существующей цепочки.
• --insert, или -I. С помощью данной опции вы можете включить правило в середину цепочки. При этом необходимо задать номер правила. Если номер не указан, iptables включит правило в начало цепочки (при использовании опции --append правило помещается в конец цепочки).
• --replace, или -R. Эта опция дает возможность заменить правило. Задавая данную опцию, следует указать номер заменяемого правила.
• --list, или -L. Данная опция отображает все правила в цепочке.
Для утилиты iptables предусмотрены также другие опции. Информацию о них вы можете получить на страницах справочной системы, посвященных iptables. В следующем разделе рассматривается формирование критериев выбора, передаваемых iptables. В одной команде можно задать несколько критериев, например, вы можете ограничить доступ по номеру порта и по IP-адресу.
На заметку
Ядро системы читает правила в цепочке по порядку и применяет первое из них, которому соответствует пакет. Если вы хотите задать исключение из какого-либо правила (например, запретить доступ к порту Telnet для всех узлов, кроме машин, принадлежащих локальной сети), вы должны поместить исключение перед основным правилом. Политика по умолчанию по сути представляет собой правило, находящееся в самом конце цепочки. Ему удовлетворяют все пакеты, которые не соответствуют ни одному другому правилу в цепочке.
Использование номеров портов при выполнении фильтрации
При выполнении фильтрации пакетов могут анализироваться порты источника и назначения. Например, брандмауэр, находящийся на компьютере, на котором выполняется почтовый сервер, можно настроить для передачи пакетов, в которых указан порт назначения 25. Для этого используется опция --destination-port (--dport). Аналогичных результатов можно добиться, используя опцию --protocol (-p), в качестве значения которой указывается тип протокола (tcp, udp, icmp или all). Опция --source-port (--sport) выполняет подобные действия, но задает порт источника. Команды, определяющие правила фильтрации на основе номеров портов, выглядят следующим образом:
# iptables -A INPUT -р tcp --dport 25 -j ACCEPT
# iptables -A OUTPUT -p tcp --sport 25 -j ACCEPT
Эти команды обеспечивают прием пакетов, направленных серверу, который ожидает поступление запросов через порт 25, и передачу пакетов, возвращаемых сервером в ответ на запрос (в них указан порт источника 25). В результате, даже если политика по умолчанию отвергает пакеты, сервер сможет получить почту от внешних серверов. Заметьте, если в качестве политики по умолчанию указано действие DROP или REJECT вы должны включить в цепочку INPUT правило, разрешающее принимать пакеты, направленные серверу, а в цепочку OUTPUT — правило, разрешающее передавать пакеты, сгенерированные данным сервером. Для этого при определении правила для цепочки INPUT задается опция --destination-port, а при определении правила для цепочки OUTPUT — опция --source-port. Если вы забудете создать одно из правил, то сервер сможет получать запросы, но не сможет генерировать ответы на них, либо, наоборот, через брандмауэр будут пропускаться только данные, сгенерированные сервером, а информация, направленная серверу, будет отвергаться. Для брандмауэра, совмещенного с маршрутизатором, надо также включить в цепочку FORWARD правила, созданные с использованием опций --destination-port и --source-port, в противном случае данные через брандмауэр передаваться не будут. Вы можете использовать в качестве условий номера портов в сочетании с IP-адресами. Это позволит не только ограничить обмен определенным типом протокола, но и разрешить его лишь для отдельных компьютеров. Так, например, вы сможете создать правила, согласно которым взаимодействовать с внешними узлами по протоколу SMTP будет иметь право только почтовый сервер.
Если вы используете политику по умолчанию DROP или REJECT, вам необходимо разрешить клиентским программам взаимодействовать с внешними серверами. Для этого выполните следующие действия.
• Разрешите доступ к серверным портам внешних компьютеров. Соответствующее правило, включаемое в цепочку INPUT, должно создаваться с указанием опции --source-port, а при создании правила, помещаемого в цепочку OUTPUT, должна использоваться опция --destination-port. Для брандмауэра, совмещенного с маршрутизатором, необходимо также включить в цепочку FORWARD правила, созданные с помощью опций --source-port и --destination-port. Возможно, что наряду с номерами портов вам потребуется задать IP-адреса ваших компьютеров. Таким способом вам следует разрешить обращение вовне по каждому из протоколов, которые используются клиентами, выполняемыми в вашей сети.
• Разрешите доступ к непривилегированным портам компьютеров вашей сети. Номера непривилегированных портов лежат в диапазоне 1024-65535. В опциях --source-port и --destination-port указываются границы диапазона, разделенные двоеточием, например --source-port 1024:65535. Для принимаемых пакетов вы можете указать также опцию ! syn. Правилам, в которых указана опция --syn, соответствуют только пакеты, содержащие запросы на установление соединений, а символ ! означает отрицание, т.е. заданному правилу будут удовлетворять только пакеты, которые были переданы серверами в ответ на запросы клиентов.
Использование IP-адресов при выполнении фильтрации
При создании правил могут указываться IP-адреса или блоки IP-адресов. IP-адрес источника задается с помощью опции --source (-s), а IP-адрес назначения — посредством опции --destination (-d). Например, если вы хотите запретить взаимодействие с компьютерами сети 172.24.0.0/16, вам надо создать правила, которые отвергали бы пакеты, переданные из указанной сети, а также пакеты, адресованные компьютерам этой сети. Соответствующие команды имеют следующий вид:
# iptables -A INPUT -s 172.24.0.0/16 -j DROP
# iptables -A OUTPUT -d 172.24.0.0/16 -j DROP
Опции -s и -d часто используются вместе с опциями, определяющими номера портов. Таким образом, вы можете сформировать правила, согласно которым взаимодействовать по сети будут иметь право только определенные компьютеры, обращающиеся по определенным портам. Предположим, например, что вы создаете брандмауэр для защиты локальной сети, но хотите при этом разрешить удаленным пользователям, работающим в сети 10.34.176.0/24, обращаться к серверам SSH локальной сети (серверы SSH ожидают обращения через порт 22). Для этого надо определить следующие команды:
# iptables -A FORWARD -s 10.34.176.0/24 -p tcp
--destination-port 22 -j ALLOW
# iptables -A FORWARD -d 10.34.176.0/24 -p tcp
--source-port 22 -j ALLOW
Поскольку в данном примере модифицируется только цепочка FORWARD, пользователям не предоставляется доступ к серверу SSH компьютера, на котором выполняется брандмауэр (если такой сервер имеется на этой машине). Возможно, вы захотите создать правила, которые разрешали бы обращаться к этому серверу с компьютеров локальной сети. Если адрес вашей локальной сети 192.168.9.0/24, то соответствующие команды будут выглядеть так:
# iptables -A INPUT -s 192.168.9.0/24 -р tcp
--destination-port 22 -j ALLOW
# iptables -A OUTPUT -d 192.168.9.0/24 -p tcp
--source-port 22 -j ALLOW
Использование информации об интерфейсах при выполнении фильтрации
При создании правил фильтрации можно указывать сетевой интерфейс, например ppp0 или eth1. Данный подход в основном используется на компьютерах с несколькими интерфейсами, выполняющих функции маршрутизаторов. Применение в составе правила сведений об интерфейсе позволяет противодействовать фальсификации адресов, в частности, включению в заголовки пакетов, приходящих извне, адресов компьютеров локальной сети. Правила, в которых интерфейс задается с помощью опции --in-interfасе (-i), как правило, помещаются в цепочки INPUT и FORWARD, а правила, создаваемые с использованием опции --out-interface (-о), обычно предназначены для включения в цепочки FORWARD и OUTPUT. Предположим, что адрес вашей локальной сети 192.168.9.0/24, маршрутизатор, совмещенный с брандмауэром, подключен к ней с помощью интерфейса eth1, а соединение маршрутизатора с Internet осуществляется посредством интерфейса eth0. Правила, препятствующие фальсификации адресов, имеют следующий вид:
# iptables -A INPUT -s 192.168.9.0/24 -i eth0 -j DROP
# iptables -A FORWARD -s 192.168.9.0/24 -i eth0 -j DROP
# iptables -A FORWARD -s !192.168.9.0/24 -i eth1 -j DROP
# iptables -A OUTPUT -s !192.168.9.0/24 -i eth1 -j DROP
Первые две команды отвергают поступающие извне (через интерфейс eth0) пакеты, адресованные маршрутизатору или компьютерам локальной сети, в которых указано, что они отправлены из локальной сети. Последние две команды блокируют пакеты, направленные в Internet (поступающие через интерфейс eth1), в которых указан IP-адрес источника, не совпадающий с адресами компьютеров локальной сети.
Проверка пакетов с учетом состояния
Одна из самых новых возможностей фильтрации пакетов, реализованных в системе Linux, позволяет учитывать при проверке пакетов состояние соединения. Средства, рассмотренные ранее в этой главе, позволяли обрабатывать отдельные пакеты, независимо от того, являлись ли они частью соединения или были специально сгенерированы для организации атаки. (Ранее уже встречалась опция --syn, позволяющая определить пакет, содержащий запрос на установление соединения. Существуют средства, которые предоставляют возможность включить свои пакеты в набор пакетов, передаваемых в рамках действующего соединения. Такое включение пакетов называется перехватом TCP- соединения.) Средства проверки пакетов с учетом состояния определяют принадлежность пакетов к текущему соединению, анализируя последовательные номера, IP-адреса, указанные в заголовках, и другие характеристики пакетов. Правила, реализующие такую проверку, позволяют отвергать посторонние пакеты, включенные в состав данных, которые передаются в рамках существующего соединения.
Для включения средств проверки пакетов с учетом состояния используется опция --state, предваряемая опцией -m состояние. Для опции --state можно задать одно или несколько значений. Если вы указываете несколько значений, они должны разделяться запятыми. Символ ! перед опцией --state изменяет ее действие на обратное. Ниже перечислены допустимые параметры опции --state.
• INVALID. Проверка показала, что пакет не принадлежит известному соединению и может оказаться фальсифицированным.
• NEW. Пакет пытается установить новое соединение.
• ESTABLISHED. Пакет соответствует существующему соединению.
• RELATED. Пакет не является частью существующего соединения, но его присутствие допустимо (например, это может быть ICMP-пакет, сообщающий об ошибке).
На заметку
Опция ! --state INVALID эквивалентна опции --state NEW, ESTABLISHED, RELATED.
Рассмотрим пример проверки с учетом состояния. Предположим, что, настраивая брандмауэр на отдельном компьютере, вы задали политику по умолчанию DROP или REJECT, но хотите разрешить взаимодействие с сервером HTTP через порт 80. Вы можете задать поверку с учетом состояния, в ходе которой будут отвергаться пакеты, не предназначенные для установления соединений, не принадлежащие к существующим соединениям и не относящиеся к пакетам, присутствие которых допустимо. Команды, предназначенные для создания правил, имеют следующий вид:
# iptables -A INPUT -m state -p tcp --dport 80
--state NEW,ESTABLISHED,RELATED -j ACCEPT
# iptables -A OUTPUT -m state -p tcp --sport 80
--state ESTABLISHED,RELATED -j ACCEPT
Эти правила включают проверку входящих и исходящих пакетов. Для проверки пакетов, передаваемых с компьютера, значение NEW опции --state не задано, так как новое соединение может устанавливаться только по инициативе клиента. Эти правила препятствуют перехвату существующих соединений с Web-сервером.
На заметку
Проверка пакетов с учетом состояния может осуществляться только в тех системах, в которых используется версия ядра 2.4.x. Предыдущими версиями ядра такая возможность не поддерживается. Это может стать одним из стимулов перехода к использованию iptables.
Использование дополнительных опций
Программа iptables поддерживает большое количество опций, которые могут быть использованы для создания брандмауэров. Например, посредством опции --new-chain (-N) можно создать новую цепочку, указав опцию --fragment (-f), можно создать правило, которое будет применяться ко второму и к последующим фрагментам фрагментированного пакета, а опция --tcp-flags дает возможность организовать проверку на присутствие флагов в составе TCP-пакета. Дополнительную информацию об этих и о других опциях вы можете получить на страницах справочной системы Linux, посвященных iptables.
Сценарий для создания брандмауэра
В завершение разговора о средствах фильтрации пакетов рассмотрим сценарий, который создает брандмауэр. Код сценария представлен в листинге 25.1. Данный сценарий предназначен для компьютера, на котором выполняется Web-сервер и который поддерживает SSH-соединения с компьютерами, подключенными к локальной сети.
Внимание
Сценарии брандмауэров, предназначенные для практического применения, содержат гораздо больший объем кода по сравнению представленным в листинге 25.1. Для удобства чтения в данном листинге при вызове iptables не указывается путь к файлу. В реальных сценариях это недопустимо. Не указывая путь к файлу, вы создаете угрозу безопасности системы. Код, приведенный в листинге 25.1, может послужить основой для создания более сложных сценариев.
Листинг 25.1. Простой сценарий, использующий iptables для создания брандмауэра
#!/bin/sh
iptables -F INPUT
iptables -F OUTPUT
iptables -F FORWARD
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
# Разрешить NDS-трафик
iptables -A INPUT -p udp --sport 53 -j ACCEPT
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
# Разрешить обмен клиентов с локальной сетью
iptables -A INPUT -m state -p tcp --dport 1024:65535
--state ESTABLISHED,RELATED -s 192.168.9.0/24 -j ACCEPT
iptables -A OUTPUT -m state -p tcp --sport 1024:65535
! --state INVALID -d 192.168.9.0/24 -j ACCEPT
# Разрешить все HTTP-соединения
iptables -A INPUT -m state -p tcp --dport 80
! --state INVALID -j ACCEPT
iptables -A OUTPUT -m state -p tcp --sport 80
--state ESTABLISHED, RELATED -j ACCEPT
# Разрешить обращения к SSH-серверу
# из локальной сети (192.168.9.0/24)
iptables -A INPUT -m state -p tcp --dport 22
! --state INVALID 192.168.9.0/24 -j ACCEPT
iptables -A OUTPUT -m state -p tcp --sport 22
--state ESTABLISHED,RELATED -d 192.168.9.0/24 -j ACCEPT
# Разрешить прохождение локального трафика через интерфейс lo
iptables -A INPUT -s 127.0.0.1 -i lo -j ACCEPT
iptables -A OUTPUT -d 127.0.0.1 -o lo -j ACCEPT
Ниже описаны некоторые особенности кода, приведенного в листинге 25.1.
• Удаление существующих правил и установка политики по умолчанию. В первых шести строках программа iptables вызывается для удаления правил, присутствующих в цепочках, и установки политики по умолчанию. В качестве политики по умолчанию задается действие DROP. Несмотря на то что компьютер не выполняет маршрутизацию пакетов, политика по умолчанию задается также и для цепочки FORWARD. Это делается на случай, если на компьютере будет установлен еще один сетевой интерфейс.
• Взаимодействие с сервером DNS. Для того чтобы компьютер мог взаимодействовать с сервером DNS, две строки, следующие за комментариями "Разрешить NDS-трафик", предоставляют компьютеру возможность обращаться к удаленным серверам DNS (UDP-порт 53). Возможности соединения не ограничиваются одним адресом; компьютеру разрешено взаимодействовать с любым сервером имен. Если понадобится, вы можете наложить более жесткие ограничения.
• Обмен с клиентами локальной сети. Строки, следующие за комментариями "Разрешить обмен клиентов с локальной сетью", открывают путь трафику, связанному с непривилегированными портами (1024-65535). В цепочки INPUT и OUTPUT включены правила проверки пакетов с учетом состояния. Заметьте, что правило в цепочке INPUT запрещает установление новых соединений, поэтому, даже если на компьютере будет находиться сервер, принимающий обращения через непривилегированные порты, другие компьютеры не смогут обратиться к нему. Цепочки INPUT и OUTPUT ограничивают взаимодействие компьютерами локальной сети. При создании реального брандмауэра следует рассмотреть возможность замены этих правил более конкретными, которые разрешали бы прохождение данных между непривилегированными локальными портами и портами, используемыми для поддержки отдельных протоколов.
• Трафик, связанный с Web-сервером. Web-сервер, выполняющийся на компьютере, должен принимать обращения от любого узла сети, поэтому в правилах, регламентирующих обмен с Web-сервером, не указывается IP-адрес. Для того чтобы противодействовать перехвату соединения, в этих правилах задана проверка пакетов с учетом состояния.
• Трафик, связанный с сервером SSH. Правила, определяющие взаимодействие с сервером SSH, во многом напоминают правила для Web-сервера, но в них указаны IP-адреса. В результате эти правила разрешают обращение к SSH-серверу только с компьютеров локальной сети.
• Трафик обратной петли. Для решения ряда системных задач, связанных с организацией работы системы, Linux использует интерфейс обратной петли (lo). Правила брандмауэра разрешают передачу данных через этот интерфейс. Проверка пакетов с учетом состояния не выполняется, так как трафик, направленный через интерфейс lo, поступает только по адресу 127.0.0.1.