ai管理openwrt

Other

OpenWRT 路由器管理与监控。通过 LuCI Web 接口(无 SSH 依赖)管理 OpenWRT 路由器,支持 DHCP 租约查询、在线设备列表查看、WiFi 客户端管理、网络状态监控等。当用户提到路由器管理、查看联网设备、WiFi 状态、DHCP 租约、OpenWRT/LEDE 等时触发。

Install

openclaw skills install openwrt-router-skill

OpenWRT Router

概述

通过 LuCI RPC API 远程管理 OpenWRT 路由器,无需 SSH 或 telnet。使用 curl + HTTP Cookie 认证,通过 cgi-bin/luci/rpc/sys 接口执行 shell 命令。

原理

认证流程

  1. 用用户名/密码 POST 登录 LuCI 登录页面
  2. 保存返回的 sysauth cookie
  3. 用 cookie + RPC API 执行命令

RPC API 地址

POST http://<router-ip>/cgi-bin/luci/rpc/sys?auth=<sysauth_token>

参数为 JSON: {"method":"exec","params":["<shell_command>"]} 返回 JSON: {"id":null,"result":"<stdout>","error":null}

多路由器管理

支持同时管理多台 OpenWRT 路由器,通过别名(如 "家"、"租房")来区分。

配置方式

TOOLS.md 中记录路由器信息:

### OpenWRT 路由器

- **家** 
  - IP: 192.168.123.1
  - 用户: root
  - 密码: xxx
- **租房**
  - IP: 192.168.125.1  
  - 用户: root
  - 密码: xxx

使用方式

用户可以说:

  • "看看家里路由器的联网情况"
  • "租房那边有人蹭网吗"
  • "查一下家里的 DHCP 租约"
  • "看看租房装了哪些软件"

网络打通的情况

如果路由器之间网络已打通(如通过 WireGuard、Tailscale、FRP 等),一台机器就可以直接管理所有路由器,只需切换目标 IP 即可。

前置条件

  • 需要 curl 命令
  • 用户提供:路由器 IP、用户名、密码(或记录在 TOOLS.md 中)

核心操作

1. 登录路由器

curl -s -m 10 -X POST "http://<router_ip>/cgi-bin/luci/" \
  -d "luci_username=root&luci_password=<password>" \
  -c /tmp/luci_cookies.txt

登录成功后 cookie 文件包含 sysauth token。

2. 执行命令

SYS_AUTH=$(grep sysauth /tmp/luci_cookies.txt | awk '{print $NF}')
curl -s -m 10 -b /tmp/luci_cookies.txt \
  -H "Content-Type: application/json" \
  -X POST "http://<router_ip>/cgi-bin/luci/rpc/sys?auth=$SYS_AUTH" \
  -d '{"method":"exec","params":["<command>"]}'

3. 常用命令

查看 DHCP 租约(所有分配了 IP 的设备)

cat /tmp/dhcp.leases

输出格式:租约过期时间 MAC地址 IP地址 主机名

查看 ARP 表(当前活跃的有线设备)

cat /proc/net/arp

查看 WiFi 连接设备

iwinfo <interface> assoclist

先用以下命令查看无线接口名:

iwinfo 2>/dev/null | grep ESSID
# 或
iw dev

查看无线接口列表

ls /sys/class/net/
# 用 grep 过滤 ESSID
iwinfo 2>/dev/null | grep -E "ESSID" 

获取系统负载/运行时间

uptime
cat /proc/loadavg

查看活跃连接数

cat /proc/net/nf_conntrack 2>/dev/null | wc -l

4. 数据解析示例

从 DHPC 租约拿到纯文本后用 \u000a(Python 的 \n 换行 Unicode 转义)分隔行:

{"result": "MAC1 IP1 Name1\u000aMAC2 IP2 Name2\u000a"}

WiFi assoclist 输出格式:

MAC_ADDRESS  -XX dBm / -XX dBm (SNR XX)  XXX ms ago
     RX: XX MBit/s, MCS X, XXMHz     XXX Pkts.
     TX: XX MBit/s, MCS X, XXMHz     XXX Pkts.
  • RX = 接收速率
  • TX = 发送速率
  • dBm 越小信号越差(负值)
  • SNR = 信噪比,越高越好

使用流程

flowchart TD
    A[用户提供路由器信息] --> B[cURL 登录 LuCI]
    B --> C{登录成功?}
    C -->|是| D[获取 DHCP 租约]
    C -->|否| E[返回错误信息]
    D --> F[获取 WiFi 连接设备]
    F --> G[获取 ARP 表]
    G --> H[解析并展示结果]

完整示例(Python)

import json, subprocess

def router_api(ip, password, cmd):
    # 1. 登录
    subprocess.run(["curl", "-s", "-m", "10", "-X", "POST",
        f"http://{ip}/cgi-bin/luci/",
        "-d", f"luci_username=root&luci_password={password}",
        "-c", "/tmp/luci_cookies.txt"])
    
    # 2. 获取 auth
    with open("/tmp/luci_cookies.txt") as f:
        for line in f:
            if "sysauth" in line:
                token = line.strip().split()[-1]
    
    # 3. 执行命令
    r = subprocess.run(["curl", "-s", "-m", "10", "-b", "/tmp/luci_cookies.txt",
        "-H", "Content-Type: application/json",
        "-X", "POST", f"http://{ip}/cgi-bin/luci/rpc/sys?auth={token}",
        "-d", json.dumps({"method": "exec", "params": [cmd]})],
        capture_output=True, text=True)
    
    return json.loads(r.stdout).get("result", "")

注意事项

  • 密码中含有特殊字符(如 @#$)时,curl 的 -d 参数需要使用引号包裹
  • 某些 OpenWRT 版本可能需要额外的 cookie 路径设置
  • 执行结果中含 \u000a 是 Unicode 换行符转义,需要 Python 的 decode("unicode_escape") 或 JSON 反序列化自动处理
  • RPC API 返回的 error 字段为 null 表示成功
  • 不是所有 OpenWRT 固件都预装 iwinfo 命令(新版可能用 iw 替代)