В обязанности любого администратора, отвечающего за соединение с интернетом, входит обеспечение безопасности этого доступа. Как правило, на маршрутизаторе настраивается фильтр пакетов, который потом гордо называется межсетевой экран или firewall. Так вот, настройка фильтрации пакетов - задача кропотливая, требующая понимания работы IP-протоколов.
Обычно настройка фильтра сводится к запрету всех входящих соединений, за исключением необходимых, и разрешению всех исходящих. Как правило, запрет всех входящих соединений и разрешение некоторых из них не вызывает труда, сложнее правильно настроить именно разрешение на установление исходящих соединений так, чтобы при этом не разрешить лишних входящих.
Казалось бы, достаточно сбрасывать входящие пакеты с установленным SYN-флагом, ведь именно эти пакеты запрашивают установление сессии, но, во-первых, это будет работать только для протокола TCP (в UDP нет понятия SYN-пакетов), во-вторых, это оставляет слишком большие возможности для атаки, поскольку все остальные пакеты будут пропускаться.
О том, как фильтровать входящие пакеты корректно, и пойдёт речь дальше. Внимание будет акцентировано на протоколах TCP и UDP как основных применяющихся в интернете. Под установлением соединения будет пониматься обмен пакетами, инициированный одной из сторон, сессия имеет направление, оно соответствует тому, откуда сессия была инициирована - из вашей сети или в вашу сеть. Именно направление сессии будет решающим фактором при выборе маршрутизатором решения - пропускать пакеты, принадлежащие к этой сессии, или нет.
Хорошо настроенная фильтрация пакетов похожа на выпускной клапан - она пропускает все исходящие сессии и блокирует все входящие. Делается это из соображения, что потенциальные взломщики находятся, всё-таки, в интернете, и нужно максимально усложнить им задачу проникновения в вашу сеть.
Само понятие сессии документально определено только для протокола TCP: упрощённо сессия состоит их трёх частей: установление сессии, обмен данными и закрытие сессии. Управление сессией определено стандартом на протокол TCP, и поэтому транзитный маршрутизатор может получить информацию о сессии, непосредственно анализируя заголовки проходящих пакетов, где эта информация и содержится.
С протоколом UDP дело обстоит несколько сложнее - в нём понятия сессии нет как такового, т.е. обмен данными происходит сразу же, и этапы установление и закрытие в нём отсутствуют, есть только обмен. Этот "недостаток" в UDP был внесён осознанно - отсутствие контроля сессии маршрутизаторами экономит массу времени на обработку пакетов на каждом транзитном маршрутизаторе (каковых может быть пару десятков) и позволяет использовать протокол для пересылки данных, которые допускают частичную потерю информации.
Хороший пример обмена подобного протокола UDP, - это GSM-телефония, при плохой связи пакеты просто сбрасываются (теряются), и ваш собеседник не слышит ничего, однако после улучшения связи вы можете продолжить разговор сразу же. Если же для передачи голоса использовать протокол типа TCP с контролем соединения (и коррекцией ошибок), то после улучшения связи ваш собеседник будет вынужден выслушать сначала всё то, что вы наговорили за время отсутствия связи, и только потом продолжить разговор, а в некоторых случаях вам вообще пришлось бы прервать разговор, поскольку данные могут поступать с такой задержкой (из-за перепосылок вызванных коррекцией ошибок), что разговаривать будет просто невозможно. Но, разумеется, в телефонии для передачи голоса не применяются протоколы с установлением соединения, так что этот пример чисто академический и призван показать разницу между протоколом с установлением соединения (и коррекцией ошибок) - TCP и протоколом без установления соединения (и без коррекции ошибок) - UDP. Именно UDP используется для стремительно набирающей в последнее время обороты IP-телефонии. Так что считать протокол UDP второстепенным не стоит, именно он применяется для передачи мультимедийных данных в режиме реального времени, как то голос и видеоизображение. Со временем роль протокола UDP будет только усиливаться, и системным администраторам стоит уделять ему не меньше внимания, чем TCP.
Несмотря на то, что UDP не содержит в себе средств контроля за соединением, сессии с помощью UDP всё же возможны, но для контроля состояния сессии используются механизмы, заложенные непосредственно в сетевое приложение, а не в TCP/IP-стек операционной системы, как это реализовано для протокола TCP. Сложность заключается в том, что заголовки UDP-пакетов не несут в себе информации о сессии - эта информация либо вообще не передаётся за переделы сетевой программы, либо передаётся внутри поля данных UDP-пакета, в первом случае маршрутизатор вообще не может получить информацию о сессии, во втором это довольно сложно, поскольку маршрутизатор будет вынужден анализировать не только заголовки, но и содержимое UDP-пакетов, что может в значительной мере нагрузить процессор маршрутизатора, плюс маршрутизатор должен знать обо всех протоколах верхнего уровня, использующих такой транспорт, что вообще мало реально.
На практике применяется другой метод отслеживания UDP-сессий на маршрутизаторах - таблицы обмена пакетами. Работают они следующим образом: если маршрутизатор обнаруживает UDP-пакет, он проверяет его на наличие записи об аналогичном пакете в таблице обмена, если запись обнаружена (т.е. совпал адрес и порт отправителя и адрес и порт получателя, либо наоборот), то пакет считается принадлежащим к существующей сессии (запись о которой как раз была в таблице) и обрабатывается в соответствии с правилами фильтрации для установленных сессий; если запись не обнаружена, то маршрутизатор заключает, что этот пакет отрывает новую сессию, и делает запись в таблице обмена, причём именно при обнаружении пакета, открывающего сессию, определяется её направление - отправитель этого пакета считается инициатором сессии. Далее для новой сессии запускается таймер, который обнуляется при обнаружении очередного пакета, принадлежащего этой сессии. Если таймер не обнулялся за заданное время (т.е. не было обнаружено обмена пакетами в пределах этой сессии), то маршрутизатор считает, что обмен пакетами прекратился, и удаляет запись об этой сессии из таблицы обмена. Такие таймеры маршрутизатор ведёт для каждой записи в таблице, таким образом он отслеживает UDP-сессии, поскольку средствами протокола UDP это сделать невозможно.
Итак, маршрутизатор ведёт список существующих сессий, теперь можно вооружиться правилами фильтрации пакетов и беспрепятственно впускать пакеты, принадлежащие к сессиям, инициированным со стороны нашей сети, и сбрасывать пакеты, которые к ним не принадлежат, т.е. могут быть опасны.
Технология отслеживания сессий называется Reflexive Access Lists в терминологии CISCO Systems и Stateful inspection в OC Linux, именно она используется для контроля соединений между разными сетями для обеспечения безопасного соединения с интернетом (см. "КВ" №37).
В маршрутизаторах CISCO создаются специальные динамические списки доступа, в которые маршрутизатор добавляет записи в соответствии с обнаруженными сессиями, поэтому такие списки доступа называются рефлексивными (reflexive), т.е. реагирующими на обстановку (в отличие от других типов списков, которые задаются вручную). Далее такие списки доступа включаются в списки доступа, привязанные к определённому интерфейсу таким образом, чтобы пакеты, попадающие в них, пропускались. При закрытии сессии запись из рефлексивного списка доступа удаляется.
OC Linux поддерживает обработку сессий, начиная с ядра 2.4, в которое была включена новая версия пакетного фильтра IPTables, именно этот фильтр отвечает за функции межсетевого экрана. В Linux обнаружение и отслеживание сессий происходит автоматически, нужно лишь правильно настроить правила входящей фильтрации.
© 2002 Алексей ГРЕЧАНИНОВ
Горячие темы