Техническая информация о работе туннеля VPS

Эксплуатационное руководство для DevOps: что где работает, как держится туннель, как обновляются бинарники, как синхронизируются сессии и логи.

1. Зачем это нужно

Демоны мессенджеров (WhatsApp = chatsd, Telegram = tgd, MAX = maxd) держат постоянное соединение с серверами WhatsApp/Telegram. В сетях с DPI это соединение глушится. Поэтому демоны переносятся на VPS в "чистой" локации, а сама MikoPBX остается "мозгом": gnatsd, лицензия, 1С-интеграция, телефония и супервизор работают как раньше.

Связь между PBX и VPS - один исходящий SSH-туннель. Оператор включает вынос тремя тумблерами в веб-интерфейсе модуля (отдельно WhatsApp / Telegram / MAX) и указывает адрес VPS + SSH-ключ. Дальше все происходит автоматически: провижининг, поднятие туннеля, миграция сессий, зеркалирование и сбор логов.

2. Общая схема

МИКО: Схема связи АТС с VPS

3. Что где работает

Компонент Где Назначение
gnatsd-cti (NATS :4222 + HTTP-шлюз/лицензия :8222) PBX Шина сообщений и единственная точка входа 1С. Никогда не переносится.
monitord (local) PBX Супервизор всего стека + маршрутизатор каналов. Владеет SSH-туннелем (см. раздел 4).
amid, crmd, authd, proxyd, speechd PBX AMI, 1С-CRM, авторизация, прокси, распознавание речи. Не переносятся.
chatsd / tgd / maxd PBX или VPS Демоны мессенджеров. Уезжают на VPS по тумблеру (поканально-посервисно). Пока тумблер OFF - работают локально.
monitord (remote, "тонкий") VPS Запускает/перезапускает демоны на VPS, отдает их статус и проксирует /chats/*. Стартует с daemons=[], слушает только loopback (127.0.0.1:8225).
WorkerRemoteTunnel (PHP-воркер) PBX Провижининг VPS, запуск remote-monitord, зеркало сессий, сбор логов, авто-failback. Сам туннель не держит - этим занят monitord.

Лицензия (feature 42) выдается gnatsd на PBX. На VPS демоны получают ее через туннель - поэтому standalone на VPS они не работают, им всегда нужен живой туннель к PBX.

4. Туннелирование трафика

SSH-туннель устанавливает и держит monitord на стороне PBX (встроенный ssh.Client с авто-реконнектом и keepalive). Параметры подключения PHP-модуль рендерит в блок ssh_tunnel внутри monitord.json - при любой регенерации конфига туннель сохраняется. Прежняя схема с отдельным процессом ssh -N в PHP-воркере больше не используется.

Транспорт - обычный SSH на порт 22 (настраивается полем remote_ssh_port), аутентификация - приватным ключом. Поверх одного соединения работают три фиксированных форварда - их число не зависит от количества каналов:

Форвард Направление Зачем
-R 4222
reverse
VPS loopback -> PBX На VPS 127.0.0.1:4222 ведет на NATS PBX. Демоны - NATS-клиенты, сами дозваниваются до шины. Через NATS идут пинги monitord и live-фид событий.
-R 8222
reverse
VPS loopback -> PBX На VPS 127.0.0.1:8222 ведет на HTTP-шлюз/лицензию PBX. Закрывает "вшитый" в демоны адрес проверки лицензии 127.0.0.1:8222 (feature 42).
-L 8226
local
PBX -> VPS:8225 На PBX 127.0.0.1:8226 ведет на manager.api удаленного monitord (его :8225). По нему local-monitord проксирует /chats/* и собирает статус каналов с VPS.

Путь запроса 1С к удаленному каналу

1С -> gnatsd :8222 -> monitord local :8225 -> форвард -L :8226 -> VPS monitord :8225 -> демон на VPS :8228 -> WhatsApp/TG/MAX

Для 1С путь неотличим от локального: она по-прежнему обращается только к :8222. Решение "локально или на VPS" monitord принимает по метке location канала.

5. Справочник портов

Порт Хост Доступность Что это
22 VPS входящий SSH (только от PBX) Транспорт туннеля. Настраивается (remote_ssh_port).
4222 PBX loopback + reverse-форвард NATS / шина сообщений.
8222 PBX открыт в firewall (вход 1С) + reverse-форвард HTTP-шлюз gnatsd + лицензия. Единственная точка входа 1С.
8225 PBX и VPS только loopback manager.api монитора (статус, маршрутизация, /chats/*). На VPS забинден на 127.0.0.1 - наружу не торчит.
8226 PBX только loopback Local-форвард на :8225 удаленного monitord. Наличие LISTEN на 8226 = туннель сконфигурирован.
8228+ VPS внутри VPS Динамические порты каналов. Проксируются remote-monitord, отдельных форвардов не требуют.

6. Обновление бинарников на VPS

Бинарники на VPS - те же linux/amd64-файлы, что и на PBX (пересборки нет). Провижининг кладет их в {base}/bin/ (где {base} = remote_bin_dir, по умолчанию /opt/mikopbx-cti) вместе со сгенерированными конфигами в {base}/conf/.

Как обновление "доезжает" до VPS

  • В {base}/bin/.version хранится штамп версии модуля, развернутой на VPS.
  • При апгрейде модуля локальные бинарники заменяются. Воркер сравнивает локальную версию со штампом на VPS; при расхождении - принудительный re-push (без расхождения сверяется только размер файла, лишний трафик не гоняется).
  • Заливка идет через temp-файл + rename - чтобы перезапись работающего бинарника не уперлась в ETXTBSY.
  • После того как новые бинарники легли, затронутые демоны на VPS перезапускаются (полный рестарт remote-monitord либо pkill конкретных дочерних) - иначе на VPS продолжил бы крутиться старый код.
  • Штамп .version пишется только после полного успешного провижининга - если апгрейд оборвался посередине, на следующем тике он повторится.

7. Синхронизация сессий (авторизация)

Вся авторизация мессенджера лежит в файлах сессии и переживает перенос между хостами и смену IP/гео без повторной авторизации (проверено round-trip-тестом):

Сервис Файл авторизации Каталог
WhatsApp <area>-whatsappSession.db (SQLite) {base}/db/chats/
Telegram <area>-tgSession.json {base}/db/tg/
MAX <area>-max_session.json {base}/db/max/

Миграция (по тумблеру)

При включении/выключении выноса сессия копируется в нужную сторону:

стоп источника -> tar-over-ssh пофайлово по area (<area>-*) + сверка sha256 -> старт приемника -> флип метки location

Жесткое правило: один и тот же канал никогда не запускается одновременно на обеих сторонах - это разлогинило бы сессию.

Теплое зеркало (постоянно)

Пока канал на VPS, воркер периодически копирует сессию VPS -> PBX. Локальная копия всегда наготове.

Зачем: если VPS внезапно пропал, авторизация не теряется - ее свежая копия уже лежит на PBX, и сервис можно поднять локально без повторного сканирования QR.

8. Синхронизация логов

Демоны на VPS пишут логи в {base}/logs/<service>/ - локально на PBX их не видно, и штатный просмотр System -> Logs их бы не показал. Поэтому воркер инкрементально подкачивает их на PBX.

  • Инкрементально по offset - тянется только "хвост" файла (новые байты), а не весь лог. Экономия трафика через туннель.
  • Куда: logDir/ModuleCTIClient/<service>-<host>/, где <host> - это remote_host (IP/имя VPS, очищенное до [A-Za-z0-9._-]). Отдельная папка с именем хоста исключает коллизию с локальным логом того же сервиса и сразу показывает источник.
  • Условие закачки: канал реально на VPS (side == remote) и туннель connected. Каденция ~60 с (реже, чем зеркало сессий).
  • Видимость "бесплатно": System -> Logs сканирует logDir рекурсивно, поэтому подкачанные файлы появляются в списке и доступны на просмотр/скачивание без доработки ядра.
  • Локальный накопительный файл ротируется по размеру; штатная 7-дневная чистка убирает старье.

9. Поведение при потере VPS

Что отказало Что происходит
VPS / туннель недоступны Локальная телефония, CRM и не-вынесенные мессенджеры не страдают. По вынесенным каналам приостанавливаются и отправка, и прием (data-plane идет по HTTP через туннель): исходящие из 1С падают по таймауту.
Входящие сообщения во время простоя Не теряются: WhatsApp/Telegram держат бэклог у себя; демон на VPS вытянет пропущенное после реконнекта, 1С увидит это при следующем поллинге.
Данные авторизации В безопасности - теплое зеркало (раздел 7) держит свежую копию сессии на PBX.
Долгий простой VPS Предусмотрен авто-failback на локаль по таймауту (remote_failback_after_sec, по умолчанию 7200 с) - поднимает сервис из локальной копии сессии. Часть фенсинга - owner-lock на VPS - на момент написания дорабатывается.

10. Эксплуатация и диагностика

Проверки на PBX

# Жив ли супервизор (он же - владелец туннеля)
pgrep -a monitord

# Статус туннеля (configured/connected/last_ok_ts/attempts)
curl -s http://127.0.0.1:8225/manager.api/tunnel/status

# Local-форвард на удаленный monitord должен слушать - признак, что туннель сконфигурирован
ss -tlnp | grep 127.0.0.1:8226

# Сводный статус всех каналов (как его видит 1С): local + remote вместе
curl -s http://127.0.0.1:8222/manager.api/status

Как выглядит "здоровый" туннель

{
  "result": {
    "configured": true,
    "connected": true,
    "state": "connected",
    "last_ok_ts": 1781677831,
    "last_error": "",
    "attempts": 1
  }
}

На что смотреть при разборе инцидента

  • connected:false + растущий attempts -> SSH до VPS не встает: проверить сеть/firewall до VPS :22, ключ, что VPS жив.
  • Туннель connected, но канал в error -> демон на VPS падает: смотреть подкачанный лог logDir/ModuleCTIClient/<service>-<host>/ (System -> Logs).
  • Канал в состоянии qrcode -> нужна (повторная) авторизация: QR доступен прямо в UI модуля.
  • После апгрейда модуля канал на старом поведении -> проверить, что {base}/bin/.version на VPS совпал с версией модуля (иначе re-push не прошел - см. раздел 6).