Операционная система Linux

Подмена адресов


Если в некоторой сети используются адреса из описанного стандартом RFC1918 внутреннего диапазона (например, из сети 10.0.0.0/8), то без дополнительных действий абоненты этой сети доступа к Internet иметь не будут. Пакеты с такими адресами запрещено передавать в Internet, а даже если они туда просочатся через маршрутизатор, соединяющий "внутреннюю" и "внешнюю" сети, следующий же маршрутизатор откажется их пересылать. Простая, казалось бы, мысль научить межсетевой экран, установленный на маршрутизаторе, подменять IP-адреса в пакетах, приходящих из внутренней сети, своим внешним IP-адресом, наталкивается на серьезное препятствие.

Допустим, абоненты с адресом 10.0.0.3 и 10.0.0.7 устанавливают TCP-соединение с адресом в Internet (скажем, 209.173.53.26). Специально обученный маршрутизатор подменяет 10.0.0.3 и 10.0.0.7 на адрес своего сетевого интерфейса, подключенного к внешней сети (допустим, 194.87.0.50). Пакеты уходят адресату, как если бы и тот, и другой были отправлены самим маршрутизатором. 209.173.53.26 отвечает на два запроса двумя пакетами, оба – на адрес 194.87.0.50. Что делать дальше? Как отличить пакет, предназначенный для 10.0.0.3 от такого же для 10.0.0.7?

На помощь приходит знание TCP. Как известно, TCP-соединение идентифицируется шестью параметрами: IP-адресами отправителя и получателя, портами на отправителе и получателе и номерами последовательности (SEQN) входящего и исходящего потока данных. В нашей схеме межсетевой экран обязательно заменяет IP-адреса одним, поэтому у двух принятых пакетов они совпадают. А вот с четырьмя оставшимися параметрами он волен поступать, как заблагорассудится: в любом случае каждому из сеансов должны соответствовать разные SEQN и разные номера исходящих портов. Осталось только держать в памяти таблицу соответствия TCP-соединений из внутренней сети TCP-соединениям во внешнюю сеть.

Этот механизм носит название "преобразование сетевых адресов" (Network Adress Translation, NAT). Следует помнить, что чем больше транспортных соединений отслеживается межсетевым экраном, тем больше требуется оперативной памяти ядру Linux и тем медленнее работает процедура сопоставления проходящих пакетов таблице. Впрочем, мощность современных компьютеров позволяет без каких-либо затруднений обслуживать преобразование адресов для сети с пропускной способностью 100Мбит/с и даже выше. В iptables есть специальный модуль для NAT и соответствующие действия в правиле. Такие правила принято помещать в таблицы типа nat:

[root@fuji root]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 83.237.29.1 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0 192.168.102.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 10.13.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo 0.0.0.0 83.237.29.1 0.0.0.0 UG 0 0 0 ppp0 [root@fuji root]# iptables-save # Generated by iptables-save v1.2.11 on Sat Dec 25 14:02:44 2004 *nat :PREROUTING ACCEPT [216:12356] :POSTROUTING ACCEPT [242:27148] :OUTPUT ACCEPT [1428:91596] -A POSTROUTING -o ppp+ -j MASQUERADE COMMIT . . .


Пример 15.14. Использование простейшего преобразования адресов (html, txt)

На том самом маршрутизаторе, где, по словам Гуревича, "всего один настоящий адрес, да и тот – PPP", как раз и настроено преобразование адресов. Делается это всего одним правилом, добавленным в таблицу nat цепочки POSTROUTING. Действие MASQUERADE отличается от действия SNAT (Source NAT) только тем, что может быть использовано на интерфейсах с изменяемым IP-адресом, таких как ppp или настраиваемый по DHCP eth. Если в процессе работы IP-адрес интерфейса поменяется, правило SNAT продолжит менять адреса на старый, заданный во время настройки iptables. Зато MASQUERADE вынуждено спрашивать у системы IP-адрес указанного интерфейса для каждого преобразуемого пакета, что может быть неудобно на очень медленных или очень загруженных разнообразными службами компьютерах.

Преобразование адресов работает не только для TCP-соединений, но и для многих других протоколов, где возможно отследить либо настоящего адресата на внутренней сети, либо идентификатор сеанса связи. Например, ICMP-пакет команды ping содержит уникальный идентификатор, который используется в ответе на него, поэтому не составляет труда отследить, на чей именно ping пришел ICMP-ответ. Таблица отслеживаемых соединений отражается в файле net/ip_conntrack виртуальной файловой системы /proc:

Пример 15.15. Просмотр таблицы подменяемых адресов (html, txt)

Так и есть: во-первых, Мефодий (скорее всего) что-то рассматривает на сайте www.ru (он же 194.87.0.50), а во-вторых, он зачем-то запустил ping www.us: команда cat подана как раз между ICMP-запросом по ад- ресу 209.173.53.26 и ответом на него. Левая часть таблицы описывает соединение до подмены адресов, а правая – после. Точно так же можно "ловить" и UDP-запросы к службе доменных имен, и многое другое.

Конечно, фильтрацией и маскарадом функции iptables не исчерпываются. Можно, например, задать статическую таблицу подмены адресов, тогда появится возможность принимать из Internet соединения, предназначенные для внутренних серверов. Того же можно добиться, используя подмену адреса только для соединений по определенным портам и т. д.


Содержание раздела