之前我对 OpenWrt 的网络控制插件试用总结,最后只留下了插件 应用过滤(OpenAppFilter)
应用过滤(OpenAppFilter)的特征库虽然开发者有 VIP 服务,提供了更丰富的特征库,但我的需求只针对个别的一些网站过滤,所以研究了一下如何自己添加特征码。
对特征库有刚需的可以购买 VIP 支持一下开发者,也不算贵 39。

特征库文件

首先在这里下载免费的特征库:
网址:https://www.openappfilter.com/#/feature
解压后有三个文件,两个 bin 文件是特征库,可以看升级说明两个文件的不同:
oaf6
继续解压 bin 文件,可以看到一个 feature.cfg,一个 app_icons,很好理解了。
oaf7

特征码格式

特征库文件用于存储所有 APP 的特征码,为非加密的文本文件,一般 .cfg 格式,可以通过文本文档编辑。
特征库文件说明:https://github.com/destan19/OpenAppFilter/wiki/self%E2%80%90define-feature-file

特征码用于定义每个 APP 的协议特征,比如可以定义端口号、域名、七层内容字典等:

$id $name:[$proto;$sport;$dport;$host url;$request;$dict]

$id: 唯一的 APP 编号,不能重复
$name: APP 的名称,比如抖音
$proto: 传输层协议,tcp 或 udp
$sport: 源端口,1-65535,不设置表示匹配所有,一般不用设置源端口
$dport: 目的端口,1-65535,不设置表示匹配所有
$host: http或者https请求的域名,比如 www.baidu.com
$dict: 七层内容字典,格式 xx:aa|yy:bb,其中 xx,yy 是位置,表示第几个字节,而 aa,bb 表示十六进制内容,示例:00:a0|02:08|03:0a,表示第 0 个位置为 0xa0,第 2 个位置为 0x08,第 3 个位置为 0x0a,注意第一位从 0 开始,如果位置为负数,表示从最后一个开始,一般不要用负数表示。

自定义特征库

打开特征库文件 feature.cfg 后可以看到如下内容:

#class video 3 视频
3001 抖音:[tcp;;;-dy-;;,tcp;;;-dy.;;,tcp;;;douyin;;,tcp;;;amemv.com;;,tcp;;;pstatp.com;;,tcp;;;volcsirius.com;;,tcp;;80;;^/pull.*.douyincdn.com;,tcp;;;ecombdapi.com;;,udp;;443;;;09:51|10:30|11:34;amemv.com;0,udp;;16000;;;00:00|01:01,udp;;1000-2000;;;00:00|01:01]
3006 斗鱼:[tcp;;;douyu;;,tcp;;;douyu;;-2:2f|-1:00]
3004 爱奇艺:[tcp;;;iqiyi;;,tcp;;;qy.net;;,tcp;;;inter.71edge.com;;,tcp;;;;^/videos;,tcp;;80;;;00:51|01:48|02:54,tcp;;80;;;09:00|10:00|11:00]
3014 哔哩哔哩:[tcp;;;bilivideo;;,tcp;;;bilibili.com;;,tcp;;;data.bilibili.com;;,tcp;;;biliapi.net;;,tcp;;;;;00:47|05:75|06:70|07:67,tcp;;;;/bfs/emote/;,tcp;;;hdslb.com;;,tcp;;1000-10000;;/v1/resource;,tcp;;8082;;;;00:16|01:03|02:01]
3008 虎牙直播:[tcp;;;huya;;,udp;;;;;01:00|02:00|03:00|04:23,udp;;;;;01:00|02:00|03:00|04:24]
3010 小红书:[tcp;;;xiaohongshu;;,tcp;;;xhscdn;;]

可以在同一个分类中复制某个 APP 特征,追加到该分类的最后一行,这样用于保证 appid 中的分类字段是统一的 appid 的低 3 位表示分类中的编号,高位表示分类 id,比如 3001,其中 3 表示视频分类,而 001 为编号,表示抖音。
复制后首先需要修改 appid,保证组内唯一,最好是组内编号最大值加 1,比如当前最大值为 3012,那新的 appid 就设置成 3013,这样方便统一管理。
比如现在要增加一个 web 游戏网站 poki.com,那新增的特征码定义如下:
2117 宝玩:[tcp;;;*.poki-cdn.com;;,tcp;;;poki.com;;,tcp;;;t.poki.io;;]

多个网址之间可以用 , 分隔,相互之间是或的关系。
添加完成后,记得把文件页首的版本号更新一下。

获取网站的 logo 图片,大小格式为 50x50,PNG,如果不想找,随便用个替代图片也是可以的。图片按格式保存到 app_icons 文件夹内,名称按对应的 appid 命名。
我发现 app_icons 文件夹里的 appid 数量很多,所以 appid 最好先看下文件夹内的最大编号。

浏览器分析域名

在 PC 端使用 Chrome 开发者工具分析网站域名比较方便。

  • 使用 Chrome 打开网站前,先按键盘:F12 再切换到顶部 Network(网络)标签页。
  • 勾选上面的选项 Preserve log,以便页面跳转后保留请求记录。
  • 点击左上角的“🛑”停止按钮或“⨯”图标清除之前的请求。
  • 在浏览器地址栏输入 https://poki.com 并回车,开始加载页面。
  • 在 Network 里,有许多条请求记录,在 Name / Domain 列查看以下域名(如果没有就右键列首,勾选网域):

poki.com
*.poki.io
*.poki-cdn.com

这些都是页面加载过程中涉及的域名,可以按规则加入 feature.cfg

Wireshark 抓取没有域名的应用

有些没有明显域名但有独特流量特征的应用(如手游、专有加密协议)需要 Wireshark 抓包,获取 $dict 所需的字节特征(也就是七层协议数据中的特定字节内容)。
两种方法:

  • 用笔记本做热点,手机 WiFi 连接笔记本,直接用 Wireshark 抓包分析
  • 在路由器上用 tcpdump 抓取网络数据包,保存下来用 Wireshark 分析 .pcap 文件

我编译的 X86 固件添加了 tcpdump 插件,直接抓取,下载 pcap 文件,然后用 Wireshark 分析。
tcpdump-OpenWrt

  1. 选择要抓取的端口;
  2. 设置抓取时间;
  3. 抓包;

等待完成后即可看到 .pcap 文件。但是在插件页面不知道为什么点按钮无法下载,更换浏览器也不行,只能通过文件管理去下载,目录:/tmp/tcpdump/cap/

当然也可以在 OpenWrt 命令行中安装 tcpdump

opkg update
opkg install tcpdump

安装后通过终端命令抓包:
TCPdump
可以参考这里:OpenWrt抓包

Wireshark 打开文件后可使用下列过滤条件,如专门分析 IP:192.168.1.101 的设备数据:

ip.addr == 192.168.1.101 && (http.host || tls.handshake.extensions_server_name)

在任意一个 HTTPS 握手包选择后展开 Transport Layer SecurityExtension: server_name,右键 → Apply as Column,主界面就会多一列 Server Name,这样所有请求对应的域名一眼就能看出来了。
Wireshark 界面如下:
Wireshark

选中该应用 TCP/UDP 会话,查看数据包内容。如下:

0000   a0 45 13 10 00 1c 00 00 00 03 01 0a 00 00 00 01
0010 4f 12 09 45 01 5d ...

对应 $dict 规则:
00:a0|01:45|02:13|03:10

规则匹配建议:

  • 位置尽量靠前(前几十字节)
  • 尽量使用固定字段(如协议标志)
  • 避免使用 IP /端口变化的数据或会话 ID(不稳定)
  • 可以通过比较多个数据包找出固定不变的字节序列
  • 对于加密通信(如 HTTPS),可从 Client Hello / SNI 获取字节。
  • 对于 WebSocket,可查看握手包中独特字段。

其实我对 Wireshark 抓包分析也不熟,都是现学现卖。

封装 bin 文件

feature3.0_cn_20250316.bin 文件虽然解压就可以自定义特征码了,但如何重新封装成 bin 文件呢?开始我以为直接压缩后将格式改成 bin 就完事了,后来发现根本不行。
于是我先分析了一下 feature3.0_cn_20250316.bin

sudo apt install binwalk  # Ubuntu/Debian 安装 binwalk
binwalk feature3.0_cn_20250316.bin

接着会看到类似这样的输出:
DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 gzip compressed data, from Unix, last modified: 1970-01-01 00:00:00 (null date)

这说明 feature3.0_cn_20250316.bin 文件是纯 gzip 压缩文件。
目录结构如下:
feature/
├── feature.cfg
└── app_icons/
├── ...

先进入 feature 文件夹目录,再打包,封装成 .bin 格式:
tar -cf feature.tar feature.cfg app_icons  # 先将文件一起生成 tar 包
gzip -c feature.tar > feature3.0_cn_20250822.bin # 压缩成 .bin 格式

这样就生成了一个新的特征库文件:feature3.0_cn_20250822.bin。直接在插件管理页面上传就可以了。

应用过滤 特征库下载

分享一下我的特征库,添加了宝玩游戏和几个网盘。
夸克网盘分享:https://pan.quark.cn/s/e9e26f3f5881 提取码:n1MD

百度网盘分享:https://pan.baidu.com/s/1qcsD1XVwoLjC4J3vAwBh2A?pwd=hm8g 提取码: hm8g

OpenWrt X86 固件

我编译的 X86 固件,有应用过滤和网络控制插件,当然还有各种科学上网工具:
夸克网盘分享:https://pan.quark.cn/s/275136450f54
百度网盘分享:https://pan.baidu.com/s/1BTbtZJQvvUXtfwCAknNJdQ?pwd=xg1r 提取码: xg1r

应用过滤 openappfilter 的问题

  1. 过滤的网址,有可能还会引起其他的网址无法访问,比如我屏蔽了几个国内视频网站,接着 Google 就无法搜索了。原因不明,我也没找到解决方法。(有时又正常了)
  2. 应用过滤这个插件会影像 Docker,如果应用过滤启动了,那么容器会报 500 错误,只能先启动容器,再开启应用过滤插件。
  3. 如果同时打开了科学上网插件,那么应用过滤的网站同时也是代理的网站,那过滤无效。比如我开启了所有国外网站都走科学上网,那么应用过滤里的所有国外网站还是都能正常访问的。这就是我为什么没有把国外的社交网站,视频网站加到特征库的原因。