Skip to content
Эта страница создана и переведена с помощью ИИ. Если вы заметили неточности, помогите нам улучшить её. Редактировать на GitHub

Туннели и NAT-обход

Агентам PRX часто необходимо принимать входящие соединения -- обратные вызовы вебхуков от GitHub, обновления Telegram, события Slack или межузловая коммуникация. При работе за NAT или файрволом подсистема туннелирования обеспечивает автоматический входящий доступ, устанавливая исходящее соединение к провайдеру туннеля и отображая публичный URL на ваш локальный экземпляр PRX.

Зачем нужно туннелирование

Многие функции PRX требуют публично доступного эндпоинта:

  • Каналы вебхуков -- Telegram, Discord, Slack и GitHub отправляют события на указанный вами URL. Без публичного эндпоинта эти каналы не смогут доставлять сообщения вашему агенту.
  • Обратные вызовы OAuth2 -- Потоки аутентификации провайдера перенаправляют браузер на локальный URL. Туннели позволяют это работать даже когда PRX запущен в приватной сети.
  • Межузловая коммуникация -- Распределённые развёртывания PRX требуют, чтобы узлы могли связываться друг с другом. Туннели соединяют узлы в разных сетях.
  • Хостинг MCP-сервера -- Когда PRX выступает MCP-сервером для внешних клиентов, туннель предоставляет публичный эндпоинт.

Поддерживаемые бэкенды

PRX поставляется с четырьмя бэкендами туннелей и заглушкой no-op:

БэкендПровайдерБесплатный планСвой доменТребуется авторизацияZero-Trust
Cloudflare TunnelCloudflareДаДа (с зоной)Да (cloudflared)Да
Tailscale FunnelTailscaleДа (личный)Через MagicDNSДа (аккаунт Tailscale)Да
ngrokngrokДа (ограниченно)Да (платно)Да (токен авторизации)Нет
Пользовательская командаЛюбойЗависитЗависитЗависитЗависит
Нет----------

Архитектура

Подсистема туннелирования построена на трейте Tunnel:

rust
#[async_trait]
pub trait Tunnel: Send + Sync {
    /// Start the tunnel and return the public URL.
    async fn start(&mut self) -> Result<String>;

    /// Stop the tunnel and clean up resources.
    async fn stop(&mut self) -> Result<()>;

    /// Check if the tunnel is healthy and the public URL is reachable.
    async fn health_check(&self) -> Result<bool>;
}

Каждый бэкенд реализует этот трейт. Структура TunnelProcess управляет базовым дочерним процессом (например, cloudflared, tailscale, ngrok) -- обрабатывая запуск, захват stdout/stderr, корректное завершение и автоматический перезапуск при сбое.

┌─────────────────────────────────────────────┐
│                PRX Gateway                   │
│            (localhost:8080)                   │
└──────────────────┬──────────────────────────┘
                   │ (локально)
┌──────────────────▼──────────────────────────┐
│              TunnelProcess                   │
│  ┌──────────────────────────────────┐       │
│  │  cloudflared / tailscale / ngrok │       │
│  │  (дочерний процесс)             │       │
│  └──────────────┬───────────────────┘       │
└─────────────────┼───────────────────────────┘
                  │ (исходящий TLS)
┌─────────────────▼───────────────────────────┐
│         Граничная сеть провайдера туннеля     │
│    https://your-agent.example.com            │
└──────────────────────────────────────────────┘

Конфигурация

Настройка туннеля в config.toml:

toml
[tunnel]
# Backend selection: "cloudflare" | "tailscale" | "ngrok" | "custom" | "none"
backend = "cloudflare"

# Local address that the tunnel will forward traffic to.
# This should match your gateway listen address.
local_addr = "127.0.0.1:8080"

# Health check interval in seconds. The tunnel is restarted if
# the health check fails consecutively for `max_failures` times.
health_check_interval_secs = 30
max_failures = 3

# Auto-detect: if backend = "auto", PRX probes for available
# tunnel binaries in order: cloudflared, tailscale, ngrok.
# Falls back to "none" with a warning if nothing is found.

Конфигурация для конкретных бэкендов

Каждый бэкенд имеет собственную секцию конфигурации. Подробности на страницах отдельных бэкендов:

Бэкенд пользовательской команды

Для провайдеров туннелей, не поддерживаемых нативно, используйте бэкенд custom:

toml
[tunnel]
backend = "custom"

[tunnel.custom]
# The command to run. Must accept traffic on local_addr and print
# the public URL to stdout within startup_timeout_secs.
command = "bore"
args = ["local", "8080", "--to", "bore.pub"]
startup_timeout_secs = 15

# Optional: regex to extract the public URL from stdout.
# The first capture group is used as the URL.
url_pattern = "listening at (https?://[\\S]+)"

Автоопределение

При backend = "auto" PRX ищет бинарники туннелей в $PATH в следующем порядке:

  1. cloudflared -- предпочтителен благодаря возможностям zero-trust
  2. tailscale -- предпочтителен для приватной mesh-сети
  3. ngrok -- широко доступен, простая настройка

Если ничего не найдено, туннель отключается и PRX записывает предупреждение. Каналы, зависящие от вебхуков, не будут работать без туннеля или публичного IP.

Жизненный цикл TunnelProcess

Структура TunnelProcess управляет жизненным циклом дочернего процесса:

ФазаОписание
ЗапускСтарт бинарника туннеля с настроенными аргументами
Извлечение URLПарсинг stdout для получения публичного URL (в пределах startup_timeout_secs)
МониторингПериодические проверки состояния через HTTP GET к публичному URL
ПерезапускПри max_failures последовательных неудачных проверок -- остановка и перезапуск
ЗавершениеОтправка SIGTERM, ожидание 5 секунд, затем SIGKILL при необходимости

Переменные окружения

Конфигурацию туннеля можно задать через переменные окружения, которые имеют приоритет над config.toml:

ПеременнаяОписание
PRX_TUNNEL_BACKENDПереопределение бэкенда туннеля
PRX_TUNNEL_LOCAL_ADDRПереопределение локального адреса перенаправления
PRX_TUNNEL_URLПропустить запуск туннеля и использовать этот URL
CLOUDFLARE_TUNNEL_TOKENТокен Cloudflare Tunnel
NGROK_AUTHTOKENТокен аутентификации ngrok

Установка PRX_TUNNEL_URL полезна, когда у вас уже есть обратный прокси или балансировщик нагрузки, открывающий PRX публично. Подсистема туннелирования пропустит управление процессом и будет использовать предоставленный URL напрямую.

Замечания по безопасности

  • Терминация TLS -- Все поддерживаемые бэкенды терминируют TLS на граничном узле провайдера. Трафик между провайдером и вашим локальным экземпляром PRX проходит через зашифрованный туннель.
  • Контроль доступа -- Cloudflare и Tailscale поддерживают политики доступа на основе идентичности. Используйте их при открытии чувствительных эндпоинтов агента.
  • Хранение учётных данных -- Токены туннеля и ключи авторизации хранятся в менеджере секретов PRX. Никогда не фиксируйте их в системе контроля версий.
  • Изоляция процессов -- TunnelProcess запускается как отдельный дочерний процесс. Он не разделяет память со средой выполнения агента PRX.

Устранение неполадок

СимптомПричинаРешение
Туннель запускается, но вебхуки не работаютURL не передан в конфигурацию каналаПроверьте, что tunnel.public_url используется каналом
Туннель перезапускается постоянноПроверка состояния обращается к неверному эндпоинтуУбедитесь, что local_addr совпадает с адресом прослушивания шлюза
Ошибка "binary not found"CLI-утилита туннеля не установленаУстановите соответствующий бинарник (cloudflared, tailscale, ngrok)
Таймаут при извлечении URLБинарник туннеля слишком долго запускаетсяУвеличьте startup_timeout_secs

Связанные страницы

Released under the Apache-2.0 License.