Внешний доступ к API
Панель Remnawave умеет отдавать свой API внешним клиентам: ботам, панелям управления, статистике. По умолчанию скрипт прячет всё за cookie-защитой или страницей входа, поэтому наружу выходит только то, что вы откроете сами: один location в nginx.conf, а дальше любой запрос проходит ту же защиту, что и браузер, плюс токен панели (Настройки → API-токены).
Открытие API наружу
Заголовок раздела «Открытие API наружу»Блок одинаков для всех вариантов установки («только панель» и «панель + нода»).
-
Откройте конфигурацию nginx:
root@server: ~ nano /opt/remnawave/nginx.conf -
В блок сервера с доменом панели (
server_name panel.example.com;) добавьтеlocation: он выводит/api/из-под проверки cookie и отдаёт запросы напрямую панели:nginx.conf location ^~ /api/ {proxy_http_version 1.1;proxy_pass http://remnawave;proxy_set_header Host $host;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection $connection_upgrade;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;proxy_set_header X-Forwarded-Host $host;proxy_set_header X-Forwarded-Port $server_port;proxy_send_timeout 60s;proxy_read_timeout 60s;} -
Перезапустите веб-сервер, чтобы конфигурация применилась:
root@server: ~ cd /opt/remnawave && docker compose restart remnawave-nginx -
Проверьте доступность снаружи (запрос без токена должен вернуть ошибку авторизации, а не таймаут):
root@server: ~ curl -i https://panel.example.com/api/nodes
Caddy ставится в двух видах, и API в них устроен по-разному.
Портал с MFA (caddy-with-auth). Ничего добавлять не нужно: маршрут route /api/* уже открыт в Caddyfile из коробки. API защищён собственным токеном, вход в панель остаётся за порталом, а для программных клиентов есть ключ X-Api-Key (способ «Портал с MFA» ниже).
Cookie-защита. API закрыт вместе с панелью: запрос без куки упирается в abort. Чтобы открыть его, добавьте отдельный маршрут.
-
Откройте Caddyfile:
root@server: ~ nano /opt/remnawave/Caddyfile -
Внутри блока
https://{$PANEL_DOMAIN}добавьте маршрут в начало, до матчеров@has_token_paramи@unauthorized:Caddyfile route /api/* {reverse_proxy {$BACKEND_URL} {header_up X-Real-IP {remote}header_up Host {host}}} -
Перезапустите Caddy:
root@server: ~ cd /opt/remnawave && docker compose restart remnawave-caddy -
Проверьте доступность снаружи (запрос без токена должен вернуть ошибку авторизации, а не таймаут):
root@server: ~ curl -i https://panel.example.com/api/nodes
Прохождение защиты
Заголовок раздела «Прохождение защиты»Дальше всё зависит от способа защиты панели, выбранного при установке. Токен панели (Authorization: Bearer …) отправляется в каждом запросе поверх любого из вариантов.
Получение cookie
Заголовок раздела «Получение cookie»Скрипт генерирует случайную пару ИМЯ=ЗНАЧЕНИЕ. Откройте nginx.conf и найдите строку map $http_cookie $auth_cookie, ваши данные это значение после ~*:
map $http_cookie $auth_cookie { default 0; "~*zIdejKtN=MWbLrRzx" 1;}Здесь кука zIdejKtN=MWbLrRzx.
Отправка cookie в заголовке
Заголовок раздела «Отправка cookie в заголовке»На примере HTTP-клиента httpx и записи COOKIES в .env вашего проекта:
COOKIES={"zIdejKtN":"MWbLrRzx"}token = os.getenv("API_TOKEN", "")base_url = os.getenv("REMNAWAVE_BASE_URL", "")cookies = json.loads(os.getenv("COOKIES", "{}"))
async def get_all_nodes(): headers = { "Content-Type": "application/json", "Authorization": "Bearer " + token }
async with httpx.AsyncClient(cookies=cookies) as async_client: response = await async_client.get(f"{base_url}/api/nodes", headers=headers)
return response.json()Быстрая проверка curl:
curl -b "zIdejKtN=MWbLrRzx" -H "Authorization: Bearer <токен>" https://panel.example.com/api/nodesДанные для входа передаются в отдельном заголовке X-Api-Key, а Authorization с токеном панели доходит до API нетронутым, оба заголовка отправляются в одном запросе.
В X-Api-Key передаются данные для входа TinyAuth в формате Basic base64(логин:пароль). Собрать пару:
printf '%s' 'логин:пароль' | base64# dXNlcm5hbWU6cGFzc3dvcmQ=Итоговые заголовки запроса:
{ "Authorization": "Bearer <токен панели>", "X-Api-Key": "Basic dXNlcm5hbWU6cGFzc3dvcmQ="}Быстрая проверка curl:
curl -H "X-Api-Key: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" -H "Authorization: Bearer <токен>" https://panel.example.com/api/nodesКлюч создаётся на самой странице входа: https://<домен панели>/r/settings/apikeys (ссылка «API Keys»). Отправляется как есть, без обёртки Basic:
{ "Authorization": "Bearer <токен панели>", "X-Api-Key": "<ключ со страницы входа>"}Быстрая проверка curl:
curl -H "X-Api-Key: <ключ со страницы входа>" -H "Authorization: Bearer <токен>" https://panel.example.com/api/nodesОтдельная страница подписки
Заголовок раздела «Отдельная страница подписки»Установка «только страница подписки» спрашивает способ защиты панели и подставляет всё сама: при TinyAuth достаточно ввести логин и пароль страницы входа: base64-пару установщик собирает самостоятельно.
| Защита панели | Что спрашивает инсталлер | Переменная в compose страницы подписки |
|---|---|---|
| Cookie-защита | кука ИМЯ=ЗНАЧЕНИЕ |
EGAMES_COOKIE=ИМЯ=ЗНАЧЕНИЕ |
| Страница входа (TinyAuth) | логин и пароль | CADDY_AUTH_API_TOKEN=Basic base64(...) |
| Caddy с MFA | ключ со страницы входа | CADDY_AUTH_API_TOKEN=<ключ> |
