apfree-wifidog

apfree-wifidog is a high-performance captive portal solution that serves as a gateway between your wireless networks and the Internet. Optimized for both HTTP and HTTPS traffic, it ensures secure border control while enabling seamless user authentication and efficient network management. 技术交流QQ群 331230369

View project on GitHub
# ApFree WiFiDog - 认证服务器API文档

本文档详细说明了 ApFree WiFiDog 与认证服务器之间的通信接口。

## 1. Ping (心跳) 接口

此接口供 ApFree WiFiDog 定期通知认证服务器其处于活动状态,并报告基本系统状态。

*   **方法:** `GET`
*   **路径:**`auth_server_path` + `auth_server_ping_script_path_fragment` 构建 (在 `wifidog.conf` 中配置)。
*   **频率:** 通常每 60 秒一次。
*   **查询参数:**
    *   `device_id`: (字符串) WiFiDog 网关的唯一标识符。
    *   `sys_uptime`: (长整型) 系统运行时间 (秒)。
    *   `sys_memfree`: (无符号整型) 系统空闲内存 (KB)。
    *   `sys_load`: (浮点型) 系统平均负载 (1分钟)。
    *   `nf_conntrack_count`: (长整型) Netfilter 连接跟踪计数。
    *   `cpu_usage`: (双精度浮点型) CPU 使用率百分比。
    *   `wifidog_uptime`: (长整型) WiFiDog 进程运行时间 (秒)。
    *   `online_clients`: (整型) 当前在线客户端数量。
    *   `offline_clients`: (整型) 最近断开连接并已老化的客户端数量。
    *   `ssid`: (字符串) 网关的主 SSID (URL编码)。默认为 "NULL"。
    *   `fm_version`: (字符串) 设备固件版本。默认为 "null"。
    *   `type`: (字符串) 设备主板类型。默认为 "null"。
    *   `name`: (字符串) 设备主板名称。默认为 "null"。
    *   `wired_passed`: (整型) 如果有线客户端绕过门户则为1,否则为0。
    *   `aw_version`: (字符串) ApFree WiFiDog 软件版本。

*   **服务器响应:**
    *   **成功:** 响应体必须包含字符串 "Pong"。
    *   **成功操作:** WiFiDog 将认证服务器标记为在线。如果先前标记为离线,则更新防火墙规则。
    *   **失败:** 如果未找到 "Pong",或发生连接错误,WiFiDog 将认证服务器标记为离线,并可能更新防火墙规则以处理认证服务器不可用的情况 (例如,阻止客户端或允许所有客户端)。

## 2. Counters (计数器) 接口 (V2 版本)

此接口供 ApFree WiFiDog 定期向认证服务器发送所有已连接客户端的详细计数器信息。然后,服务器可以对特定客户端进行操作响应 (例如,断开连接)。

*   **方法:** `POST`
*   **路径:**`auth_server_path` + `auth_server_auth_script_path_fragment` 构建。
*   **路径中的查询参数:** `stage=counters_v2`
*   **频率:** 通常每 `checkinterval` (例如 60 秒) 一次。
*   **请求体:** `application/json`
    ```json
    {
      "device_id": "字符串", // WiFiDog 网关的唯一标识符
      "gateway": [
        {
          "gw_id": "字符串",      // 网关 ID
          "gw_channel": "字符串", // 网关信道
          "clients": [
            {
              "id": "整数",                  // WiFiDog 内部客户端 ID
              "ip": "字符串",                // 客户端 IPv4 地址
              "ip6": "字符串",               // 客户端 IPv6 地址 (或 "N/A")
              "mac": "字符串",               // 客户端 MAC 地址
              "token": "字符串",             // 客户端的认证令牌
              "name": "字符串",              // 客户端名称 (或 "N/A")
              "incoming_bytes": "长长整型",
              "outgoing_bytes": "长长整型",
              "incoming_rate": "长长整型",   // 字节/秒
              "outgoing_rate": "长长整型",   // 字节/秒
              "incoming_packets": "长长整型",
              "outgoing_packets": "长长整型",
              "incoming_bytes_v6": "长长整型",
              "outgoing_bytes_v6": "长长整型",
              "incoming_rate_v6": "长长整型", // 字节/秒
              "outgoing_rate_v6": "长长整型", // 字节/秒
              "incoming_packets_v6": "长长整型",
              "outgoing_packets_v6": "长长整型",
              "first_login": "长长整型",     // 客户端首次登录的时间戳
              "is_online": "布尔型",         // WiFiDog 知晓的当前在线状态
              "wired": "布尔型"              // 如果客户端是有线连接则为 true
            }
            // ... 更多客户端对象
          ]
        }
        // ... 更多网关对象 (单个设备通常只有一个)
      ]
    }
    ```

*   **服务器响应:** `application/json`
    ```json
    {
      "result": [
        {
          "gw_id": "字符串", // 此操作适用的网关 ID
          "auth_op": [
            {
              "id": "整数",        // 需要操作的 WiFiDog 内部客户端 ID
              "auth_code": "整数"  // 针对此客户端的操作代码
            }
            // ... 更多针对其他客户端的 auth_op 对象
          ]
        }
        // ... 更多 result 对象
      ]
    }
    ```
    *   **`auth_code` 值及 WiFiDog 操作:**
        *   `0` (AUTH_ALLOWED): 允许客户端。如果先前处于验证状态,计数器可能会被重置。
        *   `1` (AUTH_DENIED): 拒绝客户端。应用防火墙规则以阻止客户端,并将客户端从 WiFiDog 的活动列表中移除。
        *   `2` (AUTH_VALIDATION): 客户端处于验证阶段 (例如,等待邮件验证)。访问可能受限。
        *   `5` (AUTH_VALIDATION_FAILED): 验证失败或超时。拒绝客户端,应用防火墙规则,并移除客户端。
        *   其他代码可能用于特定的错误条件。

## 3. WebSocket 接口

此接口提供 ApFree WiFiDog 与认证服务器之间的持久性实时通信通道。

### 3.1. 连接建立

1.  **HTTP Upgrade 请求 (客户端到服务器):**
    *   **方法:** `GET`
    *   **路径:** 通过 `wifidog.conf` 中的 `ws_server_path` 配置。
    *   **头部信息:**
        *   `Host`: `<ws_server_hostname>:<ws_server_port>`
        *   `User-Agent`: `apfree-wifidog`
        *   `Upgrade`: `websocket`
        *   `Connection`: `upgrade`
        *   `Sec-WebSocket-Key`: 随机生成的24字节 Base64 字符串。
        *   `Sec-WebSocket-Version`: `13`

2.  **HTTP Upgrade 响应 (服务器到客户端):**
    *   **状态码:** `101 Switching Protocols`
    *   **头部信息:**
        *   `Upgrade`: `websocket`
        *   `Connection`: `Upgrade`
        *   `Sec-WebSocket-Accept`: 服务器计算的接受密钥 (客户端 `Sec-WebSocket-Key` 与标准 GUID 串联后的 SHA1 哈希值,再进行 Base64 编码)。

### 3.2. 客户端到服务器消息 (通过 WebSocket TEXT_FRAME 发送的 JSON 载荷)

1.  **初始 "Connect" (连接) 消息:**
    *   在 WebSocket 成功升级后立即发送。
    *   **JSON 结构:**
        ```json
        {
          "type": "connect", //  "heartbeat"
          "device_id": "字符串", // WiFiDog 网关的唯一 ID
          "gateway": [
            {
              "gw_id": "字符串",
              "gw_channel": "字符串",
              "gw_address_v4": "字符串",
              "auth_mode": "整数", // 网关当前认证模式
              "gw_interface": "字符串",
              "gw_address_v6": "字符串" // (可选)
            }
            // ... 如果配置了多个网关,则有更多网关对象
          ]
        }
        ```

2.  **周期性 "Heartbeat" (心跳) 消息:**
    *   每 60 秒发送一次。
    *   **JSON 结构:** 与 "connect" 消息结构相同,但 `"type": "heartbeat"````json
        {
          "type": "heartbeat",
          "device_id": "字符串",
          "gateway": [ /* ...  connect 结构相同 ... */ ]
        }
        ```

### 3.3. 服务器到客户端消息 (通过 WebSocket TEXT_FRAME 发送的 JSON 载荷)

WiFiDog 根据 JSON 载荷中的 `"type"` 字段解析传入消息。

1.  **Type: "heartbeat" 或 "connect" (服务器对客户端消息的响应)**
    *   这是服务器对客户端 connect/heartbeat 消息的确认/响应。
    *   **JSON 结构:**
        ```json
        {
          "type": "heartbeat", //  "connect"
          "gateway": [
            {
              "gw_id": "字符串",
              "auth_mode": "整数" // 此网关的新认证模式
            }
            // ... 更多网关对象
          ]
        }
        ```
    *   **WiFiDog 操作:** 更新每个指定 `gw_id` 的本地 `auth_mode`。如果任何模式发生更改,可能会重新加载防火墙规则。

2.  **Type: "auth" (服务器授予认证)**
    *   **JSON 结构:**
        ```json
        {
          "type": "auth",
          "token": "字符串",         // 客户端的认证令牌
          "client_ip": "字符串",
          "client_mac": "字符串",
          "client_name": "字符串",   // (可选)
          "gw_id": "字符串",         // 客户端所在的网关 ID
          "once_auth": "布尔型"     // 如果为 true,则为特殊的一次性认证处理
        }
        ```
    *   **WiFiDog 操作:**
        *   如果 `once_auth` 为 true: 将指定网关的 `auth_mode` 设置为 0 (绕过/无认证模式) 并重新加载防火墙。
        *   如果 `once_auth` 为 false: 使用提供的详细信息将客户端添加到已认证列表,并应用防火墙规则以允许访问。

3.  **Type: "kickoff" (服务器请求断开客户端连接)**
    *   **JSON 结构:**
        ```json
        {
          "type": "kickoff",
          "client_ip": "字符串",
          "client_mac": "字符串",
          "device_id": "字符串", // 必须与 WiFiDog 自身的 device_id 匹配
          "gw_id": "字符串"      // 必须与客户端当前的 gw_id 匹配
        }
        ```
    *   **WiFiDog 操作:** 验证 `device_id``gw_id`。如果正确且客户端存在,则应用防火墙规则拒绝访问,并将客户端从活动列表中移除。

4.  **Type: "tmp_pass" (服务器授予临时访问权限)**
    *   **JSON 结构:**
        ```json
        {
          "type": "tmp_pass",
          "client_mac": "字符串",
          "timeout": "整数" // (可选) 访问持续时间 (秒),默认为 300
        }
        ```
    *   **WiFiDog 操作:** 通过更新防火墙规则,为指定的 MAC 地址授予指定超时时间的临时网络访问权限。

5.  **Type: "get_trusted_domains" (服务器请求受信任的域)**
    *   **JSON 结构:**
        ```json
        {
          "type": "get_trusted_domains"
        }
        ```
    *   **WiFiDog 操作:** 使用包含当前受信任域列表的 `get_trusted_domains_response` 消息进行响应。

6.  **Type: "sync_trusted_domain" (服务器同步受信任的域)**
    *   **JSON 结构:**
        ```json
        {
          "type": "sync_trusted_domain",
          "domains": ["domain1.com", "domain2.com"]
        }
        ```
    *   **WiFiDog 操作:** 清除现有的受信任域列表,并用 `domains` 数组中提供的域替换它。

7.  **Type: "get_trusted_wildcard_domains" (服务器请求受信任的通配符域)**
    *   **JSON 结构:**
        ```json
        {
          "type": "get_trusted_wildcard_domains"
        }
        ```
    *   **WiFiDog 操作:** 使用包含当前受信任通配符域列表的 `get_trusted_wildcard_domains_response` 消息进行响应。

8.  **Type: "sync_trusted_wildcard_domain" (服务器同步受信任的通配符域)**
    *   **JSON 结构:**
        ```json
        {
          "type": "sync_trusted_wildcard_domain",
          "domains": [".domain1.com", ".domain2.com"]
        }
        ```
    *   **WiFiDog 操作:** 清除现有的受信任通配符域列表,并用 `domains` 数组中提供的域替换它。

5.  **Type: "firmware_upgrade" (固件升级指令)**
    *   服务器发送此消息以指示设备下载并应用新的固件。
    *   **JSON 结构:**
        ```json
        {
          "type": "firmware_upgrade",
          "url": "<firmware_download_url>"
        }
        ```
        *   `type`: (字符串) 必须为 "firmware_upgrade"。
        *   `url`: (字符串) 固件文件的下载地址。
    *   **WiFiDog 操作:**
        *   设备将记录接收到的 URL。
        *   设备将构造并执行系统命令: `sysupgrade <firmware_download_url>`        *   **重要提示:** 执行此命令后,设备预计将开始固件升级过程并随后重新启动。因此,**WiFiDog 不会就此特定命令向服务器发送任何显式的成功或失败确认消息**。认证服务器应通过监控设备的在线/离线状态来间接判断固件升级的结果。例如,设备在升级后重新上线并以新的固件版本进行心跳或连接,则可以认为升级成功。