Ваш локальный сервер — в интернете за одну команду

dreamTunnel пробрасывает порт вашего компьютера в публичный интернет через исходящее соединение. Настройка не нужна: при первом запуске устройство само получает свой токен и запоминает его. NAT, файрвол и CG-NAT не помеха. Каждому туннелю — свой HTTPS-поддомен, сертификат включён, переподключение при обрыве интернета — автоматическое.

Установка

Windows — PowerShell
iwr -useb https://tunnel.swag.best/install.ps1 | iex
Linux / macOS
curl -fsSL https://tunnel.swag.best/install.sh | bash
Запуск туннеля
dt http 8080

  dreamTunnel — tunnel online

  Forwarding   https://my-site.maiuni.online -> http://127.0.0.1:8080
  Connections  https://my-site.maiuni.online

  Press Ctrl+C to stop

  GET /          200 OK        12.4ms
  GET /api        200 OK         3.1ms

Одна команда — и любой HTTP-сервер на порту 8080 доступен по адресу https://my-site.maiuni.online. Валидный сертификат уже включён: никаких предупреждений браузера. В терминале видно каждый запрос: метод, путь, код ответа и время.

Настраивать ничего не нужно: при первом запуске клиент регистрирует это устройство на сервере, получает личный токен и сохраняет его в ~/.dreamtunnel/config.env — dt login и переменные окружения нужны только для своего сервера. Прямые ссылки на сборки (Linux, macOS, Windows · x86_64/arm64) — tunnel.swag.best/dl/, контрольные суммы в /dl/SHA256SUMS (установщик проверяет их сам).

Возможности

01

Одна команда

Без регистрации, конфигов и ключей. Установили — запустили — работает. Установщик сам кладёт бинарник в PATH.

02

HTTPS без предупреждений

Wildcard-сертификат на весь пул поддоменов *.maiuni.online. Браузер открывает туннель как обычный сайт — замок, зелёный, честный.

03

Не падает

Обрыв интернета? Клиент переподключается сам: экспоненциальный бэкофф с джиттером, heartbeat каждые 10 секунд, сессия восстанавливается на тот же поддомен.

04

Своё имя поддомена

dt http 3000 my-api — получите https://my-api.maiuni.online. Без имени — случайный короткий поддомен из пула.

05

Живые логи запросов

Каждое обращение к туннелю видно в консоли: метод, путь, код ответа, время выполнения — как у больших, только свои.

06

Кроссплатформенно

Один бинарник на Go: Windows, Linux, macOS — amd64 и arm64. Ставится скриптом, ничего не требует.

07

Свой токен на устройство

При первом запуске устройство регистрируется на сервере и получает личный токен, который хранит у себя. Никаких общих ключей, которые невозможно отозвать.

08

Видно каждое устройство

В панели управления — имя, платформа, IP, первый и последний визит, статус. Отзыв закрывает туннели устройства сразу, кнопка «бан IP» не пускает его обратно.

09

Python SDK на PyPI

Туннель из кода: pip install dreamtunnel. SDK сам скачивает dt, дожидается готовности релея и отдаёт публичный адрес как атрибут.

Как это работает

  ваш компьютер                          сервер dreamTunnel                 браузер
  ┌─────────────┐   исходящее TLS    ┌──────────────────────┐    HTTPS    ┌─────────┐
  │ dt http 8080├───────────────────>│ :444 control-канал   │<────────────┤ визитёр  │
  │ локальный   │<───────────────────┤ :8453 edge + wildcard├────────────>│ на сайт  │
  │ web-сервер  │   стримы данных    │ сертификат *.maiuni  │             └─────────┘
  └─────────────┘                    └──────────────────────┘
       NAT / CG-NAT / файрвол — не проблема: всё соединение инициирует клиент

Документация

Команды

КомандаЧто делает
dt http 8080Туннель к локальному HTTP-серверу на порту 8080. Поддомен — случайный.
dt http 8080 my-apiТо же, но с постоянным именем: https://my-api.maiuni.online
dt http 8080 --server host:portУказать другой сервер dreamTunnel.
dt tcp 25565Сырой TCP-туннель (например, игровой сервер).
dt http 8080 --jsonМашинный вывод: события NDJSON на stdout (enrolled, ready, disconnected, error…) — для скриптов и SDK.
dt loginНеобязательно: сохранить свой сервер и токен в ~/.dreamtunnel/config.env.
dt configПоказать конфигурацию: сервер, id этого устройства, поддомен, сессию, путь к файлу.
dt enrollПолучить для этого устройства новый токен — после переноса, переустановки или если токен отозвали.
dt devices listНа сервере: список устройств со статусом. Ещё dt devices revoke <id> [--ban-ip] и dt devices restore <id>.

Переподключение

Клиент держит контрольный канал с сервером и обменивается heartbeat-сообщениями. Если связь пропала — Wi-Fi мигнул, ноутбук уснул, провайдер перебрал кабель — клиент сам начинает переподключение: 1с, 2с, 4с… до 60с максимум, со случайным джиттером, чтобы толпа клиентов не валилась на сервер одновременно.

Сессия хранится локально (файл ~/.dreamtunnel/config.env или свой DT_CONFIG на каждый процесс, поэтому несколько туннелей на одной машине не мешают друг другу). После восстановления клиент получает тот же поддомен — ссылки не ломаются. Активные TCP-соединения внутри туннеля при обрыве пересоздаются (это свойство TCP), но сам туннель и URL остаются прежними.

Токен доступа

Из коробки настраивать ничего не нужно: в бинарник dt вкомпилирован токен регистрации, поэтому dt http 8080 работает сразу после установки. Но это только пропуск на регистрацию: при первом запуске клиент просит сервер выдать токен для этого устройства, сохраняет его и дальше ходит только с ним.

Порядок поиска токена: файл ~/.dreamtunnel/config.env → переменная DT_TOKEN → встроенный токен регистрации. Адрес сервера задаётся так же: --server host:port или DT_SERVER. Перерегистрировать устройство (новый токен) — dt enroll, посмотреть свой id — dt config.

Владелец сервера: токен регистрации задаётся строкой DT_ENROLL_TOKEN в /etc/dreamtunnel/server.conf (он и попадает в релизные сборки). DT_REQUIRE_DEVICE_TOKENS=1 запрещает этому токену открывать туннели — только регистрация устройств. Выданные токены лежат в /var/lib/dreamtunnel/devices.json (путь меняется DT_DEVICES_FILE) в виде хешей, в открытом виде они не хранятся нигде. dt token <секрет> печатает обфусцированную форму приватного токена; мастер-секрет остаётся только на сервере.

Устройства

Каждое устройство получает свой токен при первом запуске — вместе с записью в панели управления: имя (hostname), платформа, IP, время первой и последней связи, статус — на связи, не в сети или отозвано. Пароли и токены в панели не показываются: сервер хранит только хеши.

Отзыв закрывает все туннели устройства немедленно и запрещает подключаться с его токеном. Кнопка «Отозвать + бан IP» дополнительно блокирует адрес — это единственный надёжный способ не пустить устройство обратно, потому что токен регистрации всё ещё вкомпилирован в бинарник и позволяет завести новое устройство с того же адреса.

То же из терминала на сервере: dt devices list, dt devices revoke <id> [--ban-ip], dt devices restore <id>. Команды работают через API панели, поэтому состояние устройств всегда согласовано с запущенным сервером.

Python SDK

Туннель можно поднять прямо из кода: SDK запускает и присматривает за процессом dt, дожидается подтверждения от релея, отдаёт публичный адрес и сообщает о переподключениях. Бинарник dt SDK скачает сам при первом запуске, а устройство зарегистрируется автоматически.

pip install dreamtunnel
from dreamtunnel import Tunnel

with Tunnel(port=8080, subdomain="my-api") as tun:
    print(tun.url)         # https://my-api.maiuni.online
    print(tun.device_id)   # id этого устройства на сервере
    # ... работает ваше приложение, туннель живёт
# выход из блока — туннель закрыт

События и управление вручную:

tun = Tunnel(port=8080, on_event=lambda e: print(e["event"]))
tun.start()
tun.connected   # True, пока туннель на связи
tun.restart()   # перезапуск с тем же адресом
tun.stop()      # корректно гасит процесс

Пакет опубликован на PyPI: pypi.org/project/dreamtunnel. Исходники — в папке sdk/python репозитория. Готовые примеры: Flask, FastAPI и обычный http.server.

Свой сервер

Релей — это тот же бинарник: dt server. Конфиг в /etc/dreamtunnel/server.conf (секрет, домен, порты, логин/пароль админки). systemd-юнит и wildcard-сертификат через acme.sh DNS-01 — всё как в описании проекта на GitHub.

Устройствами сервер управляет сам: выдаёт персональные токены при первом подключении, ведёт их список и умеет отзывать. Панель администратора показывает активные туннели, историю, трафик и блокировки — на 127.0.0.1:8484, наружу её выставлять не нужно. Строка DT_REQUIRE_DEVICE_TOKENS=1 закрывает туннели по общему токену регистрации, DT_DEVICES_FILE задаёт путь к списку устройств.

Пул поддоменов реализован wildcard-записью DNS: *.maiuni.online → IP сервера. Никаких отдельных записей создавать не нужно — поддомены виртуальные, сервер раздаёт их динамически и следит, чтобы два клиента никогда не получили один и тот же.