Текст книги "Iptables Tutorial 1.1.19"
Автор книги: Oskar Andreasson
Жанр:
ОС и Сети
сообщить о нарушении
Текущая страница: 3 (всего у книги 14 страниц)
4.3. Состояния в пространстве пользователя
Как вы уже наверняка заметили, в пространстве ядра, в зависимости от типа протокола, пакеты могут иметь несколько различных состояний. Однако, вне ядра пакеты могут иметь только 4 состояния. В основном состояние пакета используется критерием –state. Допустимыми являются состояния NEW, ESTABLISHED, RELATED и INVALID. В таблице, приводимой ниже, рассмтриваются каждое из возможных состояний.
Таблица 4-1. Перечень состояний в пространстве пользователя
(Состояние – Описание)
Состояние: NEW
Описание: Признак NEW сообщает о том, что пакет является первым для данного соединения. Это означает, что это первый пакет в данном соединении, который увидел модуль трассировщика. Например если получен SYN пакет являющийся первым пакетом для данного соединения, то он получит статус NEW. Однако, пакет может и не быть SYN пакетом и тем не менее получить статус NEW. Это может породить определенные проблемы в отдельных случаях, но может оказаться и весьма полезным, например когда желательно «подхватить» соединения, «потерянные» другими брандмауэрами или в случаях, когда таймаут соединения уже истек, но само соединение не было закрыто.
Состояние: RELATED
Описание: Состояние RELATED одно из самых «хитрых». Соединение получает статус RELATED если оно связано с другим соединением, имеющим признак ESTABLISHED. Это означает, что соединение получает признак RELATED тогда, когда оно инициировано из уже установленного соединения, имеющего признак ESTABLISHED. Хорошим примером соединения, которое может рассматриваться как RELATED, является соединение FTP-data, которое является связанным с портом FTP control, а так же DCC соединение, запущенное из IRC. Обратите внимание на то, что большинство протоколов TCP и некоторые из протоколов UDP весьма сложны и передают информацию о соединении через область данных TCP или UDP пакетов и поэтому требуют наличия специальных вспомогательных модулей для корректной работы.
Состояние: ESTABLISHED
Описание: Состояние ESTABLISHED говорит о том, что это не первый пакет в соединении. Схема установки состояния ESTABLISHED достаточна проста для понимания. Единственное требование, предъявляемое к соединению, заключается в том, что для перехода в состояние ESTABLISHED необходимо чтобы узел сети передал пакет и получил на него ответ от другого узла (хоста). После получения ответа состояние соединения NEW или RELATEDбудет изаменено на ESTABLISHED.
Состояние: INVALID
Описание: Признак INVALID говорит о том, что пакет не может быть идентифицирован и поэтому не может иметь определенного статуса. Это может происходить по разным причинам, например при нехватке памяти или при получении ICMP–сообщения об ошибке, которое не соответствует какому либо известному соединению. Наверное наилучшим вариантом было бы применение действия DROP к таким пакетам.
Эти четыре состояния могут использоваться в критерии –state. Механизм определения состояния позволяет строить чрезвычайно мощную и эффективную защиту. Раньше приходилось открывать все порты выше 1024, чтобы пропустить обратный трафик в локальную сеть, теперь же, при наличии механизма определения состояния, необходимость в этом отпала, поскольку появилась возможность «открывать» доступ только для обратного (ответного) трафика, пресекая попытки установления соединений извне.
4.4. TCP соединения
В этом и в последующих разделах мы поближе рассмотрим признаки состояний и порядок их обработки каждым из трех базовых протоколов TCP, UDP и ICMP, а так же коснемся случая, когда протокол соединения не может быть классифицирован на принадлежность к трем, вышеуказанным, протоколам. Начнем рассмотрение с протокола TCP, поскольку он имеет множество интереснейших особенностей в отношении механизма определения состояния в iptables.
TCP соединение всегда устанавливается передачей трех пакетов, которые инициализируют и устанавливают соединение, через которое в дальнейшем будут передаваться данные. Сессия начинается с передачи SYN пакета, в ответ на который передается SYN/ACK пакет и подтверждает установление соединения пакет ACK. После этого соединение считается установленным и готовым к передаче данных. Может возникнуть вопрос: «А как же трассируется соединение?». В действительности все довольно просто.
Для всех типов соединений, трассировка проходит практически одинаково. Взгляните на рисунок ниже, где показаны все стадии установления соединения. Как видите, трассировщик, с точки зрения пользователя, фактически не следит за ходом установления соединения. Просто, как только трассировщик «увидел» первый (SYN) пакет, то присваивает ему статус NEW. Как только через трассировщика проходит второй пакет (SYN/ACK), то соединению присваивается статус ESTABLISHED. Почму именно второй пакет? Сейчас разберемся. Строя свой набор правил, вы можете позволить покидать локальную сеть пакетам со статусом NEW и ESTABLISHED, а во входящем трафике пропускать пакеты только со статусом ESTABLISHED и все будет работать прекрасно. И наоборот, если бы трассировщик продолжал считать соединение как NEW, то фактически вам никогда не удалось бы установить соединение с «внешним миром», либо пришлось бы позволить прохождение NEW пакетов в локальную сеть. С точки зрения ядра все выглядит более сложным, поскольку в пространстве ядра TCP соединения имеют ряд промежуточных состояний, недоступных в пространстве пользователя. В общих чертах они соответствуют спецификации RFC 793 – Transmission Control Protocol на странице 21-23. Более подробно эта тема будет рассматриваться чуть ниже.
С точки зрения пользователя все выглядит достаточно просто, однако если посмотреть с точки зрения ядра, то все выглядит несколько сложнее. Рассмотрим порядок изменения состояния соединения в таблице /proc/net/ip_conntrack. После передачи первого пакета SYN.
tcp 6 117 SYN_SENT src=192.168.1.5 dst=192.168.1.35 sport=1031 dport=23 [UNREPLIED] src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 use=1
Как видите, запись в таблице отражает точное состояние соединения – был отмечен факт передачи пакета SYN (флаг SYN_SENT), на который ответа пока не было (флаг [UNREPLIED]). После получения пакета-ответа, соединение переводится в следующее внутреннее состояние:
tcp 6 57 SYN_RECV src=192.168.1.5 dst=192.168.1.35 sport=1031 dport=23 src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 use=1
Теперь запись сообщает о том, что обратно прошел пакет SYN/ACK. На этот раз соединение переводится в состояние SYN_RECV. Это состояние говорит о том, что пакет SYN был благополучно доставлен получателю и в ответ на него пришел пакет-подтверждение (SYN/ACK). Кроме того, механизм определения состояния «увидев» пакеты, следующие в обеих направлениях, снимает флаг [UNREPLIED]. И наконец после передачи заключительного ACK–пакета, в процедуре установления соединения
tcp 6 431999 ESTABLISHED src=192.168.1.5 dst=192.168.1.35 sport=1031 dport=23 src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 use=1
соединение переходит в состояние ESTABLISHED (установленное). После приема нескольких пакетов через это соединение, к нему добавится флаг [ASSURED] (уверенное).
При закрытии, TCP соединение проходит через следующие состояния.
Как видно из рисунка, соединение не закрывается до тех пор пока не будет передан последний пакет ACK. Обратите внимание – эта картинка описывает нормальный процесс закрытия соединения. Кроме того, если соединение отвергается, то оно может быть закрыто передачей пакета RST (сброс). В этом случае соединение будет закрыто по истечение предопределенного времени.
При закрытии, соединение переводится в состояние TIME_WAIT, продолжительность которого по-умолчанию соответствует 2 минутам, в течение которого еще возможно прохождение пакетов через брандмауэр. Это является своего рода «буферным временем», которое дает возможность пройти пакетам, «увязшим» на том или ином маршрутизаторе (роутере).
Если соединение закрывается по получении пакета RST, то оно переводится в состояние CLOSE. Время ожидания до фактического закрытия соединения по-умолчанию устанавливается равным 10 секунд. Подтверждение на пакеты RST не передается и соединение закрывается сразу же. Кроме того имеется ряд других внутренних состояний. В таблице ниже приводится список возможных внутренних состояний соединения и соответствующие им размеры таймаутов.
Таблица 4-2. Internal states
(Состояние – Время ожидания )
NONE – 30 минут
ESTABLISHED – 5 дней
SYN_SENT – 2 минуты
SYN_RECV – 60 секунд
FIN_WAIT – 2 минуты
TIME_WAIT – 2 минуты
CLOSE – 10 секунд
CLOSE_WAIT – 12 часов
LAST_ACK – 30 секунд
LISTEN – 2 минуты
Эти значения могут несколько изменяться от версии к версии ядра, кроме того, они могут быть изменены через интерфейс файловой системы /proc (переменные proc/sys/net/ipv4/netfilter/ip_ct_tcp_*). Значения устанавливаются в сотых долях секунды, так что число 3000 означает 30 секунд.
ПРИМЕЧАНИЕ: Обратите внимание на то, что со стороны пользователя, механизм определения состояния никак не отображает состояние флагов TCP пакетов. Как правило – это не всегда хорошо, поскольку состояние NEW присваивается, не только пакетам SYN.
Это качество трассировщика может быть использовано для избыточного файерволлинга (firewalling), но для случая домашней локальной сети, в которой используется только один брандмауэр это очень плохо. Эта проблема более подробно обсуждается в разделе Пакеты со статусом NEW и со сброшенным битом SYN приложения Общие проблемы и вопросы. Альтернативным вариантом решения этой проблемы может служить установка заплаты tcp-window-tracking из patch-o-matic, которая сделает возможным принятие решений в зависимости от значения TCP window.
4.5. UDP соединения
По сути своей, UDP соединения не имеют признака состояния. Этому имеется несколько причин, основная из них состоит в том, что этот протокол не предусматривает установления и закрытия соединения, но самый большой недостаток – отсутствие информации об очередности поступления пакетов. Приняв две датаграммы UDP, невозможно сказать точно в каком порядке они были отправлены. Однако, даже в этой ситуации все еще возможно определить состояние соединения. Ниже приводится рисунок того, как выглядит установление соединения с точки зрения трассировщика.
Из рисунка видно, что состояние UDP соединения определяется почти так же как и состояние TCP соединения, с точки зрения из пользовательского пространства. Изнутри же это выглядит несколько иначе, хотя во многом похоже. Для начала посмотрим на запись, появившуюся после передачи первого пакета UDP.
udp 17 20 src=192.168.1.2 dst=192.168.1.5 sport=137 dport=1025 [UNREPLIED] src=192.168.1.5 dst=192.168.1.2 sport=1025 dport=137 use=1
Первое, что мы видим – это название протокола (udp) и его номер (см. /etc/protocols прим. перев.). Третье значение – оставшееся «время жизни» записи в секундах. Далее следуют характеристики пакета, прошедшего через брандмауэр – это адреса и порты отправителя и получателя. Здесь же видно, что это первый пакет в сессии (флаг [UNREPLIED]). И завершают запись адреса и порты отправителя и получателя ожидаемого пакета. Таймаут такой записи по умолчанию составляет 30 секунд.
udp 17 170 src=192.168.1.2 dst=192.168.1.5 sport=137 dport=1025 src=192.168.1.5 dst=192.168.1.2 sport=1025 dport=137 use=1
После того как сервер «увидел» ответ на первый пакет, соединение считается ESTABLISHED (установленным), единственное отличие от предыдущей записи состоит в отсутствии флага [UNRREPLIED] и, кроме того, таймаут для записи стал равным 180 секундам. После этого может только добавиться флаг [ASSURED] (уверенное соединение), который был описан выше. Флаг [ASSURED] устанавливается только после прохождения некоторого количества пакетов через соединение.
udp 17 175 src=192.168.1.5 dst=195.22.79.2 sport=1025 dport=53 src=195.22.79.2 dst=192.168.1.5 sport=53 dport=1025 [ASSURED] use=1
Теперь соединение стало «уверенным». Запись в таблице выглядит практически так же как и в предыдущем примере, за исключением флага [ASSURED]. Если в течение 180 секунд через соединение не пройдет хотя бы один пакет, то запись будет удалена из таблицы. Это достаточно маленький промежуток времени, но его вполне достаточно для большинства применений. «Время жизни» отсчитывается от момента прохождения последнего пакета и при появлении нового, время переустанавливается в свое начальное значение, это справедливо и для всех остальных типов внутренних состояний.
4.6. ICMP соединения
ICMP пакеты используются только для передачи управляющих сообщений и не организуют постоянного соединения. Однако, существует 4 типа ICMP пакетов, которые вызывают передачу ответа, поэтому они могут иметь два состояния: NEW и ESTABLISHED. К этим пакетам относятся ICMP Echo Request/Echo Reply, ICMP Timestamp Request/Timestamp Reply, ICMP Information Request/Information Reply и ICMP Address Mask Request/Address Mask Reply. Из них – ICMP Timestamp Request/Timestamp Reply и ICMP Information Request/Information Reply считаются устаревшими и поэтому, в большинстве случаев, могут быть безболезненно сброшены (DROP). Взгляните на рисунок ниже.
Как видно из этого рисунка, сервер выполняет Echo Request (эхо-запрос) к клиенту, который (запрос) распознается брандмауэром как NEW. На этот запрос клиент отвечает пакетом Echo Reply, и теперь пакет распознается как имеющий состояние ESTABLISHED. После прохождения первого пакета (Echo Request) в ip_conntrack появляется запись:
icmp 1 25 src=192.168.1.6 dst=192.168.1.10 type=8 code=0 id=33029 [UNREPLIED] src=192.168.1.10 dst=192.168.1.6 type=0 code=0 id=33029 use=1
Эта запись несколько отличается от записей, свойственных протоколам TCP и UDP, хотя точно так же присутствуют и название протокола и время таймаута и адреса передатчика и приемника, но далее появляются три новых поля – type, code и id. Поле type содержит тип ICMP, поле code – код ICMP. Значения типов и кодов ICMP приводятся в приложении Типы ICMP. И последнее поле id содержит идентификатор пакета. Каждый ICMP–пакет имеет свой идентификатор. Когда приемник, в ответ на ICMP–запрос посылает ответ, он подставляет в пакет ответа этот идентификатор, благодаря чему, передатчик может корректно распознать в ответ на какой запрос пришел ответ.
Следующее поле – флаг [UNREPLIED], который встречался нам ранее. Он означает, что прибыл первый пакет в соединении. Завершается запись характеристиками ожидаемого пакета ответа. Сюда включаются адреса отправителя и получателя. Что касается типа и кода ICMP пакета, то они соответствуют правильным значениям ожидаемого пакета ICMP Echo Reply. Идентификатор пакета-ответа тот же, что и в пакете запроса.
Пакет ответа распознается уже как ESTABLISHED. Однако, мы знаем, что после передачи пакета ответа, через это соединение уже ничего не ожидается, поэтому после прохождения ответа через netfilter, запись в таблице трассировщика уничтожается.
В любом случае запрос рассматривается как NEW, а ответ как ESTABLISHED.
ПРИМЕЧАНИЕ: Заметьте при этом, что пакет ответа должен совпадать по своим характеристикам (адреса отправителя и получателя, тип, код и идентификатор) с указанными в записи в таблице трассировщика, это справедливо и для всех остальных типов трафика.
ICMP запросы имеют таймаут, по-умолчанию, 30 секунд. Этого времени, в большинстве случаев, вполне достаточно. Время таймаута можно изменить в /proc/sys/net/ipv4/netfilter/ip_ct_icmp_timeout. ( Напоминаю, что переменные типа /proc/sys/net/ipv4/netfilter/ip_ct_* становятся доступны только после установки «заплаты» tcp-window-tracking из patch-o-matic прим. перев.).
Значительная часть ICMP используется для передачи сообщений о том, что происходит с тем или иным UDP или TCP соединением. Всвязи с этим они очень часто распознаются как связанные (RELATED) с существующим соединением. Простым примером могут служить сообщения ICMP Host Unreachable или ICMP Network Unreachable. Они всегда порождаются при попытке соединиться с узлом сети когда этот узел или сеть недоступны, в этом случае последний маршрутизатор вернет соответствующий ICMP пакет, который будет распознан как RELATED. На рисунке ниже показано как это происходит.
В этом примере некоторому узлу передается запрос на соединение (SYN пакет). Он приобретает статус NEW на брандмауэре. Однако, в этот момент времени, сеть оказывается недоступной, поэтому роутер возвращает пакет ICMP Network Unreachable. Трассировщик соединений распознает этот пакет как RELATED, благодаря уже имеющейся записи в таблице, так что пакет благополучно будет передан клиенту, который затем оборвет неудачное соединение. Тем временем, брандмауэр уничтожит запись в таблице, поскольку для данного соединения было получено сообщение об ошибке.
То же самое происходит и с UDP соединениями – если обнаруживаются подобные проблемы. Все сообщения ICMP, передаваемые в ответ на UDP соединение, рассматриваются как RELATED. Взгляните на следующий рисунок.
Датаграмма UDP передается на сервер. Соединению присваивается статус NEW. Однако доступ к сети запрещен (брандмауэром или роутером), поэтому обратно возвращается сообщение ICMP Network Prohibited. Брандмауэр распознает это сообщение как связанное с открытым UDP соединением, присваивает ему статус RELATED и передает клиенту. После чего запись в таблице трассировщика уничтожается, а клиент благополучно обрывает соединение.
4.7. Поведение по-умолчанию
В некоторых случаях механизм определения состояния не может распознать протокол обмена и, соответственно, не может выбрать стратегию обработки этого соединения. В этом случае он переходит к заданному по-умолчанию поведению. Поведение по-умолчанию используется, например при обслуживании протоколов NETBLT, MUX и EGP. Поведение по-молчанию во многом схоже с трассировкой UDP соединений. Первому пакету присваивается статус NEW, а всем последующим – статус ESTABLISHED.
При использовании поведения по-умолчанию, для всех пакетов используется одно и то же значение таймаута, которое можно изменить в /proc/sys/net/ipv4/netfilter/ip_ct_generic_timeout. По-умолчанию это значение равно 600 секундам, или 10 минутам В зависимости от типа трафика, это время может меняться, особенно когда соединение устанавливается по спутниковому каналу.
4.8. Трассировка комплексных протоколов
Имеется ряд комплексных протоколов, корректная трассировка которых более сложна. Прмером могут служить протоколы ICQ, IRC и FTP. Каждый из этих протоколов несет дополнительную информацию о соединении в области данных пакета. Соответственно корректная трассировка таких соединений требует подключения дополнительных вспомогательных модулей.
В качестве первого примера рассмотрим протокол FTP. Протокол FTP сначала открывает одиночное соединение, которое называется «сеансом управления FTP» (FTP control session). При выполнении команд в пределах этого сеанса, для передачи сопутствующих данных открываются дополнительные порты. Эти соединения могут быть активными или пассивными. При создании активного соединения клент передает FTP серверу номер порта и IP адрес для соединения. Затем клент открывает порт, сервер подключает к заданному порту клиента свой порт с номером 20 (известный как FTP-Data) и передает данные через установленное соединение.
Проблема состоит в том, что брандмауэр ничего не знает об этих дополнительных подключениях, поскольку вся информация о них передается через область данных пакета. Из-за этого брандмауэр не позволит серверу соединиться с указанным портом клиента.
Решение проблемы состоит в добавлении специального вспомогательного модуля трассировки, который отслеживает, специфичную для данного протокола, информацию в области данных пакетов, передаваемых в рамках сеанса управления. При создании такого соединения, вспомогательный модуль корректно воспримет передаваемую информацию и создаст соответствующую запись в таблице трассировщика со статусом RELATED, благодаря чему соединение будет установлено. Рисунок ниже поясняет порядок выполнения подобного соединения.
Пассивный FTP действует противоположным образом. Клиент посылает запрос серверу на получение данных, а сервер возвращает клиенту IP адрес и номер порта для подключения. Клиент подключает свой 20-й порт (FTP-data) к указанному порту сервера и получает запрошенные данные. Если ваш FTP сервер находится за брандмауэром, то вам потребуется этот вспомогательный модуль для того, чтобы сервер смог обслуживать клиентов из Интернет. То же самое касается случая, когда вы хотите ограничить своих пользователей только возможностью подключения к HTTP и FTP серверам в Интернет и закрыть все остальные порты. Рисунок ниже показывает как выполняется пассивное соединение FTP.
Некоторые вспомогательные модули уже включены в состав ядра. Если быть более точным, то в состав ядра включены вспомогательные модули для протоколов FTP и IRC. Если в вашем распоряжении нет необходимого вспомогательного модуля, то вам следует обратиться к patch-o-matic, который содержит большое количество вспомогательных модулей для трассировки таких протоколов, как ntalk или H.323. Если и здесь вы не нашли то, что вам нужно, то у вас есть еще варианты: вы можете обратиться к CVS iptables, если искомый вспомогательный модуль еще не был включен в patch-o-matic, либо можете войти в контакт с разработчиками netfilter и узнать у них – имеется ли подобный модуль и планируется ли он к выпуску. Если и тут вы потерпели неудачу, то наверное вам следует прочитать Rusty Russell's Unreliable Netfilter Hacking HOW-TO.
Вспомогательные модули могут быть скомпилированы как в виде подгружаемых модулей ядра, так и статически связаны с ядром. Если они скомпилированы как модули, то вы можете загрузить их командой:
modprobe ip_conntrack_*
Обратите внимание на то, что механизм определения состояния не имеет никакого отношения к трансляции сетевых адресов (NAT), поэтому вам может потребоваться большее количество дополнительных модулей, если вы выполняете такую трансляцию. Допустим, что вы выполняете трансляцию адресов и трассировку FTP соединений, тогда вам необходим так же и соответствующий вспомогательный модуль NAT. Имена вспомогательных модулей NAT начинаются с ip_nat_, в соответствии с соглашением об именах. В данном случае модуль называется ip_nat_ftp. Для протокола IRC такой модуль будет называться ip_nat_irc. Тому же самому соглашению следуют и названия вспомогательных модулей трассировщика, например: ip_conntrack_ftp и ip_conntrack_irc.