OpenGFW for iKuai
=================

基于 Netfilter NFQUEUE 的深度报文检测（DPI）插件。

引擎（OpenGFW）已内嵌进本插件，安装包内只有一个可执行文件 opengfwd：
检测引擎、面板、内核规则管理、自我保护都在同一个进程里。没有子进程，
没有日志管道。

面板地址
--------
http://<lan1-ip>:9170/dashboard

拦截默认关闭
------------
安装后不会阻断任何流量。默认规则是「只记录不拦截」，用来先观察识别结果，
确认符合预期后再把 action 改成 block。

两种模式
--------
网关模式（推荐）
  处理转发流量（FORWARD 链），即 LAN 客户端的上网流量。
  路由器自身的管理面不受影响。

本机模式（高级，慎用）
  处理路由器自身流量（INPUT/OUTPUT 链）。
  注意：此模式会接管管理面。它把路由器自己的出入流量交到用户态，一旦插件
  停止消费，队列里的报文会被扣住，管理通道可能随之卡住。插件内置两重保护
  （下文的「过载保护」与自动卸载），但都只是减小影响、不能消除影响。
  仅在需要短时诊断时使用，用完请立即关闭。
  自我保护：开启本机模式后会周期性探测本机出网，连续失败则自动卸下内核规则
  并关闭拦截（无需人工介入即可恢复）。本机模式不跨重启保留。

识别范围
--------
本插件不是要取代爱快内置的应用识别，而是补它的盲区。识别范围决定两者的分工：

辅助增强（默认，推荐）
  内核能识别的流量完全交给内核，插件只处理内核没有结论的那部分。
  判定条件是「内核未识别（appid 为 0）且内核未裁决」。
  爱快内置的应用识别、限速、MAC 绑定上网控制、ping 等功能都不受影响。

全量接管（备选）
  所有转发流量都经过本插件，规则对每一条流都生效。
  代价是性能与延迟：每个报文都要送到用户态处理，大流量下 CPU 与延迟会上升；
  同时规则写错的波及面从「内核未识别的那部分」扩大到全部转发流量。
  仅在明确需要时才选，应用设置里可切换。

组播噪声过滤
------------
默认开启。把组播与广播报文排除在检测队列之外：这类报文内核从不参与分类，会持续
占用队列（仅 SSDP/DLNA 的广播就足够占住），排除后不会漏掉任何需要检测的流量。
IPv4 与 IPv6 分别探测（两个协议族的匹配写法不同），若某个协议族不支持，面板会
明确显示为「部分生效」，而不是假装已生效。

过载保护
--------
使用爱快内核自带的 NFQUEUE 过载保护（默认开启）。

不开时用的是内核原生行为：队列一旦打满，后续报文直接被丢弃——在内网里这会
表现为断网。开启后，队列占用超过 90% 时改为放行，报文不再被丢。

请注意这是减小影响，不是免疫：已经进入队列的报文仍然在等待，所以插件若停止
处理，最多仍会有「队列长度」这么多报文被扣住。真正兜底的是插件自身的设计
（读取永不阻塞、异常自动卸载）与这个内核开关一起作用。

该开关是全内核生效的，与其它使用 NFQUEUE 的组件共用；本插件启动拦截时会按
设置置位，停止时还原为原先的值。

部署前提
--------
以下情况插件根本看不到流量，会直接拒绝启用并说明原因（而不是安静地一条都不
命中，让人误以为"没有匹配流量"）：

- 链路模式为旁路模式或 SD-WAN 网桥：这类流量走二层桥接，不经过 iptables。
- 检测到网桥透传。

加速模式（FASTOFFLOAD）不阻止启用，但会提示：开启后每条流只能看到前若干报文，
依赖整条流行为的检测（如全加密流量判定）会失效。

规则写法
--------
规则为 YAML 列表，每条形如：

  - name: log-dns
    action: allow      # allow / block / drop
    log: true
    expr: dns != nil

常用表达式片段（字段名必须是真实存在的分析器）：

  dns != nil                              DNS 查询
  tls != nil && tls.req.sni != ""         TLS SNI（注意 SNI 在 tls.req 下）
  quic != nil                             QUIC / HTTP3
  http != nil                             HTTP
  ssh != nil / socks != nil               SSH / SOCKS
  wireguard != nil / openvpn != nil       WireGuard / OpenVPN
  fet != nil && fet.yes                   全加密流量（Shadowsocks 类）
  trojan != nil                           Trojan 特征

注意：引擎不会拒绝写错的字段名（规则会静默永不命中），面板会在保存时校验，
请以面板的校验结果为准。例如并不存在 ss / vmess 分析器，全加密流量检测是 fet。

绕过名单
--------
填写不进入检测队列的 IP 或 CIDR，多个用逗号或换行分隔。规则会插在 NFQUEUE
之前，这些地址直接放行，不消耗检测资源。

安全须知
--------
- 开启拦截前，请先用「只记录」规则观察日志。
- 关闭拦截时会自动卸下内核挂载，不留残余规则；异常退出后重新启动也会清理。
- 若上次未正常退出（拦截仍处于挂载状态），本次开机不会自动恢复拦截。
- 本机模式不跨重启保留，每次都需要手动开启。
- 应用设置里的改动（识别范围、过载保护）在下次启动插件时生效；面板里的改动
  立即生效。

与爱快内置功能的关系
--------------------
在网络流量的处理顺序上，本插件的钩子位于爱快自身功能链之后：

  转发路径：ACL_MAC（MAC 绑定）→ 连接数限制 → 限速 → 防火墙 → 本插件

所以辅助增强模式不会绕过或削弱这些功能。全量接管的代价见上文。

日志
----
面板「日志」页显示引擎识别结果（命中规则、解析到的协议字段）。
文件：<插件目录>/log/engine.log（引擎输出）、log/run.log（插件自身状态）。
