Сетевое взаимодействие и обнаружение

Обнаружение и транспорты

У OpenClaw есть две различные проблемы, которые на первый взгляд выглядят схожими:

  1. Удалённое управление оператором: приложение в строке меню macOS управляет шлюзом, работающим в другом месте.
  2. Сопряжение узлов: iOS/Android (и будущие узлы) находят шлюз и безопасно с ним сопрягаются.

Цель проектирования — оставить всё сетевое обнаружение/анонсирование в Шлюзе Узла (openclaw gateway), а клиенты (mac-приложение, iOS) оставить в роли потребителей.

Термины

  • Шлюз (Gateway): единственный долгоживущий процесс шлюза, который владеет состоянием (сессии, сопряжение, реестр узлов) и запускает каналы. В большинстве настроек используется один на хост; возможны изолированные мультишлюзовые конфигурации.
  • Gateway WS (плоскость управления): конечная точка WebSocket на 127.0.0.1:18789 по умолчанию; может быть привязана к LAN/tailnet через gateway.bind.
  • Прямой WS транспорт (Direct WS transport): конечная точка Gateway WS, доступная в LAN/tailnet (без SSH).
  • SSH транспорт (резервный): удалённое управление через проброс 127.0.0.1:18789 по SSH.
  • Устаревший TCP мост (удалён): старый транспорт для узлов (см. Протокол моста); больше не анонсируется для обнаружения.

Детали протоколов:

Почему мы сохраняем и «прямой», и SSH

  • Прямой WS обеспечивает лучший пользовательский опыт в одной сети и внутри tailnet:
    • автообнаружение в LAN через Bonjour
    • токены сопряжения + ACL принадлежат шлюзу
    • не требуется доступ к оболочке; поверхность протокола может оставаться узкой и поддающейся аудиту
  • SSH остаётся универсальным резервным вариантом:
    • работает везде, где есть доступ по SSH (даже через несвязанные сети)
    • переживает проблемы с multicast/mDNS
    • не требует новых входящих портов, кроме SSH

Источники обнаружения (как клиенты узнают, где находится шлюз)

1) Bonjour / mDNS (только LAN)

Bonjour работает по принципу best-effort и не пересекает сети. Используется только для удобства в «одной LAN». Целевое направление:

  • Шлюз анонсирует свою WS конечную точку через Bonjour.
  • Клиенты просматривают и показывают список «выберите шлюз», затем сохраняют выбранную конечную точку.

Устранение неполадок и детали маячка: Bonjour.

Детали сервисного маячка

  • Типы сервисов:
    • _openclaw-gw._tcp (маячок транспорта шлюза)
  • TXT ключи (несекретные):
    • role=gateway
    • lanHost=<hostname>.local
    • sshPort=22 (или любой другой анонсируемый)
    • gatewayPort=18789 (Gateway WS + HTTP)
    • gatewayTls=1 (только когда включен TLS)
    • gatewayTlsSha256=<sha256> (только когда включен TLS и доступен отпечаток)
    • canvasPort=<port> (порт хоста canvas; в настоящее время совпадает с gatewayPort, когда хост canvas включен)
    • cliPath=<path> (опционально; абсолютный путь к исполняемой точке входа или бинарнику openclaw)
    • tailnetDns=<magicdns> (опциональная подсказка; определяется автоматически, когда доступен Tailscale)

Примечания по безопасности:

  • TXT записи Bonjour/mDNS не аутентифицированы. Клиенты должны рассматривать значения TXT только как подсказки для UX.
  • Маршрутизация (хост/порт) должна отдавать предпочтение разрешённой конечной точке сервиса (SRV + A/AAAA) перед указанными в TXT lanHost, tailnetDns или gatewayPort.
  • Прикрепление TLS никогда не должно позволять анонсированному gatewayTlsSha256 переопределять ранее сохранённый отпечаток.
  • Узлы iOS/Android должны рассматривать прямое подключение на основе обнаружения как только TLS и требовать явного подтверждения «доверять этому отпечатку» перед сохранением отпечатка при первом подключении (верификация вне канала).

Отключение/переопределение:

  • OPENCLAW_DISABLE_BONJOUR=1 отключает анонсирование.
  • gateway.bind в ~/.openclaw/openclaw.json управляет режимом привязки Gateway.
  • OPENCLAW_SSH_PORT переопределяет SSH порт, анонсируемый в TXT (по умолчанию 22).
  • OPENCLAW_TAILNET_DNS публикует подсказку tailnetDns (MagicDNS).
  • OPENCLAW_CLI_PATH переопределяет анонсируемый путь к CLI.

2) Tailnet (межсетевой)

Для настроек типа London/Vienna Bonjour не поможет. Рекомендуемая «прямая» цель:

  • Имя Tailscale MagicDNS (предпочтительно) или стабильный tailnet IP.

Если шлюз может определить, что работает под Tailscale, он публикует tailnetDns как опциональную подсказку для клиентов (включая широковещательные маячки).

3) Ручной / SSH целевой адрес

Когда нет прямого маршрута (или прямой отключён), клиенты всегда могут подключиться через SSH, пробросив локальный порт шлюза. См. Удалённый доступ.

Выбор транспорта (политика клиента)

Рекомендуемое поведение клиента:

  1. Если настроена и доступна конечная точка прямого подключения для сопряжённого устройства, использовать её.
  2. Иначе, если Bonjour находит шлюз в LAN, предложить выбор «Использовать этот шлюз» в одно нажатие и сохранить его как прямую конечную точку.
  3. Иначе, если настроено tailnet DNS/IP, попробовать прямое подключение.
  4. Иначе, перейти к резервному SSH.

Сопряжение + аутентификация (прямой транспорт)

Шлюз является источником истины для допуска узлов/клиентов.

  • Запросы на сопряжение создаются/одобряются/отклоняются в шлюзе (см. Сопряжение шлюза).
  • Шлюз обеспечивает:
    • аутентификацию (токен / пара ключей)
    • области действия/ACL (шлюз не является сырым прокси для каждого метода)
    • ограничение скорости

Ответственность по компонентам

  • Шлюз: анонсирует маячки обнаружения, принимает решения о сопряжении и размещает WS конечную точку.
  • macOS приложение: помогает выбрать шлюз, показывает запросы на сопряжение и использует SSH только как резервный вариант.
  • Узлы iOS/Android: просматривают Bonjour для удобства и подключаются к сопряжённому Gateway WS.

Сопряжение, управляемое шлюзомОбнаружение через Bonjour