Как подключиться к серверу без белого IP через обратный SSH-туннель
У вас есть машина без белого IP — домашний ПК, сервер в офисе или арендованный риг за NAT. Снаружи к ней не подключиться: провайдер не выдал внешний адрес, а проброс портов на роутере — это возня и лишний риск. На мобильных и части домашних тарифов проброс вообще невозможен: адрес выдан за CGNAT, наружу смотрит шлюз провайдера. «Удалённый доступ» решает это одной командой: вы заходите на свой сервер по SSH через хаб vast.sale — откуда угодно, включая телефон.
По этой схеме мы обслуживаем серверы клиентов на бирже Vast.ai. Поломки, о которых ниже, мы сначала ловили на собственном парке — шесть машин от одиночной RTX 5090 до сервера с четырьмя RTX 4090 на EPYC 7C13. Ниже: как устроено, сколько стоит по задержке, что схема закрывает и чего не закрывает принципиально. Доход этих машин открыт на странице парка.
Как это работает
Ключевая идея — соединение всегда исходящее. Ваша машина сама открывает защищённый канал к хабу (узел-посредник) и держит его. На вашей стороне ничего не «слушает» интернет: не нужен белый IP, не нужен проброс портов, наружу не открывается ни одного порта. Когда нужно подключиться — вы идёте к своему серверу через хаб, как будто он стоит рядом.
В деталях на машине появляется одна служба: SSH-соединение к хабу с обратным перенаправлением порта — «слушай у себя вот этот порт и всё, что в него придёт, отдавай мне на локальный 22». Соединение держит autossh, службу после ребута поднимает systemd. Это штатный OpenSSH, который на сервере уже стоит, без закрытых протоколов и облачных агентов.
- Вы запускаете на сервере одну команду — она поднимает зашифрованный исходящий туннель.
- Канал инициирует сама машина — он работает за NAT, CGNAT, роутером и файрволом.
- На хабе обратный порт слушается только на 127.0.0.1 — снаружи хаба его не видно (GatewayPorts no).
- Канальный ключ урезан опциями restrict и port-forwarding с одним портом, учётка на хабе — без шелла.
- Пара ключей на каждый сервер своя: закрыли доступ к одной машине — остальные не тронуты.
- Подключаетесь через хаб — по SSH с компьютера или прямо в браузере.
Чем это отличается от других способов
| способ | нужен белый IP | что открыто наружу | работает за CGNAT | чей узел в середине |
|---|---|---|---|---|
| проброс порта на роутере | да | порт SSH/RDP | нет | нет |
| белый IP за доплату | да | весь хост целиком | — | нет |
| VPN до дома | да, на стороне сервера | порт VPN | нет | ваш роутер |
| обратный туннель до своего VPS | нет | ничего | да | ваш VPS |
| туннель до хаба vast.sale | нет | ничего | да | наш хаб |
| «удалёнка» с агентом | нет | ничего | да | чужое облако |
Разница между четвёртой и пятой строкой только в том, кто администрирует середину. Механика одна: есть свой VPS и желание держать на нём учётку без шелла, урезанный ключ и наблюдение за живостью туннеля — делайте свой хаб, мы разобрали такую схему в платном руководстве про резервный туннель. Наш хаб — для тех, кому не нужен ещё один сервер.
Почему это безопасно
- Ничего не открывается наружу — только исходящий канал: сервер не попадает в списки сканеров.
- Изоляция: у каждого свой канал и свой порт на loopback хаба, дотянуться можно только до своих серверов.
- Всё в шифровании — трафик идёт по SSH, хаб его не расшифровывает. Оговорка: в терминале в браузере SSH-сессию открывает сервер vast.sale, и он видит то же, что вы на экране; нужна сквозная защита — подключайтесь своим SSH-клиентом по «Набору для подключения».
- Персональные ключи с ограничениями: канальный ключ умеет только перенаправление одного порта.
- Контроль у вас: одна команда полностью удаляет туннель и служебную учётную запись.
- Статус канала виден в кабинете; без вашей команды установки ничего не происходит.
Одну вещь мы не прячем: служебная учётная запись имеет права sudo, причём без пароля. Без них нельзя ни обновить драйвер, ни перезапустить агента биржи, ни собрать диагностику — то есть нельзя сделать то, за чем доступ и нужен. Поэтому важны не обещания, а два проверяемых факта: ключ на каждый сервер отдельный, и удаление делается с вашей стороны в один шаг.
Задержка и трафик: что это стоит
| что мерили | значение | как получено |
|---|---|---|
| отклик от нашей домашней линии до хаба в Стокгольме | 12 мс | ping, 20 пакетов, 10.10.2026 |
| трафик простаивающего канала | keepalive раз в 30 с | ServerAliveInterval=30 в службе канала |
| восстановление после обрыва | через 15 с, без ограничения попыток | Restart=always, RestartSec=15 |
Практический вывод: комфорт в терминале определяет задержка, а не скорость, и задержка в десятки миллисекунд при наборе команд не ощущается — у нас до хаба 12 мс. Ощущаются на файловых менеджерах, перерисовывающих экран, и на длинном выводе логов — лечится привычкой писать tail -n 200 вместо tail -f. Простаивающий туннель шлёт только keepalive. Замерить линию до установки поможем на бесплатной консультации, а прикинуть, что машина принесёт, — в калькуляторе дохода.
Терминал в браузере
Кнопка «Терминал» в кабинете удалённого доступа открывает SSH-сессию прямо в браузере: xterm.js, соединение по WebSocket, дальше тот же обратный туннель. Клиент ставить и ключи возить не надо, с телефона работает. Клавиши буфера мы довели вручную, в стиле PuTTY:
- Копировать: выделить мышью — текст сразу в буфере; либо Ctrl+Insert, либо Ctrl+Shift+C.
- Вставить: правый клик, либо Shift+Insert, либо Ctrl+Shift+V.
- Ctrl+C намеренно оставлен как SIGINT, а не копирование.
- В Firefox правый клик не вставляет: браузер не даёт странице читать буфер, там нативный Ctrl+V.
- Копирование работает во всех браузерах, но только по HTTPS.
Что удалённый доступ лечит, а что нет
| поломка из нашего журнала | видна снаружи | лечится по SSH | нужны руки |
|---|---|---|---|
| залипший контроллер биржи: 4 машины 25.08 | числится неактивной | да, сброс кэша адреса | нет |
| крон биржи стирает VM-флаг, когда все карты в vfio | оффер перестаёт быть VM | да, вернуть флаг | нет |
| агент повис на вызове веб-API без таймаута | нет, канал идеален | да, перезапуск службы | нет |
| туннель поднялся раньше адреса по DHCP | ложный переход на резервный VPS | да, правило маршрутизации | нет |
| мёртвая планка памяти, memtest чист | нет, машина работает | нет | да, перестановка модулей |
| карта не вернулась из проброса | GPU исчезла из списка | нет | да, холодная перезагрузка |
Первые четыре строки — ровно то, ради чего схема существует: случаются в произвольный момент, чинятся за минуты и стоят денег, пока вы о них не знаете. Случай из журнала: наша машина с двумя RTX 5080 простояла без режима виртуальных машин десять дней — с 19:22 одиннадцатого сентября до 17:04 двадцать первого — крон биржи стирал флаг, а заметить это можно было только зайдя на сервер. Разбор со сторожем — в статье про залипший контроллер, команды для диагностики — в шпаргалке по Linux.
Последние две строки — предел любого удалённого доступа. Мёртвую планку памяти на сервере с четырьмя RTX 4090 мы искали неделями: memtest проходил чисто, ядро молчало, а машина падала под нагрузкой; доказали перестановкой модулей по слотам и подменой на swap — руками, на месте. Поэтому работы делим прямо: настройка, диагностика и большинство отказов — удалённо, физика — с вашим участием или выездом.
Где мы ошиблись
Схема выглядит простой, но до текущей версии мы дошли через четыре ошибки, и каждая стоила простоя. Первая — канал управления через тот же туннель, что и рабочий трафик. Двадцатого сентября один риг запустил туннель раньше, чем получил адрес по DHCP: пакет к VPS ушёл в ещё не готовый интерфейс, и клиент начал открывать сокеты волнами — около 28 тысяч, практически весь диапазон исходящих портов. Забилась таблица соединений домашнего роутера, обрывы пошли у всех ригов за ним, четыре решили, что VPS умер, и ушли на резервный, хотя сломан не был ни один. Вывод жёсткий: доступ, которым вы чините туннель, не должен идти через этот туннель.
Вторая — проверка, которая проверяла саму себя. Скрипт автоперехода «пинговал» нетекущий VPS и получал ответ за 1–8 миллисекунд, то есть считал его живым всегда: отвечал локальный интерфейс туннеля, который принимает пакет и никуда его не отдаёт. Переходы на резерв делались вслепую. В версии от двадцатого сентября проверка стала настоящей и даёт честные 36–46 миллисекунд, а порог поднят с трёх подряд неудачных попыток до девяти — при трёх хватало обычной помехи на домашнем канале. С 7 октября автопереход мы выключили совсем: резервный VPS снят, переключение делает человек.
Третья — хаб у дешёвого хостера. Скорость загрузки режется не по адресу, а по автономной системе хостера целиком: у нас OVH и M247 были задушены до неработоспособности, а Private Layer — чист при полностью одинаковом конфиге. День ушёл на переборку параметров, прежде чем мы сравнили двух хостеров с одним файлом настроек. В терминале это видно сразу: на задушенной AS текст печатается рывками. И список меняется: 6 октября TCP-трафик из сети VEESP, где стоит наш хаб, тоже стали резать, а OVH к тому времени снова работал. Хаб выбирайте по замеру с вашей линии, а не по цене, и перемеряйте; про канал — отдельный разбор.
Четвёртая — мы выпустили браузерный терминал, ни разу не попробовав в нём скопировать текст. Жалоба пришла от клиента: «в консоль вставить могу, а скопировать — нет». В шаблоне не было ни одной строки про буфер обмена: вставку xterm.js делает сам, а копирование из коробки не подключает — выделение видно, в буфер не попадает. Урок не про xterm.js: приёмка «соединение встало, приглашение bash пришло» не проверяет ничего, проверять надо сценарий целиком.
Как начать
Порядок простой и занимает пару минут. Требуется Ubuntu или Debian с systemd и правами sudo: установщик ставит пакеты через apt. Если SSH-сервера на машине нет, он его поставит и включит — туннелю нужно куда вести; за NAT снаружи он по-прежнему не виден, а при белом IP закройте порт 22 файрволом. Ubuntu 22.04 Server мы проверяем в первую очередь, потому что сами ставим на риги только её. Если сервера ещё нет — бесплатная пошаговая установка Ubuntu.
- Зарегистрируйтесь или войдите — по e-mail или через Telegram.
- Откройте раздел «Удалённый доступ».
- Возьмите пробный сервер бесплатно или оформите подписку.
- Скопируйте команду установки и выполните её на своём сервере (Linux, с правами sudo) — больше ничего настраивать не нужно.
- Дождитесь статуса «на связи» — обычно несколько секунд.
- Подключайтесь: кнопкой «Терминал» прямо в браузере или через «Набор для подключения» для SSH с вашего компьютера.
# одна команда установки на вашем сервере (точную ссылку берите в кабинете)
curl -fsSL https://vast.sale/remote/dl/ВАША-ССЫЛКА -o podkl.sh && sudo bash podkl.sh
Скрипт идемпотентен: повторный запуск ничего не ломает и второй службы не плодит. Результат видно на самой машине, без кабинета:
# служба туннеля: точное имя печатает установщик
systemctl list-units 'vast*' --no-pager
journalctl -u vast-tunnel -n 20 --no-pager
# исходящее соединение до хаба (наружу ничего не слушаем)
ss -tnp | grep -i ssh
ss -ltn # новых внешних слушателей здесь появиться не должно
Управление и отключение
- Статус, продление и оплата — в кабинете, вкладка «Серверы».
- Автопродление со счёта — по желанию и с явным согласием.
- Отвязать в любой момент: одна команда полностью убирает туннель и служебную учётную запись с вашей машины; пакеты autossh и OpenSSH остаются как обычные системные.
- Давали доступ подрядчику и работы закончились — отзыв точечный: закрывается ключ одного сервера.
# полностью удалить служебный доступ с вашего сервера
sudo vast-service-remove
Коротко
- Белый IP и проброс портов не нужны: соединение всегда исходящее, за CGNAT работает как за обычным NAT, наружу не открывается ничего
- Комфорт в терминале определяет задержка: от нашей линии до хаба 12 мс
- Схема закрывает всё, что чинится командой: залипший контроллер, стёртый VM-флаг, повисший агент, кривой маршрут
- Физику не закрывает: планку памяти и карту, не вернувшуюся из проброса, лечили руками
- Канал управления не должен зависеть от туннеля, который вы через него настраиваете — за это мы заплатили ложным переходом 4 машин
Новости и разборы рынка GPU — в нашем Telegram-канале @flux_vast_news