переадресация трафика с порта X на компьютер B с помощью c # «UDP-дыра в брандмауэре» - PullRequest
7 голосов
/ 29 августа 2011

Мне нужно установить tcp-соединение с моего домашнего компьютера на мой офисный компьютер.

в офисе есть маршрутизатор, к которому подключено несколько компьютеров.у этого роутера есть интернет, поэтому у всех компьютеров, подключенных к этому роутеру, тоже есть интернет.у меня дома есть компьютер с доступом в интернет.Мне нужно, чтобы мой офисный компьютер выполнял роль сервера, а домашний компьютер подключался к нему.Раньше я имел возможность подключаться с помощью перенаправления трафика на сервере как:

    NATUPNPLib.UPnPNATClass upnpnat;
    NATUPNPLib.IStaticPortMappingCollection mappings;

    public ServerExample()
    {
        InitializeComponent();

        upnpnat = new NATUPNPLib.UPnPNATClass();
        mappings = upnpnat.StaticPortMappingCollection;

        //                           server local IP address
        mappings.Add(1300, "TCP", 1300, "192.168.150.146", true, "plsease work");
        // this code tels the router to forward all tcp traffic comming from port
        // 1300 to the server computer (it's lan ip address happens to be 192.168.150.146)
        //...

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

теперь они заменили маршрутизатор на моемофис с более новым, и я не могу использовать свой код. Теперь, с новым маршрутизатором, когда я выполняю простой код, я получаю:

enter image description here

обратите внимание, что сопоставления возвращаютсяноль;поэтому я не могу добавить отображение.

Я уверен, что должен быть способ установить соединение, потому что некоторые люди в офисе используют, например, limewire или битовый торрент.Я думаю, что моя проблема связана с разрешениями, может быть?Как я могу решить это?


Редактировать

Итак, из исследования я обнаружил, что я пытаюсь сделать «пробить UDP-дыру в брандмауэре».Я на самом деле хочу сделать это через TCP-соединение.Я не знаю, в чем будет разница между tcp и upd puch holing .... Я имею в виду, что цель в том, чтобы клиент мог найти грушу без необходимости конфигурировать маршрутизатор.

.

.

.

.

.

.

ОБНОВЛЕНИЕ

Хорошо, так что я думаю, что я пытался сделать то, что вы, ребята, разместили по этому вопросу с помощью c #: хорошо, позвольте мне показать вам, что я сделал:

обратите внимание, вам может понадобиться обратиться к этой диаграмме, чтобы понять, что ябудет объяснено: enter image description here

Как вы знаете, я хочу установить tcp-соединение между компьютером A и компьютером B. Для этого мне нужно сделать то, что называется tcp punch holing.

Шаг 1: Первое, что я делаю, это начинаю прослушивать новые соединения на сервере S.

                   TcpListener server = new TcpListener(System.Net.IPAddress.Parse(“192.168.11.109”), 55550);
                   Server.Start();

                   var client = server.AcceptSocket();  \\ wait here until someone connects

Шаг 2: Теперь подключитесь к серверу с компьютером A как:

          TcpClient tcpClient = new TcpClient("192.168.11.109", 55550);

Шаг 3. После выполнения кода шага 2 на компьютере A отладка сервера S должна выглядеть следующим образом:

enter image description here

Шаг 4: Теперь наша цель - подключиться с компьютера B к компьютеру A. Сервер S имеет информацию, необходимую B для установления соединения.В действительности мне придется установить соединение между компьютером B и сервером S, чтобы сервер S мог дать B соответствующие параметры, чтобы B мог подключиться к A.

Шаг 5: поскольку я отлаживаю, я могучтобы увидеть параметры, я теперь сделаю компьютер A сервером, прослушивая порт 3313. Я хочу, чтобы компьютер A теперь прослушивал этот порт (3313), потому что все пакеты, отправленные на маршрутизатор X с портом 3313, должны быть отправлены на компьютер A.

       \\ COMPUTER A 
       TcpListener server = new TcpListener(System.Net.IPAddress.Parse("192.168.0.120"), 3313);
        server.Start();

        var newClient = server.AcceptSocket();  \\ wait here until a client gets connected

Шаг 6: Таким образом, компьютер A теперь должен прослушивать новые соединения через порт 3313. Опять порт 3313 важен, потому что маршрутизатор x должен пересылать все пакеты, полученные с этого порта, на компьютер A.

Компьютер A ожидает новых подключений.enter image description here

Шаг 7: Так что теперь быстро!Мы хотим установить это соединение с компьютера B. В действительности сервер S будет передавать параметры, но поскольку я просто пытаюсь выполнить эту работу, я очень быстро напишу программу на компьютере B.

          TcpClient tcpClient = new TcpClient(“192.168.11.108”, 3313);
           \\192.168.11.108  is the address of router X

Наконец:

По какой-то причине компьютер B не может подключиться к компьютеру A.

enter image description here

Причина, по которой он не может подключиться, заключается в том, что маршрутизатор X не перенаправил пакеты на компьютер A. (Я знаю это, потому что я включил переадресацию портов на порт 54540 на маршрутизаторе X, и когда я использую этот порт, он работает)Я имею в виду, я не понимаю, почему маршрутизатор X не переадресовал трафик, поступающий из порта 3313 на компьютер A. Компьютер A уже установил соединение с сервером S, и все вещи, которые сервер S отправил маршрутизатору X через порт 3313, были отправлены на компьютер AПочему, если я отправляю пакеты на маршрутизатор X через порт 3313, они не принимаются компьютером A !?

PS:

Обратите внимание, что все, что я здесь показал, на самом деле у меня есть три маршрутизатора X, Y и Z, а также у меня есть сервер S, компьютер A и компьютер B:

enter image description here

Ответы [ 4 ]

4 голосов
/ 04 сентября 2011

Ваш новый рабочий маршрутизатор, вероятно, отключен UPnP, следовательно, ваша нулевая ссылка.

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

Основные способы обойти это:

1) открыть UPnP

Это позволяет вашему приложению указывать маршрутизатору, как перенаправлять входящий трафик обратно на ваш сервер.

2) настроить переадресацию портов

Как указано выше при ручной настройке маршрутизатора.

3) сделать ваш рабочий сервер клиентом

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

4) использовать P2P (сервер-посредник)

Я не уверен, с чего бы вы начали, но принцип таков. Обычно он работает на одном порту UDP. Сервер, который не находится за NAT, используется для установления соединений. Клиенты отправляют свой IP на сервер в виде пакета UDP, а маршрутизатор перезаписывает заголовок UDP с обратным адресом маршрутизатора. Сервер берет эти данные и отправляет их другим узлам. Теперь, когда все знают обратный адрес друг друга, они могут отправлять TCP-трафик непосредственно друг другу, и сервер уходит.

Здесь есть действительно хорошая статья здесь об основах NAT, объясненная простыми словами. И хорошая статья здесь , в которой объясняется, как P2P использует NAT для обхода брандмауэров.

Надеюсь, это даст вам некоторые идеи.

3 голосов
/ 05 сентября 2011

Пробивание TCP часто не работает.Лучше всего придерживаться пробивания отверстий UDP.Если вам нужно поведение, подобное TCP, вы можете использовать RDP или аналогичный протокол, который обеспечивает поведение TCP, но может использовать UDP в качестве своего транспорта.

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

Лучшее решение будет, если вы сможете получить некоторую поддержку от маршрутизаторов, таких как переадресация портов или UPnP.

2 голосов
/ 07 сентября 2011

Вы можете написать свой собственный прокси:

Сервер: Прослушайте 1300 для соединения из A и 1301 для соединения из B. Сохраните список обоих соединений, если у вас есть хотя бы одно из них, создайте прокси-объект. В это время вы сообщаете о своем соединении от B, что у вас есть соединение, которое может быть сигнальным байтом или портом и даже адресом для подключения. После этого, когда вы получаете данные от A, отправьте их на B. Когда вы получите данные от B, отправьте их на A.

Компьютер B: Программа поддерживает соединение с портом 1301 на сервере. Если соединение когда-либо разрывается, восстановите его. Когда вы получаете сигнал (может иметь адрес и порт или просто быть байтом «У меня есть соединение»), создайте соединение с нужным портом и сохраните два соединения в прокси-объекте. Когда вы получаете данные от одного, отправьте их другому. Поскольку вы используете это соединение, установите новое соединение с портом 1301 на сервере для обработки большего количества данных.

Разумеется, вам придется обрабатывать разорванные соединения, и отправка сигнала поддержания активности между всегда открытым ожидающим соединением между B и сервером поможет.

Вот пример класса Я давно написал для проксирования. У меня нет времени на его очистку, но если вы видите TcpProxy, который является родительским классом, который принимает соединение, Client является принятым соединением, а RemoteEndPoint является конечной точкой для соединения. Он также записывает данные в файл и выполняет другие действия, которые вы можете игнорировать.

2 голосов
/ 04 сентября 2011

Есть отличная статья о технологиях перфорации UDP и TCP.

http://www.brynosaurus.com/pub/net/p2pnat/

Однако вам нужен хорошо известный сервер рандеву для этой техники дырокола, и яНе думаю, что вы хотите настроить это.

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

...