 | Настройка маршрутизатора
О фильтре пакетов
Ядро Linux содержит инфраструктуру "netfilter", которая позволяет вам отфильтровывать сетевые пакеты. Обычно эта возможность компилируется как неотъемлимая часть ядра, но можно собрать в виде модуля. В любом случае, загрузка модуля дожна быть прозрачной (например, запуск iptables приведет к загрузке iptables_filter.o, если это потребуется).
В более новых системах Linux фильтрация пакетов управляется утилитой iptables; более старые системы использовали ipchains. А до этого применялась ipfwadm. Хотя, если требуется обратная совместимость, вы все еще можете использовать ipchains вместе с недавними версиями ядра, вы все равно предпочтете более широкие возможности и улцчшенный синтаксис в iptables. То есть, большая часть понятий и опций в iptables являются совместимыми улучшениями ipchains.
В зависимости от точного сценария фильтра (firewall, NAT, и тд), фильтрация и перевод адреса может произойти либо до, либо после маршрутизации как таковой. В обоих случаях используется одна и та же программа ipchains, но используют различные правила ("цепочки") -- в основе, INPUT
и OUTPUT. Однако, фильтрация также может повлиять на решение маршрутизации, из-за филтрации FORWARD цепочки; этот способ может привести к исчезновлению пакетов, вместо их маршрутизирования.
Маршрутизация
Наряду с фильтрацией при помощи iptables (или более ранней ipchains), ядро Linux производит маршрутизацию IP-пакетов, которых получает. Маршрутизация -- более простой процесс, нежели фильтрация, хотя они умозрительно являются связанными.
Во время маршрутизации, хост просто смотрит на IP-адрес назначения и решает, знает ли он, как доставить пакет непосредственно на этот адрес, или же ему доступен шлюз, который знает, как доставить на этот адрес. Если хост не может ни доставить пакет сам, ни знает шлюза, которому можно поручить доставку, пакет теряется. Однако типичная конфигурация содержит "шлюз по умолчанию", который обрабатывает любой адрес, не определенный каким-нибудь способом.
Настройка и отображение информации по маршрутизации производится утилитой route. Однако маршрутизация может быть либо статической, либо динамической.
При статической маршрутизации, доставка определяется таблицей маршрутизации, которая явно настраивается вызовом команды route и ее командами
add или del. Более полезной, однако, может оказаться настройка динамической маршрутизации с использованием демонов routed или gated, которые рассылают информацию о маршрутизации соседним демонам-маршрутизаторам.
Демон routed поддерживает Routing Information Protocol (RIP); демон gated вдобавок имеет поддержку других протоколов -- и может пользоваться многими протоколами одновременно -- таких как:
- Routing Information Protocol Next Generation (RIPng)
- Exterior Gateway Protocol (EGP)
- Border Gateway Protocol (BGP) и BGP4+
- Defense Communications Network Local-Network Protocol (HELLO)
- Open Shortest Path First (OSPF)
- Intermediate System to Intermediate System (IS-IS)
- Internet Control Message Protocol (ICMP и ICMPv6)/Router Discovery
Давайте взглянем на довольно типичную статическую таблицу маршрутизации:
Listing 1. Типичная статическая таблица маршрутизации
% /sbin/route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
66.98.217.0 * 255.255.255.0 U 0 0 0 eth0
10.10.12.0 * 255.255.254.0 U 0 0 0 eth1
66.98.216.0 * 255.255.254.0 U 0 0 0 eth0
169.254.0.0 * 255.255.0.0 U 0 0 0 eth1
default ev1s-66-98-216- 0.0.0.0 UG 0 0 0 eth0
|
Это означает, что адресы в диапазонах 66.98.217/24 и 66.98.216/23 напрямую доставляются через eth0. Диапазоны адресов
10.10.12/23 и 169.254/16 доставляются на eth1. Все, что осталось, посылается на шлюз ev1s-66-98-216-1.ev1servers.net
(имя обрезано в выводе route; также можно использовать route -n, чтобы убедиться, что это имя имеет IP-адрес 66.98.216.1). Если вы хотите добавить другой шлюз для некоторых диапазонов адресов, вам следует выполнить следующее:
Listing 2. Добавление нового шлюза для других диапазонов адресов
% route add -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.2.1 dev eth0
|
Для машины, которая сама по себе является шлюзом, вообще говоря, используется динамическая маршрутизация, при помощи демонов routed или gated, которые могут давать меньшее число статических маршрутов. Демон routed настраивается содержимым /etc/gateways. Демон gated является более современным, и, как уже говорилось, имеет больше возможностей; он настраивается файлом /etc/gated.conf. Вообще говоря, при использовании какого-нибудь из этих демонов, вы можете запускать через сценарии запуска. Но нельзя запускать демонов routed и gated на одной машине, поскольку результаты станут непредсказуемыми и, конечно же, нежелательными.
Фильтрация с помощью iptables
Ядро Linux хранит таблицу правил фильтрации IP-пакетов, которая образует некоторую разновидность машины состояний. Наборы правил объединяются в последовательности, известные как "цепочки". Если одна цепочка встречает условие, одним из возможных действий является передача управление на обработку другой цепочки, как делается в машине состояний. Перед добавлением правил или состояний, автоматически присутствуют три цепочки:
INPUT, OUTPUT, и FORWARD. Цепочка INPUT работает когда пакет, адресованный машине-хосту, передаётся процессу локального приложения. Цепочка FORWARD используется, когда приходит пакет, адресованный другой машине, полагая, что здесь активирована переадресация, и система маршрутизации знает, как переслать пакет дальше. Пакет, порожденный на локальном хосте, посылается для фильтрации в цепочку OUTPUT -- если он проходит фильтры в цепочке OUTPUT (или любых связанных цепочек), он маршрутизуется за пределы сетевого интерфейса.
Одно действие, которое может предпринять правило, есть DROP (уничтожение) пакета; в этом случае для этого пакета больше никаких дальнейших обработок правил или переходов между состояниями не предпринимается. Но если пакет не уничтожается, то проверяется, соответствует ли пакету следующее правило в цепочке. В некоторых случаях соответствие правилу перенесёт процесс обработки на другую цепочку со своим набором правил. Создание, удаление или изменение правил и цепочек, где содержатся эти правила, производится утилитой iptables. В старых системах Linux, эти же функции выполняла утилита ipchains. Идеи, реализованные в этих утилитах, и даже в более древней
ipfwadm похожи, но здесь мы обсудим синтакс iptables.
Правило определяет набор условий, которым пакет может соответствовать, и то, какое действие следует произвести, если пакет не соответствует условию. Как упоминалось, одно общее действие состоит в DROP (уничтожении) пакетов. Например, предположим, что вам нужно (по каким-то причинам) отключить ping в петлевом интерфейсе (интерфейсе ICMP). Это можно осуществить с помощью:
Listing 3. Отключение петлевого интерфейса
% iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP
|
Конечно, это правило глупое, и его, скорее всего, следует убрать после тестирования, примерно вот так:
Listing 4. Как убрать это глупое правило
% iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP
|
Удаление правила с опцией -D требует либо в точности те же параметры, что были указаны при добавлении правила, либо описания с помощью номера правила (который нужно определять на первом месте) вот так:
Listing 5. Указание номера правила, так чтобы удаление сработало
Более интересное правило может глядеть на адрес источника и назначения в пакетах. Например, представьте, что подозрительная удаленная сеть пытается использовать службы на определенной подсети вашей сети. Это можно заблокировать на машине вашего шлюза/межсетевого экрана таким образом:
Listing 6. Блокировка машины шлюза/межсетевого экрана
% iptables -A INPUT -s 66.98.216/24 -d 64.41.64/24 -j DROP
|
Это остановит все, что исходит из 66.98.216.* IP-диапазона на локальную подсеть 64.41.64.*. Конечно, использование этого метода занесения определенного IP-диапазона в черный список в качестве защиты довольно ограничено. Более вероятным сценарием будет разрешение доступа к локальной подсети только от определенного диапазона IP:
Listing 7. Разрешение указанному диапазону IPиметь доступ к локальной подсети
% iptables -A INPUT -s ! 66.98.216/24 -d 64.41.64/24 -j DROP
|
В этом случае только адреса из IP диапазона 66.98.216.* могут иметь доступ к указанной подсети. Более того, для адреса можно использовать символическое имя, и можно указывать определенный протокол для фильтрации. Также можно выбрать для фильтрации определенный сетевой интерфейс (например, eth0), но это используется не так широко. Например, чтобы разрешить только отдельной удаленной сети обращаться к локальному web-серверу, следует использовать:
Listing 8. Разрешение отдельной удаленной сети обращаться к локальному Веб-серверу
% iptables -A INPUT -s ! example.com -d 64.41.64.124 -p TCP -sport 80 -j DROP
|
Можно указать еще и некоторые другие опции для iptables, например, включая ограничения на число допустимых пакетов или фильтрацию по флагам TCP. За подробностями обращайтесь к man-страницам iptables.
Цепочки, определенные пользователем
Мы видели основы добавления правил в автоматическае цепочки. Но гибкая настраиваемость iptables возможна при добавлении цепочек, определенных пользователем и переход к ним при совпадении с шаблоном. Новые цепочки определяются с использованием опции -N; мы уже осуществляли переход с помощью специальной цели DROP. ACCEPT (разрешить) -- это тоже специальная цель с очевидным значением. Также доступны специальные цели RETURN (вернуть) и QUEUE (поставить в очередь). Первая означает остановку обработки данной цепочки и возврат к вызывавшему/породителю ее. Обработчик QUEUE позволяет передавать пакеты к процессам пользователя для дальнейшей обработки ( это может быть журналирование, изменение пакета, или более сложная фильтрация, нежели та, что поддерживается iptables). Простой пример из книга Русти Рассела "Linux 2.4 Packet Filtering HOWTO" -- хорошая иллюстрация добавления пользовательских цепочек:
Listing 9. Добавление пользовательской цепочки
# Создание цепочки для блокировки всех соединенений за исключением локальных или уже существующих
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error: The previous line is longer than the max of 90 characters ---------|
% iptables -N block
% iptables -A block -m state --state ESTABLISHED,RELATED -j ACCEPT
% iptables -A block -m state --state NEW -i ! ppp0 -j ACCEPT
% iptables -A block -j DROP # Уничтожаем всё, что не было разрешено (ACCEPT)
# Переключение на эту цепочку с цепочек INPUT и FORWARD
% iptables -A INPUT -j block
% iptables -A FORWARD -j block
|
Обратите внимание, что цепочка block принимает (ACCEPT) в ограниченном числе случаев, тогда как последнее правило пропускает (DROP) все, что не было принято ранее.
По мере того, как были созданы новые цепочки, либо путем добавления правил к автоматическим, либо при помощи новых пользовательских цепочек, можно использовать опцию -L для просмотра текущих правил.
Преобразование сетевых адресов в сравнении с межсетевыми экранами
Примеры, которые мы видели, в основном касались правил для межсетевых экранов. Но преобразование сетевых адресов (NAT) так же настраивается с помощью iptables.
Как правило, NAT -- это способ использования отслеживания соединений для маскаранинга пакетов, исходящих из адреса локальной подсети в качестве внешнего адреса WAN, перед тем, как отправлятьиз дальше "по проводам" (на цепочке OUTPUT). Шлюз/маршутизатор, выполняющий NAT, должен запоминать, какой локальный хост соединен с каким удаленным хостом, и обращать преобразование адреса, если вдруг пакеты приходят обратно с удаленной машины.
с точки зрения системы фильтрации просто делается вид, что NAT не существует. Правила, определяемые нами, просто используют "настоящие" локальные адресы, безотносительно тому, как NAT замаскирует их для внешнего мира. Включение маскарадинга, такого как базовый NAT, просто использует описанную ниже команду iptables. Для этого следует сначала убедиться, что модуль ядра iptables_nat загружен, а затем включить IP-пересылку:
Listing 10. Включение маскарадинга
% modprobe iptables_nat # Загрузка модуля ядра
% iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
% echo 1 > /proc/sys/net/piv4/ip_forward # Включение марштуризации
|
Эта способность называется NAT источника -- адрес исходящего пакета изменен. Также существует NAT назначения (DNAT), позволяя осуществлять пересылку порта, разделение загрузки, и прозрачное проксирова. В этих случаях, входящие пакеты изменяются так, чтобы достигнуть требуемого хоста или подсети.
Но в большинстве случаев, когда пользователи или администраторы говорят о NAT, они имеют ввиду NAT источника. Если хотите настроить NAT назначения, следует указать PREROUTING, а не POSTROUTING. При DNAT, пакеты преобразовываются перед маршрутизацией.
|  |