Bedrud Документация

Как развернуть Bedrud, если ваш сервер находится за обратным прокси или CDN. Это обычная конфигурация для продакшена, но WebRTC (LiveKit) требует специальной обработки, так как CDN не могут проксировать медиа-трафик UDP.


Проблема (The Problem)

Bedrud состоит из двух сетевых компонентов с разными требованиями:

КомпонентТрафикСовместим с CDN/прокси?
Bedrud ServerHTTP/WebSocket (TCP)Да
LiveKit (WebRTC)UDP медиа + TCP сигнализацияНет — UDP должен доходить до сервера напрямую

Стандартный прокси, такой как Cloudflare, nginx или Traefik, отлично справляется с трафиком HTTP/HTTPS. Но медиа-потоки WebRTC в LiveKit проходят через UDP-порты, которые эти прокси либо молча отбрасывают (drop), либо не могут перенаправить (forward).

Browser ──HTTP/WS──► CDN ──HTTP/WS──► Bedrud Server    ✓ Работает
Browser ──UDP────────► CDN ──X─────────► LiveKit        ✗ Пакеты отброшены
Browser ──UDP─────────────────────────► LiveKit         ✓ Напрямую

Варианты развертывания (Deployment Options)

Вариант 1: Отдельный домен для LiveKit (рекомендуется)

Используйте две записи DNS: одну для сервера Bedrud (через прокси) и одну для LiveKit (только DNS).

meet.example.com     → запись A → прокси CDN (Orange Cloud) → сервер Bedrud
lk.meet.example.com  → запись A → только DNS (Grey Cloud)   → тот же сервер

Установщик (installer) берет это на себя, если вы выберете «Behind proxy» и укажете поддомен для LiveKit.

Шаги:

  1. Запустите установщик и ответьте на вопросы о прокси/CDN:

    curl -fsSL https://bedrud.org/install.sh | bash
    • “Running behind a proxy/CDN?” → Yes
    • “What type?” → cloudflare
    • “Use a separate subdomain for LiveKit?” → Yes
    • Введите lk.meet.example.com в качестве поддомена LiveKit
    • Введите реальный публичный IP вашего сервера (не IP от CDN) для LiveKit
  2. У вашего DNS-провайдера создайте:

    • meet.example.com → через прокси CDN
    • lk.meet.example.comтолько DNS (Grey Cloud), указывающий на реальный IP вашего сервера
  3. Откройте необходимые порты в брандмауэре (firewall):

    sudo ufw allow 7880/tcp    # LiveKit API
    sudo ufw allow 7881/tcp    # Резервный RTC TCP
    sudo ufw allow 50000:60000/udp  # WebRTC медиа
    sudo ufw allow 3478/udp    # TURN relay
    sudo ufw allow 5349/tcp    # TURN TLS (если используется TLS)

Почему это работает: Браузер подключается к LiveKit напрямую через lk.meet.example.com, полностью минуя CDN. Трафик WebRTC UDP идет прямо на ваш сервер. Веб-интерфейс Bedrud по-прежнему пользуется преимуществами кэширования и DDoS-защиты CDN.

Вариант 2: Внешний сервер LiveKit

Запустите LiveKit на отдельной машине, которая не находится за прокси.

Browser ──► CDN ──► Bedrud Server ──API──► LiveKit Server
Browser ──────────────────────────────────► LiveKit Server

Шаги:

  1. Настройте сервер LiveKit на отдельной машине (см. документацию LiveKit)

  2. Запустите установщик Bedrud и выберите «external LiveKit server»:

    bedrud install \
      --domain meet.example.com \
      --behind-proxy \
      --external-livekit https://lk.example.com \
      --email admin@example.com
  3. Убедитесь, что порты сервера LiveKit открыты и доступны для клиентов.

Вариант 3: Тот же IP, другая конфигурация (Встроенный LK с явным NodeIP)

Если вы не можете использовать отдельный домен, вы можете оставить LiveKit встроенным (embedded) и явно указать реальный IP сервера для ICE-кандидатов WebRTC. Сигнализация (WebSocket) все равно идет через CDN, но медиа (UDP) обходит его.

Browser ──WS/Сигнализация──► CDN ──► Bedrud Server ──► Встроенный LiveKit
Browser ──UDP Медиа─────────────────────► IP сервера (напрямую)

Шаги:

  1. Запустите установщик:

    bedrud install \
      --domain meet.example.com \
      --behind-proxy \
      --lk-ip ВАШ_РЕАЛЬНЫЙ_IP_СЕРВЕРА \
      --lk-udp-range 50000-60000
  2. Откройте порты WebRTC в брандмауэре:

    sudo ufw allow 50000:60000/udp
    sudo ufw allow 7881/tcp
    sudo ufw allow 3478/udp

Ограничения:

  • Клиенты должны иметь возможность достучаться до реального IP вашего сервера по UDP-портам
  • Сигнализация WebSocket идет через CDN (подвержена таймаутам бездействия — idle timeouts)
  • Менее надежно, чем вариант 1 или 2

Примечания по Cloudflare

Настройка DNS

ЗаписьИмяКонтентПрокси
AmeetIP вашего сервераProxied (Orange Cloud)
AlkIP вашего сервераDNS Only (Grey Cloud)

Таймауты WebSocket (WebSocket Timeouts)

На тарифах Cloudflare Free и Pro действует таймаут бездействия 100 секунд для соединений WebSocket. Если пользователь находится в комнате без активной сигнализации, соединение может разорваться. Это вызывает переподключение (reconnect) — аудио и видео обычно восстанавливаются, но это может мешать работе.

Смягчение последствий: настройте интервалы keep-alive для LiveKit в livekit.yaml:

rtc:
  peer_connection_configs:
    - video_codec: H264
  # Keepalive помогает предотвратить разрывы из-за бездействия через CDN

Правила кэширования (Cache Rules)

Убедитесь, что Cloudflare не кэширует ответы LiveKit API. Создайте правило кэширования:

  • Шаблон URL: lk.yourdomain.com/twirp/*
  • Уровень кэширования: Bypass (обход)

Исключения WAF

Если ваш сервер Bedrud делает вызовы к backend API LiveKit через CDN (редко при использовании отдельных доменов), WAF от Cloudflare может проверять или блокировать эти запросы. Добавьте исключение WAF для IP-адреса вашего сервера.

Защита от DDoS

При использовании режима DNS-only (Grey Cloud) для домена LiveKit этот поддомен не получает защиту от DDoS от Cloudflare. Встроенное ограничение скорости (rate limiting) и аутентификация (API-ключи) LiveKit обеспечивают некоторую защиту. Для дополнительной безопасности рассмотрите:

  • Использование опции --external-livekit с выделенной машиной LiveKit за отдельным брандмауэром
  • Ограничение доступа к LiveKit API только для IP вашего сервера Bedrud с помощью правил брандмауэра

Обратный прокси nginx (nginx Reverse Proxy)

При использовании nginx в качестве обратного прокси (не CDN), вам нужно проксировать сервер Bedrud, но пропускать трафик LiveKit напрямую.

Конфигурация nginx только для сервера Bedrud

server {
    listen 443 ssl http2;
    server_name meet.example.com;
 
    ssl_certificate     /etc/letsencrypt/live/meet.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/meet.example.com/privkey.pem;
 
    location / {
        proxy_pass http://127.0.0.1:8090;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
 
    # Поддержка WebSocket (если проксируете сигнализацию LiveKit через nginx)
    location /livekit {
        proxy_pass http://127.0.0.1:7880;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 86400;
    }
}

Важно: для UDP медиа по-прежнему нужен прямой доступ

Даже с nginx трафик WebRTC UDP не идет через nginx. Клиенты подключаются напрямую к NodeIP LiveKit по UDP-портам. Вам все равно нужно:

  1. Открыть UDP-порты 50000-60000 (или ваш настроенный диапазон) в брандмауэре
  2. Убедиться, что в livekit.yaml параметр node_ip установлен в значение публичного IP вашего сервера
  3. Использовать флаг --behind-proxy при установке, чтобы сервер доверял заголовкам прокси (proxy headers)
bedrud install \
  --domain meet.example.com \
  --behind-proxy \
  --lk-ip ВАШ_РЕАЛЬНЫЙ_IP_СЕРВЕРА \
  --lk-udp-range 50000-60000

Требуемые порты брандмауэра

ПортПротоколСервисВсегда требуется?
7880TCPLiveKit APIТолько если домен LK или внешний
7881TCPРезервный RTC TCPДа
50000-60000UDPWebRTC медиаДа
3478UDPTURN relayРекомендуется
5349TCPTURN TLSЕсли включен TLS
80/443TCPHTTP/HTTPSДа (через CDN или напрямую)

Встроенный режим (без отдельного домена LK): Должны быть открыты только 7881/tcp, 50000-60000/udp и 3478/udp. Порт 7880 проксируется через сервер Bedrud.


Поиск и устранение неисправностей (Troubleshooting)

Пользователи могут заходить в комнаты, но звук/видео не работают

Причина: UDP медиа-трафик не доходит до сервера LiveKit.

  1. Проверьте, что порты WebRTC UDP открыты:
    sudo ss -ulnp | grep -E '(7882|50000|3478)'
  2. Убедитесь, что node_ip в /etc/bedrud/livekit.yaml — это реальный публичный IP вашего сервера
  3. Если вы за CDN, убедитесь, что домен LiveKit работает в режиме DNS-only (Grey Cloud)

WebSocket отключается примерно каждые 100 секунд

Причина: таймаут бездействия Cloudflare на бесплатных/Pro тарифах.

Решения:

  • Используйте отдельный домен для LiveKit (только DNS) — сигнализация идет напрямую, таймаута нет
  • Перейдите на тариф Cloudflare Business или Enterprise (более длительные таймауты WebSocket)

ICE-кандидаты LiveKit показывают IP от CDN вместо IP сервера

Причина: node_ip неправильно настроен в livekit.yaml.

Исправление:

# Проверьте текущую конфигурацию
grep node_ip /etc/bedrud/livekit.yaml
 
# Если она неверна, переустановите с правильным IP
bedrud install --fresh --lk-ip ВАШ_РЕАЛЬНЫЙ_IP_СЕРВЕРА

Клиенты вообще не могут подключиться к LiveKit

  1. Проверьте, запущен ли сервис LiveKit:
    systemctl status livekit
    journalctl -u livekit -n 50
  2. Проверьте привязку портов:
    ss -tlnp | grep 7880
    ss -tlnp | grep 7881
  3. Если используете отдельный домен LK, проверьте разрешение DNS:
    dig +short lk.meet.example.com
    # Должен возвращаться реальный IP вашего сервера, а не IP от CDN