ть на любой удаленный запрос. Такие организации обладают линией доступа, обеспечивающей постоянное интернет-соединение.
Проблема усугубляется еще и тем, что все больше частных пользователей желают иметь ADSL или кабельное соединение с интернетом, поскольку при этом не нужно (как когда-то) платить за подключение на почасовой основе — взимается только ежемесячная абонентская плата. Многие пользователи имеют дома два и более компьютера (например, по одному на каждого члена семьи) и хотят, чтобы все устройства имели постоянный выход в интернет. Решение таково: необходимо установить (беспроводной) маршрутизатор и объединить все компьютеры в домашнюю LAN. Сам маршрутизатор должен быть подключен к провайдеру. С точки зрения провайдера, в этом случае семья будет выступать в качестве аналога маленькой фирмы с несколькими компьютерами. Добро пожаловать в компанию «Ивановы»! Если использовать обычные схемы, то каждый компьютер будет сохранять свой IP-адрес в течение всего дня. Но для провайдеров с несколькими тысячами клиентов (многие из которых представляют собой целые организации или семьи, также похожие на небольшие организации) такая ситуация недопустима, так как IP-адресов попросту не хватит.
Дефицит IP-адресов не является теоретической проблемой, которая может возникнуть в далеком будущем. Это происходит здесь и сейчас. В долгосрочной перспективе решением будет тотальный перевод всего интернета на протокол IPv6 со 128-битной адресацией. Этот переход действительно постепенно происходит, но процесс идет так медленно, что затянется на годы. А пока необходимо найти какое-нибудь временное решение. Им стал популярный метод трансляции сетевого адреса (Network Address Translation, NAT), описанный в RFC 3022. Суть его мы рассмотрим ниже, а более подробную информацию можно найти в работе Датчера (Dutcher, 2001).
Основная идея NAT состоит в присвоении каждой фирме или семье одного IP-адреса (или, по крайней мере, небольшого числа адресов) для интернет-трафика. Внутри абонентской сети каждый компьютер получает уникальный IP-адрес для маршрутизации внутреннего трафика. Однако как только пакет покидает пределы абонентской сети и направляется к провайдеру, выполняется трансляция адреса, при которой уникальный внутренний IP-адрес становится общим публичным IP-адресом. Для реализации этой схемы было создано три диапазона так называемых частных IP-адресов. Они могут использоваться внутри сети по ее усмотрению. Единственное ограничение — пакеты с такими адресами ни в коем случае не должны появляться в самом интернете. Вот эти три зарезервированных диапазона:
10.0.0.0 — 10.255.255.255/8 (16 777 216 хостов)
172.16.0.0 — 172.31.255.255/12 (1 048 576 хостов)
192.168.0.0 — 192.168.255.255/16 (65 536 хостов)
Итак, первый диапазон может обеспечить адресами 16 777 216 хостов (кроме всех нулей и всех единиц, как обычно), и именно его чаще всего предпочитают абоненты, даже для небольших сетей.
Работа метода NAT показана на илл. 5.56. В пределах территории абонента у каждого компьютера имеется собственный уникальный адрес вида 10.x.y.z. Тем не менее перед тем, как пакет выходит за пределы помещения абонента, он проходит через NAT-блок (NAT box), транслирующий внутренний IP-адрес источника (10.0.0.1 на рисунке) в реальный IP-адрес, полученный абонентом от провайдера (198.60.42.12 для нашего примера). NAT-блок обычно представляет собой единое устройство с межсетевым экраном, обеспечивающим безопасность путем строгого отслеживания входящего и исходящего трафика абонентской сети. Межсетевые экраны мы изучим отдельно в главе 8. NAT-блок может быть также интегрирован с маршрутизатором или модемом ADSL.
Мы до сих пор обходили одну маленькую деталь: когда приходит ответ на запрос (например, от веб-сервера), он адресуется 198.60.42.12. Как же NAT-блок узнает, каким внутренним адресом заменить общий адрес компании? В этом и состоит главная проблема применения NAT. Если бы в заголовке IP-пакета было свободное поле, его можно было бы использовать для запоминания адреса того, кто отправил запрос. Но в заголовке остается неиспользованным всего один бит. В принципе, можно было бы создать поле для реального адреса источника, но это потребовало бы изменения IP-кода на всех устройствах интернета. Это не лучший выход, особенно если мы хотим найти быстрое решение проблемы нехватки IP-адресов.
Илл. 5.56. Расположение и работа NAT-блока
На самом деле происходит следующее. Разработчики NAT заметили, что большая часть пользовательских данных IP-пакетов — это либо TCP, либо UDP. Когда мы будем рассматривать TCP и UDP в главе 6, мы увидим, что оба формата имеют заголовки, содержащие номера портов источника и получателя. Ниже мы обсудим порты TCP, но с портами UDP происходит то же самое. Номера портов представляют собой 16-разрядные целые числа, показывающие, где начинается и заканчивается TCP-соединение. Место хранения номеров портов используется в качестве поля, необходимого для работы NAT.
Когда процесс хочет установить TCP-соединение с удаленным процессом, он связывается со свободным TCP-портом на своем компьютере. Этот порт становится портом источника (source port) и сообщает TCP-коду, куда направлять пакеты данного соединения. Процесс также определяет порт назначения (destination port). Посредством этого порта сообщается, кому отдать пакет на удаленной стороне. Порты с 0-го по 1023-й зарезервированы для хорошо известных служб. Например, 80-й порт используется веб-серверами, соответственно, на них могут ориентироваться удаленные клиенты. Каждое исходящее сообщение TCP содержит информацию о портах источника и назначения. Вместе они служат для идентификации процессов на обоих концах, использующих соединение.
Проведем аналогию, которая прояснит принцип использования портов. Допустим, у компании есть один общий телефонный номер. Когда человек набирает этот номер, он слышит голос оператора, который спрашивает, с кем именно нужно соединиться, и подключает звонящего к соответствующему добавочному номеру. Основной номер является аналогией IP-адреса абонента, а добавочные на обоих концах аналогичны портам. Для адресации портов используется 16-битное поле, которое идентифицирует процесс, получающий входящий пакет.
С помощью поля Source port решается проблема отображения адресов. Когда исходящий пакет приходит в NAT-блок, адрес источника вида 10.x.y.z заменяется настоящим IP-адресом. Кроме того, поле Source port TCP заменяется индексом таблицы перевода NAT-блока, содержащей 65 536 записей. Каждая запись включает исходный IP-адрес и номер исходного порта. Наконец, пересчитываются и вставляются в пакет контрольные суммы заголовков TCP и IP. Поле Source port нужно заменять, поскольку устройства с местными адресами 10.0.0.1 и 10.0.0.2 могут случайно пожелать воспользоваться одним и тем же портом (5000-м, например). Так что для однозначной идентификации процесса отправителя единственного поля Source port оказывается недостаточно.
Когда пакет прибывает на NAT-блок со стороны провайдера, извлекается значение поля Destination port заголовка TCP. Оно используется в качестве индекса таблицы отображения NAT-блока. По найденной в этой таблице записи определяются внутренний IP-адрес и настоящий порт TCP. Эти два значения вставляются в пакет. Затем заново подсчитываются контрольные суммы TCP и IP. Пакет передается на главный маршрутизатор абонента для нормальной доставки с адресом вида 10.x.y.z.
Хотя описанная выше схема частично решает проблему нехватки IP-адресов, сетевые пуристы из IP-сообщества рассматривают NAT как некую заразу, распространяющуюся по земле. И их можно понять. Во-первых, сам принцип NAT никак не вписывается в архитектуру IP, которая подразумевает, что каждый IP-адрес уникальным образом идентифицирует только одно устройство в мире. Вся программная структура интернета построена на этом факте. При использовании NAT получается, что тысячи компьютеров могут (и так происходит в действительности) иметь адрес 10.0.0.1.
Во-вторых, NAT нарушает «сквозной» принцип, согласно которому каждый хост должен уметь отправлять пакет любому другому хосту в любой момент времени. Поскольку отображение адресов в NAT-блоке задается исходящими пакетами, входящие пакеты не принимаются до тех пор, пока не отправлены исходящие. На деле это означает, что пользователь домашней сети с NAT может создать TCP/IP-соединение с удаленным сервером, но удаленный пользователь не может подключиться к игровому серверу в домашней сети. Чтобы это сделать, необходимы специальные настройки или методы обхода NAT (NAT traversal).
В-третьих, NAT превращает интернет из сети без установления соединения в нечто, напоминающее сеть, ориентированную на его установление. Проблема в том, что NAT-блок должен поддерживать таблицу отображения для всех соединений, проходящих через него. Запоминать состояние подключений — задача сетей, ориентированных на установление соединения, но никак не сетей без него. Если NAT-блок выходит из строя, а его таблицы отображения теряются, то про все проходящие через него TCP-соединения можно забыть. Без NAT сбой или перезагрузка маршрутизатора не оказывают никакого эффекта на TCP-соединение. Отправляющий процесс просто ждет несколько секунд и отправляет все неподтвержденные пакеты заново. С NAT интернет становится таким же восприимчивым к сбоям, как сеть с коммутацией каналов.
В-четвертых, NAT нарушает одно из фундаментальных правил построения многоуровневых протоколов: уровень k не должен строить никаких предположений относительно того, что именно уровень k + 1 поместил в поле Payload. Этот принцип обеспечивает независимость уровней друг от друга. Если когда-нибудь на смену ТСР придет ТСР-2, у которого будет другой формат заголовка (например, 32-битная адресация портов), то NAT потерпит фиаско. Вся идея многоуровневых протоколов состоит в том, чтобы изменения в одном уровне никак не влияли на остальные уровни. NAT разрушает эту независимость.
В-пятых, процессы в интернете вовсе не обязаны использовать только TCP или UDP. Если пользователь устройства А придумает новый протокол транспортного уровня для общения с пользователем устройства В (например, с целью поддержки какого-либо мультимедийного приложения), то ему придется бороться с тем, что NAT-блок не сможет корректно обработать поле TCP Source port.