2014-10-08 5 views
-1

Я пытаюсь установить связь между двумя компьютерами за NAT. Я не могу открыть какой-либо порт. Я хотел бы использовать брокера, который будет в Интернете, и кто сможет общаться с другими. После этого я хотел бы создать туннель между этими 2. Я использую Python, и я пытаюсь закодировать этого брокера. Как я могу начать это?Сделать связь между двумя компьютерами за NAT

+0

Существует сто способов сделать это. Компьютеры, находящиеся за NAT, должны будут инициировать соединение с широко видимым интернет-брокером. Легким вариантом для экспериментов является zeromq, который имеет несколько полезных инструментов для маршрутизации сообщений. Вы даже можете настроить асинхронный сервер, который пересылает запросы между двумя серверами. – tdelaney

+0

Хорошо, но можно ли просто подключить сервер к брокеру, а затем подключить клиента к этому брокеру и сделать туннель между этими двумя? Без использования брокера снова –

+0

Нет, весь трафик должен будет пройти через брокера. Я предполагаю, что эти машины находятся за разными NAT и что вы не хотите выполнять переадресацию портов за NAT. Если это так, машины не видны друг другу, и для общения потребуется какой-то общий агент/брокер. – tdelaney

ответ

12

То, что вы хотите сделать , является возможным и почти рутинным (по крайней мере, для UDP). Это называется пробиванием отверстий в сети. Он не будет работать с каждым NAT в мире, но он работает со многими, включая большинство настроек большинства современных домашних маршрутизаторов.

Основная идея заключается в том, что с большинством маршрутизаторов, если вы отправляете исходящий пакет, он будет перенаправлять все входящие пакеты с одной и той же конечной точки на вас. В противном случае NAT не будет работать вообще, верно? Итак, если и вы, и я попытаемся поговорить с общедоступными адресами друг друга, один из нас будет «пробивать дыру» в своем NAT, чтобы получить сообщение. Другой, вероятно, пропустит начальное сообщение, потому что он пробивает себе отверстие слишком поздно, но он получит следующий ответ, который отправил другой парень, и после этого все работает.

Однако здесь есть несколько трюков.

Во-первых, вам нужно знать свой общий адрес. Все, что вы можете видеть напрямую - это ваш личный адрес внутри NAT, поэтому вам нужен сервер за пределами NAT, который может сообщить вам, откуда вы. Для этого есть стандарт, называемый STUN. Мало того, что существует множество бесплатных реализаций, которые вы можете создавать и запускать самостоятельно, в Интернете есть несколько открытых STUN-серверов; google для обновленного списка.

Как минимум у вас есть один частный адрес и ваш общий адрес, и вы действительно хотите дать другому парню все из них, а не только один. (Если вы предоставляете мне только свой общий адрес, и оказывается, что мы на одном NAT, мы не сможем разговаривать друг с другом.) Это становится еще сложнее, если у вас несколько сетевых адаптеров, или вы в корпоративной локальной сети с несколькими уровнями NAT и т. д. Но если вы дадите мне целое число адресов, как узнать, какой из них использовать? Простой, я могу просто попытаться подключиться к каждому из них по каждому из моих локальных адресов, а первый, который работает, тот, который я использую. Очевидно, нам нужен какой-то протокол для этого, чтобы вы могли сказать мне, когда один из них работал, но он может быть мертвым простым.

Также обратите внимание, что когда я говорю «адрес» здесь, это не просто означает IP-адрес, но IP-адрес плюс порт. В конце концов, NAT могут и делать переводы портов вместе с адресами, а «дыра», которую вы пробиваете в NAT, часто зависит от порта. Итак, вам нужно выполнить переговоры, используя те же исходные и целевые порты, которые вы собираетесь использовать для реального общения. (На самом деле, здесь есть некоторые сложные штуки, которые объясняются связанными документами, но пока не будем их просматривать.)

Когда перфорация отверстий не работает, и вам нужно вернуться к проксированию через сервер , вы не хотите, чтобы этот код выглядел совершенно другим; вам придется писать все два раза и иметь огромные проблемы с отладкой. К счастью, для этого есть стандартное решение, называемое TURN, которое заставляет его смотреть на сверстников, как будто они фактически разговаривают напрямую, даже там, где они разговаривают через реле. Опять же есть бесплатные реализации, но, конечно, для вас нет открытых серверов TURN (потому что это будет стоить большой полосы пропускания).

Между тем, как только вы узнаете свой публичный адрес, вы должны сказать мне, что это такое, и наоборот. Очевидно, нам нужен какой-то боковой канал для разговоров, например, специальный «интродуктор» или «лобби».Как правило, вы создаете одноранговое соединение как ответвление некоторого серверного оповещения. Например, мы можем быть в канале IRC вместе или в сети чата XMPP/Jabber и решать, что мы хотим иметь одноранговую связь (чтобы избежать подслушивания или обмениваться гигантскими файлами электронных таблиц или играть в игру без огромных лаг).

Существует стандарт под названием ICE, который связывает это все вместе; если у нас есть общий боковой канал и список серверов STUN (и, возможно, TURN), ICE позволяет нам согласовывать одноранговое соединение, если это возможно (возврат к TURN, если нет).

Поддержка ICE является частью протокола SIP и ряда других протоколов, поэтому, если вы используете библиотеку для одного из этих протоколов, вам, вероятно, просто нужно выяснить, как предоставить ему список серверов STUN и TURN и это оно. Если нет, возможно, библиотеки для выполнения ICE. Если нет, есть определенные библиотеки для выполнения STUN и TURN (и если их не было, они оба довольно простые протоколы), поэтому вы можете сами провести переговоры самостоятельно.

Конечно, вам не нужно использовать ни один из этих стандартов, но вы должны обязательно прочитать, что они делают и почему они так поступают. (Кроме того, имейте в виду, что люди сейчас делают маршрутизаторы специально, чтобы сделать ICE работать лучше, и это не будет верно для ничего другого, что вы изобрели.)


Я связан со статьями Википедии выше, потому что они начинают с довольно простого обзора того, как работают технологии, и обоснования, лежащие в их основе. Существуют лучшие источники для подробных справочных спецификаций, пример кода для начала работы, библиотеки для использования и т. Д., Но в целом у Википедии есть ссылки на все, что вам нужно.

+1

Большое спасибо за ваш ответ. У меня последний вопрос. Я вижу, как иметь публичный ip всех клиентов. Но как иметь порт? –

+1

@MathieuLepage: Хороший вопрос. Поскольку NAT могут перенастраивать порты, вы должны получить свой публичный порт через STUN и объявить, что через какой-либо боковой канал или интродуктор, который вы используете, точно так же, как и адрес. Некоторые протоколы (в том числе SIP) пытаются делать трюки с соседними диапазонами портов, но многие NAT будут их нарушать, поэтому, если вы можете избежать этого, сделайте это. Во всяком случае, если вы используете ICE, он позаботится об этом вместе с остальными переговорами. – abarnert

+0

Но лед можно использовать без оглушения и поворота? –

Смежные вопросы