Как службы туннелирования, такие как «Localtunnel», работают без SSH?

Я хочу понять, как мой локальный IP-адрес (localhost) может быть доступен в Интернете. Для этого я прочитал [здесь] метод проброс портов по SSH. Что в основном выполняет маршрутизацию с общедоступного сервера на наш локальный хост с использованием SSH.

Но мне интересно, как работает такой сервис, как «LocalTunnel»? В статье выше написано так:

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

Я пробовал читать код из репозитория github и понял следующее:

  • У этих служб есть общедоступный сервер, который генерирует разные URL-адреса, и когда мы нажимаем этот URL-адрес, он перенаправляет запрос на локальный хост, соответствующий этому URL-адресу.

  • Так что в основном это работает как прокси-сервер.

Правильно ли это понимание? Если да, то я не понимаю, как этот сервер имеет доступ к какому-то локальному хосту, работающему на моем компьютере? Как он выполняет запрос к нему? Что мне здесь не хватает? Вот код, на который я ссылался.


person Kaushal28    schedule 01.10.2018    source источник


Ответы (1)


Краткий ответ (TL;DR)

Remote (т. е. программное обеспечение localtunnel на вашем компьютере) инициализирует соединение с ретранслятором (т. е. localtunnel.me), действует как мультиплексирующий прокси, и когда клиенты (т. е. веб-браузеры) подключаются, ретранслятор мультиплексирует соединения между удаленными устройствами и клиентами, добавляя специальные заголовки с информацией о сети.

Browser <--\                   /--> Device
Browser <---- M-PROXY Service ----> Device
Browser <--/                   \--> Device

Видеопрезентация

Если вы предпочитаете предварительное видео, я только что рассказал об этом на UtahJS Conf 2018, в котором я также немного рассказал обо всех других потенциальных решениях: прокси SSH Socksv5 (о которых вы упомянули), VPN, UPnP, DHT, Реле и т.д.:

Возможность доступа: получайте доступ к своим устройствам, делитесь своими материалами

независимо

Слайды: http://telebit.cloud/utahjs2018

Как работают localtunnel, ngrok и Telebit (длинный ответ)

Я являюсь автором Telebit, который предоставляет сервис с функциями, аналогичными тем, которые предоставляют ngrok, localtunnel и libp2p (а также открытый исходный код как для удаленного/клиента, так и для ретранслятора/сервера, чтобы запустить его самостоятельно).

Хотя я не знаю точно внутренностей реализации localtunnel, я могу дать вам объяснение того, как это обычно делается (и как мы сделать это), и, скорее всего, это почти идентично тому, как они это делают.

Интересующая вас магия происходит в двух местах: в удаленном сокете и мультиплексоре.

Как удаленный клиент получает доступ к серверу на моем локальном хосте?

1. Удаленная розетка

Это довольно просто. Когда вы запускаете «удаленный» (telebit, ngrok и localtunnel в этом отношении работают почти одинаково), фактически ваш компьютер инициирует запрос.

Итак, представьте, что ретранслятор (прокси-сервер localtunnel в вашем случае) использует порт 7777 для получения трафика от «удаленных устройств» (например, вашего компьютера) и ваш номер сокета (случайно выбранный источник адрес на вашем компьютере) 1234:

Devices:  [Your Computer]          (tcp 1234:7777)          [Proxy Server]
Software:    [Remote]          ----------------------->        [Relay]
                                (auth & request 5678)

Однако клиенты (например, браузеры, netcat или другие пользовательские агенты), которые подключаются к вам, на самом деле также инициируют запросы к ретранслятору.

Devices:  [Proxy Service]            (tcp 5678)             [Client Computer]
Software:    [Relay]          <------------------------         [netcat]

Если вы используете tcp-порты, служба ретрансляции сохраняет внутреннее сопоставление, как и NAT.

Internal Relay "Routing Table"

Rule:
Socket remote[src:1234]    --- Captures ------>  ALL_INCOMING[dst:5678]

Condition:
Incoming client[dst:5678]  --- MATCHES ------->  ALL_INCOMING[dst:5678]

Therefore:
Incoming client[dst:5678]  --- Forwards To --->  remote[src:1234]

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

[Client Computer]  (tcp 5678)       [Proxy Service]      (tcp 1234)   [Your Computer]
   [netcat]      -------------->     <--[Relay]-->     <------------    [remote]

2. Мультиплексор

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

Browser <--\                   /--> Device
Browser <---- M-PROXY Service ----> Device
Browser <--/                   \--> Device

По сути, ретранслятор (т. е. прокси-сервер localtunnel) и удаленный сервер (т. е. ваш компьютер) помещают заголовок перед всеми данными, которые должны быть получены клиентом. Это должно быть что-то очень похожее на протокол PROXY HAProxy, но также работающее для нелокального трафика. Это может выглядеть так:

<src-address>,<src-port>,<sni>,<dst-port>,<protocol-guess>,<datalen>

Например

172.2.3.4,1234,example.com,443,https,1024

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

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

Подробнее см. https://www.npmjs.com/package/proxy-packer.

Боковое примечание/разглагольствование: Порты против TLS SNI

Первоначальное объяснение я дал с использованием портов tcp, потому что это легко понять. Однако localtunnel, ngrok и telebit могут использовать tls индикатор имени сервера (SNI) вместо того, чтобы полагаться на номера портов.

[Client Computer]        (https 443)       [Proxy Service]      (wss 443)   [Your Computer]
 [netcat+openssl]   -------------------->   <--[Relay]-->     <------------    [remote]
 (or web browser)  (sni:xyz.somerelay.com)                 (sni:somerelay.com)

MITM против p2p

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

Если вы используете только tls sni для маршрутизации (именно так работают localtunnel и ngrok по умолчанию, когда я последний раз проверял), весь трафик дешифруется на ретрансляторе.

Для другого способа требуется интеграция с ACME/Let's Encrypt (например, Greenlock.js), чтобы трафик остается сквозным шифрованием, направляя трафик tls клиенту без его расшифровки. Этот метод работает как одноранговый канал для всех практических целей (ретранслятор действует как еще один непрозрачный «переключатель» в сети Интернет, не знающий о содержимом трафика).

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

Теперь решения, основанные на libp2p, также обеспечивают виртуализированное одноранговое соединение, но оно гораздо более непрямое и требует маршрутизации через недоверенные стороны. Я не сторонник этого, потому что обычно он медленнее и я считаю его более рискованным. Я твердо верю, что в долгосрочной перспективе сетевая федерация победит анонимизацию (например, libp2p). (для нашего варианта использования нам нужно было что-то, что можно было бы объединить — управлять независимыми доверенными сторонами — поэтому мы построили наше решение так, как мы это сделали)

person coolaj86    schedule 02.10.2018