Малоизвестные подробности работы NATИсточник: cyberguru
Используя терминологию Cisco, в контексте NAT есть четыре основных определения для IP-адресов. Рассмотрим их на примере, показанном на рисунке ниже. На обоих маршрутизаторах делается NAT (network address translation). При этом используются следующие термины:
Простейший случай NAT - это трансляция адресов Inside Local в Inside Global и наоборот. При этом маршрутизатор, выполняющий NAT, модифицирует поле адреса в заголовке IP следующим образом:
Таким образом, в таблице сопоставлений NAT каждая запись состоит из двух значений - IL и IG. Эта или подобная схема иногда применяется для обеспечения доступа снаружи к хостам, находящимся в локальной сети (например, к веб-серверу или FTP-серверу). Она может также применяться для балансировки нагрузки путем динамического распределения пакетов, приходящих на публичный адрес маршрутизатора, между несколькими серверами, находящимися в локальной сети, и еще в некоторых случаях. Более распространённый случай - это NPAT, network and port address translation. При использовании NPAT в таблице сопоставлений каждая запись имеет не два (как в простом NAT), а пять значений:
Это позволяет использовать единственный публичный адрес для предоставления доступа в Интернет компьютерам, находящимся в локальной сети. В документации Cisco такая схема обычно называется "NAT with port overload" или короче - "NAT overload". Исторически сложилось так, что именно его, как правило, имеют в виду, когда употребляют термин "NAT", и о нём мы и будем говорить в дальнейшем, ввиду его распространённости. До сих пор речь шла о вещах общеизвестных. Однако, если посмотреть на NAT поближе, возникают новые вопросы. Возьмём простейшую сеть, с одним компьютером и одним маршрутизатором, выполняющим NAT. Модель маршрутизатора в данном случае не слишком важна - допустим, что это давно устаревшая, но все еще популярная Cisco 1601R.
В конфигурации маршрутизатора указано, что он должен выполнять NAT для всех пакетов, с адресами источника 192.168.0.0/24, пришедших через интерфейс Ethernet0 и отправляемых далее через интерфейс Serial0, а также для ответных пакетов, пришедших через Serial0, для которых есть соответствующая запись в таблице трансляций:
interface Serial0
ip address 11.22.33.44 255.255.255.252 ip nat outside interface Ethernet0 ip nat inside source list MyNetwork interface Serial0 overload Предположим, компьютер с адресом IL 192.168.0.141 отправляет DNS-запрос на внешний хост 1.2.3.4 (порт 53, протокол UDP). Как следует из конфигурации, наш внешний адрес IG - 11.22.33.44. В результате этого в таблице NAT появится примерно такая запись: Proto Inside global Inside local Outside local Outside global
UDP 11.22.33.44:1053 192.168.0.141:1053 1.2.3.4:53 1.2.3.4:53 Допустим, после появления такой записи в таблице, другой хост, 1.2.3.5, отправляет пакет UDP с адресом назначения 11.22.33.44 и портом назначения 1053. Вопрос - получит ли наш хост 192.168.0.141 этот пакет? Здравый смысл подсказывает, что вроде бы не должен. С другой стороны, налицо факт: в нашей таблице NAT черным по белому записано, что пакет с адресом назначения 11.22.33.44 и портом назначения 1053 нужно принять и транслировать в локальную сеть для хоста 192.168.0.141 (который его примет и молча уничтожит, поскольку на этом компьютере не запущено сетевого приложения, которому был бы предназначен этот пакет.) Кстати говоря - ну хорошо, допустим такого приложения нет, а если бы оно было? Как хорошо известно пользователям таких программ, как eMule и eDonkey, они требуют, чтобы им была предоставлена возможность беспрепятственно получать UDP пакеты с портом назначения 4661, или 4242, или 4321 - точный номер порта зависит от настроек. И, что также хорошо известно их пользователям, эти программы плохо работают, будучи запущены из локальной сети, находящейся за NAT. Так вот, это может происходить, в том числе и потому, что несмотря на успешное установление локальным клиентом соединения с сервером, из-за специфики данной конкретной реализации NAT другие клиенты, находящиеся во внешнем мире, не могут устанавливать соединение с локальным клиентом. По этой же причине может не работать DCC chat в клиентах IRC, передача файлов в ICQ и тому подобные вещи, для которых требуется обеспечение беспрепятственного прохождения пакетов непосредственно между пользовательскими компьютерами. Итак, отвечая на вопрос, "получит ли наш хост 192.168.0.141 пакет, направленный на 11.22.33.44 от постороннего хоста", - может быть, получит, а может быть, и нет; ответ на этот вопрос зависит от реализации NAT на пограничном маршрутизаторе. Реализаций же насчитывается четыре:
Как видим, реализации NAT - это настоящий зоопарк, в котором каждой твари по паре. Положение смягчается тем, что для большинства сетевых приложений подробности реализации NAT большого значения не имеют (в особенности для приложений, использующих транспорт TCP, как известно, это протокол, использующий сессии, поэтому сказанное выше для TCP неактуально. Тем не менее с развитием приложений Peer-to-Peer (eDonkey, eMule, Skype), IPтелефонии и разнообразной сетевой мультимедии (зачастую использующих транспорт на основе UDP) различия в реализациях NAT постепенно начинают играть заметную роль. Поэтому для разработчиков таких приложений пришла пора задуматься над тем, как их детище будет работать, находясь в локальной сети за NATом. Одним из плодов таких раздумий стал протокол STUN (Simple Traversal of UDP through NAT), описанный в RFC 3489. Некоторым приложениям, особенно предназначенным для IP-телефонии (поскольку там это наиболее актуально), важно знать, находится ли компьютер, на котором они запущены, в локальной сети за NAT или на компьютере с публичным IP адресом, и в случае NAT - определить, какого он типа. Для этого в настоящее время широко используется протокол STUN, который позволяет также определить наличие блокирующего firewall на пограничном маршрутизаторе или самом компьютере. Протокол STUNИдея STUN несложна - клиент отправляет на находящийся снаружи сервер зондирующие сообщения, используя транспорт UDP. В теле этих сообщений содержатся IP адреса и номера портов источника и приемника. Непременным условием работы сервера является использование им двух IP-адресов - дальше станет понятно, для чего. Процесс определения типа NAT с использованием STUN протекает следующим образом. Допустим, наш клиент находится за NAT, его локальный адрес 192.168.0.111, публичный адрес NAT - 1.2.3.4, адреса сервера STUN - 11.22.33.1 и 11.22.33.2, номера портов 3478. Происходит следующее:
Для иллюстрации работы STUN рассмотрим следующий рисунок(взят из статьи "Anatomy: A Look Inside Network Address Translators" в "The IP Journal" Vol.7 Num. 2 за сентябрь 2004 г.).
Клиент STUN встроен в некоторые приложения IP-телефонии, например, X-Pro и X-Lite от компании CounterPath, и в некоторые другие. Консольный клиент STUN под ОС Windows может быть загружен отсюда: http://prdownloads.sourceforge.net/stun/client.exe?download. Запустив его и указав в качестве параметра командной строки один из публичных STUN-серверов, вы узнаете тип вашего NAT:
C:\>client.exe stun.xten.com
STUN client version 0.94 Приведённый выше результат получен на компьютере, находящемся за маршрутизатором ZyXEL Prestige 645R. Результат для маршрутизатора Cisco 1721 с IOS версии 12.2 в свою очередь выглядит так:
C:\>client.exe stun.xten.net
STUN client version 0.94 Такой же результат получен для маршрутизатора, построенного на основе FreeBSD, на которой NAT выполнялась демоном natd. А вот как выглядит результат для PIX (прим. HunSolo) C:\>client.exe stun.xten.net
STUN client version 0.94 Осталось объяснить, что такое "random port", "preserves ports" и "no hairpin" в приведенных выше результатах. Посмотрим еще раз на строчку из таблицы NAT в нашем примере:
Proto Inside global Inside local Outside local Outside global
UDP 11.22.33.44:1053 192.168.0.141:1053 1.2.3.4:53 1.2.3.4:53 Random port означает, что данная реализация NAT не заботится о том, чтобы номер порта источника в исходящем наружу пакете оставался таким же, каким он был получен от хоста локальной сети, и заменяет его на случайное значение в диапазоне от 1024 до 65535. Можно предположить, что по замыслу автора идеи "random ports" такая замена уменьшает вероятность конфликта между записями, если несколько хостов локальной сети одновременно попытаются отправить наружу пакеты с совпадающим номером порта источника. Поскольку номер порта источника в исходящих пакетах формируется хостами локальной сети также случайным образом, преимущества такой замены сомнительны, из недостатков же можно назвать хотя бы потенциальную проблему с протоколом RPC, да и не только. Как видно из примера, наш маршрутизатор старается сохранять номер порта неизменным (11.22.33.44:1053 и 192.168.0.141:1053), из чего следует, что запущенный в его локальной сети STUN-клиент сообщил бы о нем preserves ports. К слову, на FreeBSD этот результат достигается ключом "-same_ports" или "-s" в строчке запуска или конфигурационном файле демона natd. Hairpin же означает следующее. Допустим, при наличии в таблице NAT приведенной выше строчки другой хост нашей локальной сети (например, 192.168.0.241) отправляет UDP-пакет с адресом назначения 11.22.33.44, портом назначения 1053 и портом источника 53. Что произойдет в результате? Ответ на этот вопрос зависит от того, поддерживает маршрутизатор функцию "hairpin" или не поддерживает. Если он ее поддерживает, пакет будет обычным образом обработан и (если на маршрутизаторе используется реализация NAT Full Cone или Port Restricted) попадет по назначению - на хост 192.168.0.141. Если же нет ("no hairpin"), пакет будет уничтожен маршрутизатором. Название функции "hairpin" (шпилька для волос) произошло от того, что, если изобразить прохождение такого пакета на рисунке, форма его траектории будет похожа на U-образную шпильку. Другое объяснение - слово "hairpin" переводится так же, как "разворот на 180 градусов". При поддержке маршрутизатором функции "hairpin" подпадающие под ее действие пакеты, действительно, будут развернуты на 180 градусов и отправлены обратно в локальную сеть. NAT и шлюзы приложенийК сожалению, не у всех сетевых протоколов взаимодействие с NAT протекает безболезненно. Наиболее часто встречающийся пример - это FTP. Здесь возможны два случая. Первый случай. Пользователь, находящийся в локальной сети за NAT, использует FTP-клиент для того, чтобы получить доступ к FTP-серверу с публичным IP-адресом
Проблема здесь возникает, когда клиент пытается использовать активный режим FTP. Сессия протекает при этом следующим образом. В некоторый момент по управляющему соединению серверу передается команда FTP-клиента: PORT 192,16,0,101,4,211. Дальнейший диалог выглядит примерно так:
Server: 200 PORT command successful. Consider using PASV.
Client: RETR file.zip Server: 150 Opening BINARY mode data connection for file.zip (1334109 bytes). Наибольший интерес здесь представляет первая команда от клиента, которая информирует сервер о том, что хост с адресом 192.168.0.101 открыл для приема соединения данных порт номер (4*256) + 211 = 1235. В ответ на это сервер должен установить соединение данных со своего порта номер 20 на указанный порт хоста 192.168.0.101. Поскольку этот адрес является приватным, такое соединение не может быть установлено. В результате наблюдается знакомый многим системным администраторам эффект, когда клиент вроде бы успешно подключается к FTP-серверу, но не может скачивать с него файлы или даже просматривать содержимое текущего каталога (это происходит потому, что передача листинга файлов с сервера на клиент также осуществляется по соединению данных). ля борьбы с описанной проблемой может использоваться переключение сервера в так называемый пассивный режим. Поскольку в этом режиме инициатором соединения данных выступает клиент, проблема исчезает. Именно поэтому в Microsoft Internet Explorer, как и консольный FTP-клиент, встроенный в Windows, используют по умолчанию пассивный режим (они автоматически вставляют перед командами RETR и NLST команду PASV, переключающую сервер в пассивный режим). Второй случай. Пользователь, находящийся в локальной сети за NAT, использует FTP-клиент для того, чтобы получить доступ к FTP-серверу, который также находится за NAT. В этом случае, очевидно, не поможет и пассивный режим, так как в команде PORT независимо от того, клиент или сервер ее отдает, всегда будет указан приватный IP-адрес, и соединение данных никогда не будет установлено. Для разрешения этой проблемы в некоторых реализациях NAT существует специальная функция - трансляция адресов на уровне приложений, называемая также NAT ALG (Application Level Gateways). При задействованной функции ALG маршрутизатор отслеживает и модифицирует данные уровня приложений некоторых сетевых протоколов. Так, в приведенном выше примере, если предположить, что публичный IP-адрес маршрутизатора с NAT 1.2.3.4 и что он сохраняет номер порта источника неизменным, команда PORT 192,16,0,101,4,211 была бы изменена маршрутизатором на PORT 1,2,3,4,4,211. Благодаря этому в обоих указанных выше случаях соединение данных будет успешно установлено. Функция ALG в маршрутизаторах Cisco позволяет осуществлять трансляцию адресов уровня приложений не только для протокола FTP, но также и для протоколов SIP, H.323, Skinny и некоторых других (благодаря этому можно, например, размещать в локальной сети серверы DNS). Для большего удобства функция ALG в маршрутизаторах Cisco включена по умолчанию. Аналогичную ALG функциональность в маршрутизаторах на основе ОС Linux обеспечивают дополнительные загружаемые модули и патчи к ядру (такие, как ip_masq_ftp, ip_masq_irc и т. п.). ЗаключениеПонимание принципов работы различных реализаций NAT может оказаться полезным при поиске причины неудовлетворительной работы некоторых приложений, использующих транспортный протокол UDP. Так, например, сочетание ALG и Symmetric или Port Restricted NAT и IP-телефонов, использующих протокол установки соедиенения SIP, может порой давать самые причудливые результаты (спорадические отказы в регистрации на сервере, односторонняя слышимость между абонентами и т. п.), причем это зависит не только от настроек IP-телефона, но и от настроек сервера. Другой пример: компания Microsoft сообщает в своей статье KB817778, что их реализация туннеля IPv6 over UDP не будет работать через Symmetric NAT (адрес статьи в Интернете: http://support.microsoft.com/kb/817778/EN-US). Таких примеров можно найти ещё много, и во всех случаях понимание различий в реализациях NAT если и не поможет немедленно устранить проблему, то хотя бы укажет на возможные пути решения (например, заменить firmware маршрутизатора на такое, где NAT реализован в виде Full Cone, если, конечно, оно существует, или заменить сам маршрутизатор). |