dreamTunnel пробрасывает порт вашего компьютера в публичный интернет через исходящее соединение. Настройка не нужна: при первом запуске устройство само получает свой токен и запоминает его. NAT, файрвол и CG-NAT не помеха. Каждому туннелю — свой HTTPS-поддомен, сертификат включён, переподключение при обрыве интернета — автоматическое.
iwr -useb https://tunnel.swag.best/install.ps1 | iex
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 (установщик проверяет их сам).
Без регистрации, конфигов и ключей. Установили — запустили — работает. Установщик сам кладёт бинарник в PATH.
Wildcard-сертификат на весь пул поддоменов *.maiuni.online. Браузер открывает туннель как обычный сайт — замок, зелёный, честный.
Обрыв интернета? Клиент переподключается сам: экспоненциальный бэкофф с джиттером, heartbeat каждые 10 секунд, сессия восстанавливается на тот же поддомен.
dt http 3000 my-api — получите https://my-api.maiuni.online. Без имени — случайный короткий поддомен из пула.
Каждое обращение к туннелю видно в консоли: метод, путь, код ответа, время выполнения — как у больших, только свои.
Один бинарник на Go: Windows, Linux, macOS — amd64 и arm64. Ставится скриптом, ничего не требует.
При первом запуске устройство регистрируется на сервере и получает личный токен, который хранит у себя. Никаких общих ключей, которые невозможно отозвать.
В панели управления — имя, платформа, IP, первый и последний визит, статус. Отзыв закрывает туннели устройства сразу, кнопка «бан IP» не пускает его обратно.
Туннель из кода: 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 панели, поэтому состояние устройств всегда согласовано с запущенным сервером.
Туннель можно поднять прямо из кода: 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 сервера. Никаких отдельных записей создавать не нужно — поддомены виртуальные, сервер раздаёт их динамически и следит, чтобы два клиента никогда не получили один и тот же.