From 6844c24b77d61a5ab583d56facc77274ec7bbeb3 Mon Sep 17 00:00:00 2001 From: vitya Date: Wed, 12 Aug 2026 18:46:28 +0300 Subject: [PATCH] =?UTF-8?q?wiki(kreknin/keenetic):=20DNS-override=20=D1=87?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=B7=20RCI=20API=20=D1=80=D0=B5=D1=88=D0=B0?= =?UTF-8?q?=D0=B5=D1=82=20loopback;=20=D0=BA=D0=BE=D0=BD=D1=86=D0=B5=D0=BF?= =?UTF-8?q?=D1=82=20keenetic-rci-api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit KeeneticOS 5.1.3: hairpin не работает (проверено после обновления) → статичные DNS-записи ip host git.kreknin.site/kreknin.site → 192.168.1.43 через POST /rci/ parse. Из LAN всё 200. Правила порт-форвардинга = ip.static (to-host MAC). --- .wiki/concepts/keenetic-rci-api.md | 61 ++++++++++++++++++++++++++++++ .wiki/entities/kreknin-synology.md | 2 +- .wiki/index.md | 2 + .wiki/log.md | 1 + 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 .wiki/concepts/keenetic-rci-api.md diff --git a/.wiki/concepts/keenetic-rci-api.md b/.wiki/concepts/keenetic-rci-api.md new file mode 100644 index 0000000..255558f --- /dev/null +++ b/.wiki/concepts/keenetic-rci-api.md @@ -0,0 +1,61 @@ +--- +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). diff --git a/.wiki/entities/kreknin-synology.md b/.wiki/entities/kreknin-synology.md index 813ed0b..2858bb0 100644 --- a/.wiki/entities/kreknin-synology.md +++ b/.wiki/entities/kreknin-synology.md @@ -125,7 +125,7 @@ USB **2TB WD20EARX** (sdq) отформатирован в один btrfs, см - **Домен:** `https://git.kreknin.site/` — LE-серт (traefik httpChallenge, выписан 2026-08-12), redirect http→https. - **Traefik** (v2.6.6, порты 8000/4443/8080): лежал с 07-31 (restart policy был `no`, упал на инциденте) — починен: `restart: unless-stopped`. **Урок: traefik без restart policy после ребута не поднимается.** - **Проброс на Keenetic:** 80→192.168.1.43:8000, 443→192.168.1.43:4443 (правила в панели, сделал vitya/Алексей в GUI — KeeneticOS Viva API закрыт для curl-автоматизации). -- **NAT loopback у Алексея СЛОМАН** (из его LAN внешние адреса не открываются): нужен DNS-override в Keenetic — «Домашняя сеть → Доменные имена»: `git.kreknin.site → 192.168.1.43`, `kreknin.site → 192.168.1.43`. Статус: добавлено/нет — проверить с LAN. +- **NAT loopback у Алексея СЛОМАН** (из его LAN внешние адреса не открывались): **РЕШЕНО 2026-08-12 через DNS-override** — статичные DNS-записи на Keenetic: `git.kreknin.site → 192.168.1.43`, `kreknin.site → 192.168.1.43` (добавлены через RCI API, см. концепт keenetic-rci-api). Проверено с LAN: git.kreknin.site → 200, kreknin.site:5000 → 200. KeeneticOS 5.1.3 hairpin НЕ чинит (проверено после обновления) — DNS-override это единственное рабочее решение. - **Keenetic admin-пароль:** `pass kreknin/keenetic` (t3r1a4k314; 3steaks1eGG — НЕ для роутера). - Установка через web-форму падала (xorm nil-pointer panic на sqlite) → обход: `INSTALL_LOCK=true` в [security] + CLI `admin user create`. Gitea CLI: `docker exec -u 1026:100 gitea gitea --config /data/gitea/conf/app.ini admin user ...` (новый синтаксис `admin user create`, не `create-user`). diff --git a/.wiki/index.md b/.wiki/index.md index b190e1c..f001d6a 100644 --- a/.wiki/index.md +++ b/.wiki/index.md @@ -21,6 +21,8 @@ Catalog of all wiki pages. One line per page, organized by type. Updated on ever - [windows-recovery-host](entities/windows-recovery-host.md) — Windows Recovery Host (рабочий PC пользователя) ## Concepts +- [keenetic-rci-api](concepts/keenetic-rci-api.md) — KeeneticOS RCI API: auth, чтение конфига, запись через CLI-parser, DNS-override против сломанного hairpin + - [admin-api-embed-pilonuxt](concepts/admin-api-embed-pilonuxt.md) — admin-api embedded in pilonuxt /admin/api, stack 25 retired (2026-08-05) diff --git a/.wiki/log.md b/.wiki/log.md index 2ce583a..e233b7c 100644 --- a/.wiki/log.md +++ b/.wiki/log.md @@ -1,3 +1,4 @@ +## [2026-08-12] implement | NEW concepts/keenetic-rci-api.md — разобрана автоматизация KeeneticOS 5.1.3 (RCI: GET /rci/show/*, POST /rci/ массив parse-команд). Через API добавлены DNS-записи git.kreknin.site/kreknin.site → 192.168.1.43 (решение сломанного hairpin). Проверено с LAN: всё 200. Правила порт-форвардинга в 5.x лежат в ip.static (to-host=MAC). ## [2026-08-12] implement | UPDATE entities/kreknin-synology.md — Gitea 1.27.1 + postgres 16 на kreknin (для Алексея), traefik починен (restart policy), LE-серт git.kreknin.site, проброс 80/443→8000/4443 на Keenetic. KeeneticOS Viva API закрыт — правила в GUI. NAT loopback сломан → нужен DNS-override git.kreknin.site→192.168.1.43. Пароли: pass kreknin/keenetic + pass kreknin/gitea. # Wiki op-log