Files
admin/.wiki/concepts/keenetic-rci-api.md
vitya 88f1bb5fe2 wiki: закрыта gitea-задача на kreknin (DNS-override через RCI, hairpin не чинится)
- DNS-записи git.kreknin.site/kreknin.site → 192.168.1.43 добавлены через POST /rci/ parse (ip host)
- KeeneticOS 5.1.3 hairpin НЕ чинит (проверено) — DNS-override это решение
- Концепт keenetic-rci-api + ссылка на офиц. CLI-документацию
- Handoff: задача полностью закрыта
2026-08-12 18:47:04 +03:00

4.5 KiB
Raw Blame History

title, type, tags, related, updated
title type tags related updated
Keenetic RCI API (KeeneticOS 4.x/5.x) — как автоматизировать concept
keenetic
router
rci
api
nat
dns
hairpin
kreknin-synology
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 /auth401 + заголовки 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/<id> — конфиг интерфейса
  • 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):

{ "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":"<cli-команда>"}, …] — как в командной строке Keenetic. В конце обязательно {"parse":"save"}.

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 <domain> <ip> — статичная DNS-запись (hosts override); no ip host <domain> — удалить
  • 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.site192.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…, noksa/gokeenapi (Go, CLI: routes/DNS-records/DNS-routing/WireGuard).
  • Официальная CLI-справка Keenetic: support.keenetic.com — CLI (порт-форвардинг, firewall, DNS, VPN-разделы).