Малоизвестные подробности работы NAT - Протокол STUN

ОГЛАВЛЕНИЕ

Протокол 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. Происходит следующее:
  • Клиент отправляет запрос на основной адрес сервера (11.22.33.1), при этом в теле отправленного запроса указаны адреса и порты: 192.168.0.111:1055 -> 11.22.33.1:3478. Эти же адреса и порты фигурируют в заголовке IP-пакета, содержащего запрос, но после прохождения NAT адрес источника изменится на 1.2.3.4, а номер порта в зависимости от реализации NAT может измениться или остаться неизменным. Если клиент не получает никакого ответа в течение тайм-аута, он делает вывод, что находится за блокирующим firewall, и завершает работу.
  • Сервер отвечает клиенту со своего адреса 11.22.33.1 сообщением, в теле которого также указаны адреса и порты: 11.22.33.1:3478 -> 1.2.3.4:1055. Если бы адрес, с которого клиент отправлял своё первое сообщение (192.168.0.111), и адрес в полученном от сервера сообщении (1.2.3.4) совпали, клиент сделал бы вывод, что на пути пакетов NAT отсутствует. В этом случае клиент и сервер обменялись бы еще парой запросов-ответов, на основании которых можно было бы определить, не находится ли по пути между ними firewall, блокирующий входящие пакеты UDP. Поскольку они не совпадают, очевидно, что на пути между клиентом и сервером находится NAT. В этом же сообщении сервер информирует клиента о своем альтернативном IP-адресе (11.22.33.2) и номере порта (3478).
  • После этого клиент отправляет второе зондирующее сообщение, в котором установлен специальный флажок, указывающий серверу, что клиент ожидает ответа с альтернативного IP-адреса сервера (11.22.33.2), и с другим номером порта источника. Если клиент получает ответ на этот запрос, делается вывод, что находящийся по пути между ними NAT относится к Full Cone типу.
  • Если ответ на предыдущий запрос не был получен, клиент повторяет свое первое зондирующее сообщение на альтернативный адрес STUN сервера. Если в полученном ответе адрес и номер порта отличаются от указанных в первом ответе, это означает, что этот запрос инициировал появление в таблице NAT новой записи. Такое поведение характерно исключительно для Symmetric NAT.
  • Если адрес и номер порта в полученном ответе остались такими же, какими они были в первом ответе, то NAT относится к типу Restricted Cone. Осталось установить, является ли он Address Restricted или Port Restricted. Для этого клиент отсылает четвертое сообщение, в котором установлен флажок, указывающий серверу, что он должен ответить, используя порт источника с другим номером. Если ответ был получен, NAT относится к Address Restricted Cone, если нет – то к Port Restricted Cone.
Для иллюстрации работы 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
Primary: Full Cone Nat, random port, no hairpin
Return value is 0x9

Приведённый выше результат получен на компьютере, находящемся за маршрутизатором ZyXEL Prestige 645R.

Результат для маршрутизатора Cisco 1721 с IOS версии 12.2 в свою очередь выглядит так:

C:\>client.exe stun.xten.net

STUN client version 0.94
...
Primary: Port Restricted Nat, preserves ports, no hairpin
Return value is 0x1b

Такой же результат получен для маршрутизатора, построенного на основе FreeBSD, на которой NAT выполнялась демоном natd.

А вот как выглядит результат для PIX (прим. HunSolo)
C:\>client.exe stun.xten.net

STUN client version 0.94
...
Primary: Port Restricted Nat, rundom port, no hairpin
Return value is 0xb

Осталось объяснить, что такое «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 градусов и отправлены обратно в локальную сеть.