--- title: Keenetic RCI API (KeeneticOS 4.x/5.x) — как автоматизировать type: concept tags: [keenetic, router, rci, api, nat, dns, hairpin] related: [[kreknin-synology]] updated: 2026-08-12 --- # Keenetic RCI API Автоматизация KeeneticOS (проверено на **Viva 5.1.3**, release 5.01.C.3.0-1, stable). Новые веб-панели (Angular) закрыли старый `/api/auth`-digest + `/api/rci/`, но есть живой RCI через `/rci/`. ## Auth (интерактивный метод, как панель) 1. `GET /auth` → `401` + заголовки `X-NDM-Challenge` + `X-NDM-Realm` (+ кука `*.kpd*`). 2. `POST /auth` с JSON `{"login":"admin","password":ENC}`, заголовок `x-ndw2-interactive: 1`, куки из шага 1. - `ENC = sha256hex( CHALLENGE + md5hex( login + ":" + realm + ":" + password ) )` (lowercase hex). - `realm` — весь заголовок целиком (например `Keenetic Viva`, с пробелом). 3. Дальше все запросы **с кукой** из шага 1 (curl `-b jar`). Кука живёт ~5 мин (Max-Age=300) — перед серией запросов перелогинься. ## Чтение (GET, кука) - `GET /rci/show/version` — версия OS - `GET /rci/show/interface` — интерфейсы; `GET /rci/show/sc/interface/` — конфиг интерфейса - `GET /rci/show/sc/ip` — конфиг ip: `route`, `dhcp`, `dhcp/host`, `static` (!!), `nat` (только список интерфейсов), `http`, `conntrack`… - `GET /rci/show/ip/nat` — ТЕКУЩИЕ NAT-сессии (не правила) - `GET /rci/show/ip/hotspot` — устройства (known hosts) **Правила переадресации (порт-форвардинг) в 5.x лежат в `ip.static`** (!!, не `nat`): ```json { "interface": "GigabitEthernet1", "protocol": "tcp", "port": "443", "to-port": "4443", "to-host": "22:06:7c:20:00:43", "comment": "gitea-https" } ``` `to-host` = **MAC-адрес** целевого устройства, `to-port` = внутренний порт (опционально, если ≠ внешнему). ## Запись — CLI-parser (POST, кука) `POST /rci/` телом **массивом** `[{"parse":""}, …]` — как в командной строке Keenetic. В конце обязательно `{"parse":"save"}`. ```bash curl -b $JAR -H 'Content-Type: application/json' -X POST http://192.168.1.1/rci/ \ -d '[{"parse":"ip host git.kreknin.site 192.168.1.43"}, {"parse":"ip host kreknin.site 192.168.1.43"}, {"parse":"save"}]' ``` Полезные команды: - `ip host ` — статичная DNS-запись (hosts override); `no ip host ` — удалить - `save` — сохранить конфиг (обязательно в конце батча) - (для NAT-правил в 5.x — разбираться отдельно; в 5.x GUI их кладёт в `ip.static`) ## NAT loopback (hairpin) **Keenetic (Viva, 5.1.3) hairpin НЕ работает** (проверено: из LAN внешний адрес не открывается, даже после обновления OS; провайдер не виноват — WAN IP белый 195.19.90.188). Рабочее решение — **DNS-override** на роутере (записи `host` выше): клиенты LAN резолвят `git.kreknin.site` → `192.168.1.43` напрямую. Годится для любого числа сервисов (общий traefik). ## Gotchas - Старый `/api/auth` (digest) и `/api/rci/*` на новых прошивках **не работают** (отдают SPA). Путь RCI — `/rci/` без `/api/`. - Кука в curl-куки-файле начинается с `#HttpOnly_` — не фильтруй `grep -v '^#'`, если хочешь её увидеть. - `POST /rci/` с `{"path": ...}` (не массивом) — работает, но для чтения; для записи нужен массив parse-команд. - Примеры кода: [gist ancientGlider/e72cdaa2…](https://gist.github.com/ancientGlider/e72cdaa2daf0af5f8d80f53fea4666be), [noksa/gokeenapi](https://github.com/noksa/gokeenapi) (Go, CLI: routes/DNS-records/DNS-routing/WireGuard).