‹ 首页

routeros-quickchr

@tikoci · 收录于 1 周前

Ground RouterOS config/scripts/API code against a REAL router using quickchr (@tikoci/quickchr) — a CLI + Bun/TS library that downloads, boots, and manages MikroTik CHR VMs on QEMU. Use when: validating generated RouterOS config or scripts against real RouterOS before trusting them; spinning up a disposable CHR for REST/CLI/API iteration; writing integration/lab tests against CHR; needing host↔guest networking for a CHR (port-forward, L2/MNDP capture, guest→host UDP); driving an external RouterOS tool against a live CHR. For raw QEMU/CHR boot mechanics (VirtIO, UEFI vs SeaBIOS, acceleration) without quickchr, use routeros-qemu-chr instead.

适合你,如果需要在部署前用真实 RouterOS 环境测试配置或脚本

/ 下载安装
routeros-quickchr.skill双击,或拖进 Claude 桌面版 / Cowork,即完成安装↓ .skill↓ .zip
用别的 agent?下载 .zip 解压,把文件夹放进它的技能目录
Claude Code~/.claude/skills/(项目级 .claude/skills/)
Codex CLI~/.codex/skills/
Cursor自动读取上面两处目录
其他工具见其文档的「skills」目录;两个下载是同一份文件,只是名字不同
/ 通过 npx 安装 校验哈希
npx oh-my-skill add tikoci/routeros-skills/routeros-quickchr
/ 通过 bash 安装
curl -fsSL https://oh-my-skill.com/install.sh | bash -s -- tikoci/routeros-skills/routeros-quickchr
/ 已经装过?验证本机副本,不用重装
npx oh-my-skill verify tikoci/routeros-skills/routeros-quickchr
安装目标可用 --agent / --scope 或 --to 明确指定;省略时只会在唯一已存在的 agent 目录上自动选择,零命中或多命中会停止并提示。content_hash 缺失或不一致均拒装。
33GitHub stars
~2.3K最小装载
~3.5K含声明引用
~3.5K文本包总量
镜像托管

怎么用

技能原文 SKILL.md作者撰写 · MIT · 30e966c

Grounding RouterOS with quickchr

What this is for

The reliable way to know whether a RouterOS config, script, or API call actually works is to run it against real RouterOS — not to guess from docs. quickchr (@tikoci/quickchr, npm, MIT, public) makes that a few lines: it downloads a MikroTik CHR (Cloud Hosted Router) image, boots it under QEMU, provisions it, and hands you a REST/SSH/exec handle. The free CHR license (1 Mbps, no signup) is enough for config validation, API iteration, and test grounding.

Reach for quickchr when you want to apply config and read it back, iterate on REST/scripting against a live box, or run integration tests against CHR.

Don't reach for it when you only need documentation (use the rosetta MCP / the routeros-fundamentals skill), or you're flashing physical hardware (use the routeros-netinstall skill). For raw QEMU boot internals without the quickchr wrapper, see the routeros-qemu-chr skill.

The grounding loop (core pattern)
import { QuickCHR } from "@tikoci/quickchr";

const chr = await QuickCHR.start({ name: "lab", channel: "stable" });
// start() resolves REST-READY — provisioning is already done. No second wait needed
// in normal background/library use; waitForBoot() is only a belt-and-suspenders check.

await chr.exec("/ip/firewall/address-list/add list=blocked address=10.9.9.9");
const list = await chr.rest("/ip/firewall/address-list");   // structured read-back
// assert the entry is there → your config is grounded against real RouterOS

await chr.remove();   // tear down

exec() runs a CLI command (config writes, scripts) and returns { output, via }; rest() does a REST call and returns parsed JSON. Worked, runnable version: examples/grounding/. Minimal boot-and-read smoke test: examples/vienk/.

Tip — re-run safety. Give each run a unique machine name and assert on values carrying a per-run nonce, so a stale machine from an interrupted run can't make a later run pass falsely.
Key entry points

Pointers, not duplicated signatures — the authoritative, versioned reference is the quickchr MANUAL.md and the JSDoc in src/lib/types.ts. See also [references/quickchr-api.md](./references/quickchr-api.md) in this skill.

| Need | Surface | |---|---| | Boot / create a machine | QuickCHR.start(opts) → REST-ready ChrInstance | | Pick RouterOS | channel (stable/long-term/testing/development) or version ("7.23.1") | | Architecture | arch:"x86" or "arm64" | | Managed login vs open admin | secureLogin: true (managed user, real password) / false | | Run a CLI command | instance.exec(cmd, opts?) | | REST call | instance.rest(path, init?) | | Move files | instance.upload(local, remote?) / instance.download(remote, local) | | Add a package | instance.installPackage(name) (downloads + reboots; returns installed names) | | Custom port-forwards | extraPorts / CLI --forward (see Networking) | | Extra NICs | networks / CLI --add-network (see Networking) | | Connection surface for a child process | instance.subprocessEnv() / instance.descriptor() | | Snapshots | instance.snapshot(...) | | Tear down | instance.remove() / instance.stop() / instance.destroy() |

The same two knobs exist on the CLI and the library:

| CLI | Library (StartOptions) | |---|---| | --forward <spec> (repeatable) | extraPorts: PortMapping[] | | --add-network <spec> (repeatable) | networks: NetworkSpecifier[] |

CLI without installing: bunx @tikoci/quickchr <cmd> (e.g. add, start, exec, list, inspect, env, networks, logs). Library dependency patterns (npm / file: / bun link): examples/README.md.

Networking — which mechanism for which traffic

The default user (SLIRP) NIC handles management (REST/SSH/WinBox via host-port forward) and is all most grounding needs. Reach past it only for these shapes (full by-goal guide: docs/networking-recipes.md):

| You want… | Direction | Mechanism | |---|---|---| | Reach a guest TCP/UDP service (REST, SSH, WinBox, SNMP, container port) | host → guest | user NIC + hostfwd (--forward / extraPorts) | | Reach a guest service on many/dynamic ports (e.g. btest data ports) | host → guest | hostfwd range (--forward name:9200-9210:2000-2010/udp) | | Receive UDP the guest sends (syslog, NetFlow, TZSP, a server replying) | guest → host | guest sends to gateway 10.0.2.2:<port>; host binds an unconnected socket — no forward | | Receive guest L2 frames / broadcasts (MNDP, MAC-Telnet, raw Ethernet) | guest ↔ host | socket-connect L2 NIC (host runs a TCP server) | | L2 link between two VMs | VM ↔ VM | socket::<name> named pair | | Real LAN presence / DHCP from the host | full L3 | shared or bridged:<iface> |

Two non-obvious points worth keeping:

  • guest → host UDP needs no forward. The gateway 10.0.2.2 is the host from inside the VM. A datagram the guest sends to 10.0.2.2:<port> reaches a host socket bound on loopback — but leave that host socket unconnected (recvfrom): SLIRP relays it from a rewritten source (127.0.0.1:<ephemeral>), so a connect()-ed socket filters it out. instance.tzspGatewayIp (10.0.2.2) and instance.captureInterface (lo0/any) expose the constants. Runnable: examples/udp-gateway/.
  • user terminates Layer 2. For MNDP/MAC-Telnet/broadcasts, add a socket-connect NIC — the host runs a TCP server, QEMU streams length-prefixed guest frames to it (rootless, loopback-only, cross-platform). Recipe + wire detail: docs/mndp.md; examples/mndp/. Keep user first (ether1) in any multi-NIC config — RouterOS only auto-DHCPs ether1, and hostfwd needs the guest's 10.0.2.15.
Driving an external tool against a live CHR

To point a separate process at a running CHR (a schema extractor, a protocol suite, a CLI), use the stable connection surface instead of reading machine.json:

const env = await chr.subprocessEnv();   // URLBASE, BASICAUTH, QUICKCHR_*
Bun.spawn(["my-tool"], { env: { ...process.env, ...env } });

BASICAUTH / QUICKCHR_AUTH are the raw user:password string (not a header) — base64-encode for HTTP Basic: Authorization: Basic ${btoa(env.BASICAUTH)}. URLBASE already includes the /rest base. descriptor() gives the same surface as a structured { urls, auth, ports, status, version } record. Both are secret-bearing — pass via env, don't log. Always check a machine is running before using stored ports. Runnable: examples/harness/.

Grounding gotchas & known limitations
  • Provisioning floor: managed login, package install, and exec-write provisioning need RouterOS 7.20.8+; older 7.x is boot-only.
  • QGA (--via=qga) needs KVM — RouterOS only starts the guest agent under a KVM hypervisor, so it's unavailable under HVF (macOS) and TCG. Use REST/exec.
  • socket-mcast is broken on macOS (QEMU sets only SO_REUSEADDR); use socket-connect for point-to-point / host capture. Works on Linux.
  • Cross-arch TCG x86-on-arm64 is not viable (x86 I/O emulation is too slow); aarch64-on-x86 is fine. KVM/HVF require host/guest arch match.
  • Free CHR is rate-limited to 1 Mbps — fine for config/API grounding, not throughput tests. A free 60-day trial removes the limit.
Flakes: these examples and recipes are grounded on real CHR runs. If you hit a non-deterministic failure (a boot that wedges, an intermittent REST error), re-run once; if it persists, please file an issue with qemu.log at <https://github.com/tikoci/quickchr/issues> rather than working around it silently.
Authoritative docs & related skills
  • quickchr repo: README · MANUAL · DESIGN · docs/ · examples/
  • [references/quickchr-api.md](./references/quickchr-api.md) — fuller API map (start options, ChrInstance methods/properties, port layout, error codes).
  • routeros-qemu-chr — raw QEMU/CHR boot internals (VirtIO, UEFI/SeaBIOS, acceleration) underneath quickchr.
  • routeros-fundamentals — RouterOS CLI/REST/scripting once the CHR is up.
  • routeros-sniffer / routeros-mndp — TZSP capture and MNDP wire format (the gateway-UDP and socket-connect recipes above feed these).
按 MIT 许可原样转载,未经改动 · 在 GitHub 查看 →

评论

登录即可评论;带「已验证安装」的,是发布者名下有本店的安装或持有记录。