ADB Panel

Admin-панель

Система

Очереди

Очередьwaitingactivecompletedfaileddelayed

Открыть Bull-Board

Активные стримы

УстройствоПодписчикиБитрейтFPSPID

Пользователи

UsernameРоль2FAСтатусПоследний входСоздан

Устройства

IDAliasТегиЗаметкиPINСтатусМодель

Группы устройств

Группы объединяют устройства и привязывают их к пользователям. Не-админ видит только устройства из своих групп.

НазваниеОписаниеУстройстваПользователи

Пороги алертов

Глобальные пороги задаются переменными окружения. Здесь — переопределения для отдельных устройств.

УстройствоБатарея ≤CPU ≥Темп. ≥

Макросы

ИмяШаговПривязкаЗапусковПоследний запуск

Планировщик

ИмяCronМакросУстройстваВключена

Вебхуки

ИмяURLСобытияВключён

Share-ссылки

МеткаРольУстройствСозданаИстекаетИспользованийСтатус

Логи

ВремяКтоActionDeviceOKIPДетали

Туннель

Четыре способа открыть панель снаружи. Порядок — от наиболее рекомендуемого к запасным: Cloudflare Tunnel (свой домен, скрытый IP, встроенный 2FA), Tailscale (mesh-VPN с клиентом у каждого), WireGuard на свой VPS (полный self-hosted), ngrok (только для разовых демо). Полный референс — DEPLOY.md § 12.

⚠️ Юрисдикция сервера важна. Для сервера в РФ Cloudflare Tunnel не работает — DPI (РКН/СОРМ) режет TLS-handshake по SNI *.cfargotunnel.com, проверено: TCP доходит, TLS — нет. Tailscale (через свой обфусцированный VPN) и WireGuard на иностранный VPS — работают. Для сервера в Аргентине / ЕС / США все три туннеля работают штатно.

Cloudflare Tunnel — рекомендуется

cloudflared на сервере держит исходящее HTTPS к Cloudflare; они публикуют панель на вашем домене (panel.example.com). Никаких открытых портов, IP сервера снаружи не виден, Let's Encrypt серт обновляется автоматически. Auto-setup из UI не делаетсяcloudflared login требует браузер на сервере и одноразовую ручную авторизацию; ниже — пошаговые команды.

Шаги настройки (one-time)
  1. Шаг 0 — Привязать домен к Cloudflare DNS (пропустить, если домен уже Active в dash.cloudflare.com): Add a site → выбрать Free → Cloudflare покажет два nameserver'а (*.ns.cloudflare.com); их прописать у регистратора (REG.ru / Namecheap / GoDaddy → раздел NS). Подождать 5–30 минут до статуса Active.
  2. На сервере: добавить apt-репо Cloudflare и поставить cloudflared (стабильнее чем тащить .deb с github.com — особенно за VPN/DPI). Команды короткие, копируйте по одной строке за раз:
    sudo mkdir -p --mode=0755 /usr/share/keyrings
    sudo curl -fsSL -o /usr/share/keyrings/cloudflare-main.gpg https://pkg.cloudflare.com/cloudflare-main.gpg
    echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list
    sudo apt update
    sudo apt install -y cloudflared jq
    Если curl упал с TLS-ошибкой — повторите 2–3 раза. ls -la /usr/share/keyrings/cloudflare-main.gpg должен показать ~2–4 KB.
  3. Залогиниться (откроется браузер с Cloudflare auth, выбрать свой домен): sudo cloudflared tunnel login
  4. Создать туннель. Если API падает с EOF — ретрай в цикле:
    for i in 1 2 3 4 5; do sudo cloudflared tunnel create adbpanel && break; sleep 5; done
    sudo cloudflared tunnel route dns adbpanel panel.example.com
    Если route dns тоже падает с EOF — создайте CNAME вручную в Cloudflare-дашборде: DNS → Records → Add → CNAME, Name panel, Target <UUID>.cfargotunnel.com (UUID — имя .json-файла в /root/.cloudflared/), Proxied (оранжевое облако).
  5. Записать конфиг с UUID и запустить:
    sudo mkdir -p /etc/cloudflared
    TID=$(sudo ls /root/.cloudflared/ | grep -E '\.json$' | head -1 | sed 's|\.json$||')
    sudo tee /etc/cloudflared/config.yml >/dev/null <<EOF
    tunnel: ${TID}
    credentials-file: /root/.cloudflared/${TID}.json
    protocol: http2
    ingress:
      - hostname: panel.example.com
        service: http://127.0.0.1:3030
      - service: http_status:404
    EOF
    sudo cloudflared service install
    sudo systemctl enable --now cloudflared
    protocol: http2 важен — без него используется QUIC (UDP), который часто режется на «шумных» сетях.
  6. (Опц.) Zero Trust → Access → Applications → policy «emails ending in @domain» — email-OTP до того, как запрос дойдёт до туннеля.
⚠️ Подводные камни (из практики)
  • DPI режет SNI *.cfargotunnel.com в РФ. Симптом: TLS handshake with edge error: EOF в логах cloudflared. TCP проходит, TLS — нет. Не лечится никакими опциями. Решение: переезд сервера в juris-friendly локацию. Через коммерческие VPN-exit обычно тоже режут tunnel-инфраструктуру.
  • QUIC по умолчанию. Если не указать protocol: http2, идёт через UDP — а на VPN/DPI-сетях UDP теряется (failed to dial quic: timeout). http2 = TCP/7844, обходит проблему.
  • API-вызовы флапают. tunnel create, tunnel list, tunnel route dns идут к api.cloudflare.com. На дрожащей сети падают с EOF. Обход: ретрай-loop и ручное создание CNAME через dashboard.
  • YAML-отступы. Верхний уровень (tunnel:, credentials-file:) — без пробелов слева. Иначе mapping values are not allowed in this context.
  • Multi-line с \ ломаются на пасте. Некоторые терминалы режут переносы — копируйте по одной строке или сохраните в .sh файл и sudo bash file.sh.
  • UUID в tunnel: и credentials-file: должны совпадать. Часто оставляют placeholder в одном из них. Команды выше с TID=$(...) решают это.
  • systemd timeout 90 сек. Если первые коннекты медленные — sudo systemctl edit cloudflared[Service]\nTimeoutStartSec=300.

Полный референс — DEPLOY.md § 12.1.


Tailscale — для команды до 3-х человек, клиент у каждого

Mesh-VPN. На сервере уже работает tailscaled (snap). Получить auth-key: admin.tailscale.com → Settings → Keys → Generate (reusable + tagged), вставить ниже, нажать «Подключить» — сервер сделает tailscale up --authkey=…. Дальше у вас и коллег ставится клиент Tailscale (10 минут на устройство), и панель открывается по Tailscale-IP сервера или MagicDNS-hostname.

Tailscale Funnel — публичный URL без клиента (шаги)
  1. В admin.tailscale.com → DNS включить HTTPS Certificates.
  2. В Access Controls добавить в policy:
    "nodeAttrs": [
      { "target": ["autogroup:member"], "attr": ["funnel"] }
    ]
  3. На сервере одной командой:
    sudo tailscale funnel --bg http://localhost:3030
    Должно показать «Funnel started». Проверка: sudo tailscale funnel status.
  4. Reset, если что-то пошло не так:
    sudo tailscale funnel reset
    sudo tailscale serve reset
⚠️ Подводные камни Funnel
  • Старый CLI больше не работает. tailscale funnel 443 on → «the CLI for serve and funnel has changed». Правильно: tailscale funnel --bg <target>.
  • NXDOMAIN на <host>.<tailnet>.ts.net. Если dig … @8.8.8.8 возвращает NXDOMAIN — значит не включён один из двух пунктов выше (HTTPS Certificates / nodeAttrs). DNS обновляется через 30–60 сек после включения обоих.
  • Из браузера на том же хосте Funnel недоступен. MagicDNS локально резолвит имя в Tailscale IP (100.x.x.x), трафик идёт через tun0 — Funnel принимает только public-путь через DERP. Получите PR_END_OF_FILE_ERROR. Тестируйте с внешнего устройства (телефон на мобильном интернете).
  • DERP-relays в РФ нет. Ближайший — Frankfurt (~85 мс от RU). Для RU↔RU через Funnel — +170 мс на каждый запрос. Решение: операторам поставить Tailscale-клиент (тогда direct P2P, минуя DERP).
  • После включения Funnel — обновить BASE_URL в .env:
    sudo sed -i 's|^BASE_URL=.*|BASE_URL=https://<host>.<tailnet>.ts.net|' /opt/adbpanel/.env
    sudo systemctl restart adbpanel

Полный референс — DEPLOY.md § 12.2.


WireGuard через свой VPS — полный self-hosted

Без облачных провайдеров. Поднимаете VPS (Hetzner / DO / Vultr), разворачиваете на нём WG-сервер, панель — WG-клиент. Все клиенты в WG-сети видят панель на 10.7.0.2:3030. Часто связывают с nginx + Let's Encrypt на VPS — тогда снаружи получается panel.example.com без клиента у юзеров (фактически self-hosted Cloudflare Tunnel).

Шаги настройки (полный рецепт, проверен на бою)
  1. VPS: apt install -y wireguard, сгенерировать server.key / server.pub через wg genkey | tee server.key | wg pubkey > server.pub, создать /etc/wireguard/wg0.conf с [Interface] Address=10.7.0.1/24 ListenPort=51820 PrivateKey=... и PostUp-правилами (FORWARD ACCEPT, NAT MASQUERADE, MSS clamping). Включить sysctl net.ipv4.ip_forward=1. systemctl enable --now wg-quick@wg0. Полный конфиг — DEPLOY.md § 12.3 шаг A.
  2. Здесь нажать Generate keypair — публичный ключ клиента покажется, скопировать.
  3. На VPS добавить в /etc/wireguard/wg0.conf блок [Peer] PublicKey=<тот> AllowedIPs=10.7.0.2/32 PersistentKeepalive=25, затем wg-quick down wg0 && wg-quick up wg0.
  4. Здесь в поле «Конфиг» прописать (AllowedIPs = 10.7.0.0/24, не 0.0.0.0/0! Иначе весь трафик пойдёт через VPS):
    [Interface]
    PrivateKey = <генерится автоматически>
    Address = 10.7.0.2/32
    
    [Peer]
    PublicKey = <VPS-server.pub>
    Endpoint = <IP_VPS>:51820
    AllowedIPs = 10.7.0.0/24
    PersistentKeepalive = 25
    Нажать Сохранить и поднять.
  5. Если на хосте уже работает другой VPN (Reality / OpenVPN / sing-box-TUN) — добавьте bypass-маршрут! Без него UDP к WG-серверу теряется внутри обёртки. См. блок «Подводные камни» ниже.
  6. На VPS поверх WG: nginx + Let's Encrypt. DNS A-запись panel.example.com → IP_VPS (если домен на Cloudflare, ставить DNS only, серое облако — для certbot HTTP-01). Конфиг nginx писать через nano, не через cat <<EOF (SSH-клиент часто рушит длинные heredoc'и). Полный конфиг и команда certbot — DEPLOY.md § 12.3 шаг F.
  7. На хосте обновить BASE_URL и CORS_ORIGINS в /opt/adbpanel/.env на https://panel.example.com, systemctl restart adbpanel.
⚠️ Подводные камни WireGuard (из боевого сетапа)
  • Bypass-route, если есть другой VPN на хосте — самый коварный камень. Симптом: WG handshake уходит, но wg show показывает transfer: 0 B received; ping 10.7.0.1 = 100% packet loss. UDP-пакеты к WG-серверу теряются в обёртке вышестоящего VPN (Reality / OpenVPN / sing-box-TUN — все TCP-based и плохо переваривают UDP-инкапсуляцию). Лечение: явный маршрут к VPS через физический интерфейс, обходя VPN:
    sudo ip route add <IP_VPS>/32 via <PHYS_GW> dev <PHYS_DEV> metric 50
    И persistent через systemd-сервис, чтобы переживал ребут (полный пример — DEPLOY.md § 12.3 шаг E).
  • HEREDOC и длинные команды ломаются на SSH-пасте. Симптомы: «unexpected end of file», «syntax error», файл записан обрезанным. Лечение: для длинных конфигов (wg0.conf, nginx.conf) использовать nano — открыть редактор, вставить содержимое внутри, сохранить. SSH-клиент рушит heredoc, nano принимает паст без вмешательства.
  • AllowedIPs = 10.7.0.0/24 на клиенте, не 0.0.0.0/0. Иначе хост заворачивает весь свой исходящий трафик через VPS — конфликт с уже работающим VPN-клиентом, и обычно всё ломается.
  • MSS clamping на VPS обязателен. Без него крупные пакеты (upload APK, стрим) фрагментируются и теряются. В PostUp на VPS:
    iptables -t mangle -A FORWARD -o %i -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
  • Cloudflare proxy при certbot. Если домен на Cloudflare DNS, поставьте A-запись panel.example.com в режим DNS only (серое облако) перед certbot --nginx. С proxied (оранжевое облако) Let's Encrypt не сможет доделать HTTP-01 challenge.
  • VPS в правильной юрисдикции. Для боевого использования операторами в РФ — VPS в РФ (Селектел / Яндекс / Beget), 5–30 мс. Для AR-операторов — VPS в Сан-Паулу или Буэнос-Айресе. Не путать с VPN-exit-провайдером: WG-VPS даёт доступ к панели, а не маскирует трафик.
  • DPI режет голый WG UDP на некоторых RU-ISP. Симптом: handshake не завершается, peer вообще не появляется. Лечится udp2raw, wstunnel или обфусцированным транспортом (sing-box WG outbound в Reality/Trojan).

Полный референс — DEPLOY.md § 12.3.


ngrok — только для разовых демо / тестов

Быстрый одноразовый публичный URL вида https://random-XXXX.ngrok-free.app. Бесплатный план — рандомный домен (меняется при перезапуске), лимит соединений, в плашке указано «Tunneled by ngrok». Для постоянной работы — Cloudflare Tunnel или Tailscale. Нужен токен из dashboard.ngrok.com, прописать NGROK_AUTH_TOKEN=… в .env.

Форма