做 Windows 网络开发,特别是防火墙、VPN、网络监控这类东西,WFP(Windows Filtering Platform)是绕不开的。不过一说起驱动、内核、Callout,确实容易让人头大。
这篇文章不讲复杂的API细节,只希望用最通俗的方式,把“WFP 是什么、能干什么、内部怎么回事”讲明白。
WFP 到底是干嘛的?
一句话概括:WFP是 Windows内核网络协议栈里的一个“万能插线板”。
它把网络数据流经的各个关键节点都预留了“插孔”(也就是过滤层),你可以把自己的处理逻辑(“插头”)插上去,实现对网络流量的拦截、检查、修改和放行/丢弃控制。
Windows 自带的防火墙,就是微软自己在这些“插孔”上插的“插头”。杀毒软件、家长控制、流量监控软件用的也是这套东西。
为什么要用 WFP?
在 WFP 出现之前,做网络过滤有几种老办法,比如 TDI 过滤、NDIS 中间层驱动、Winsock LSP 等等。这些技术各有各的问题:
- 有的只能管到某一段,没法全程控制;
- 有的不兼容 IPv6 等新协议;
- 有的和系统更新经常打架。
WFP最大的价值,就是把 Windows网络过滤这件事统一、标准化了。从 Vista/Server 2008 开始,它成了新一代防火墙和网络处理程序的基石。
WFP 的“四大件”
WFP 的体系结构大致可以理解为四个角色在分工协作:
- 垫片(Shims):贴身的“情报员”
这是嵌入在系统 TCP/IP 协议栈各层的内核模块,它们负责把经过的数据拦截下来,包装成 WFP 能理解的格式,然后交给过滤引擎做判断。
不同的垫片负责不同层次的流量,比如负责应用程序连接的 ALE 垫片、负责传输层数据的垫片、负责网络层的垫片等。你不用管垫片具体怎么写,它们是 WFP 框架自带的。
- 过滤引擎(Filter Engine):核心的“裁判”
这是真正干活的核心。它横跨内核态和用户态,里面分了大概50个内核层和10个用户层,数据在不同阶段会流经不同的层。
每个层内部又有子层(Sub-layer)和过滤器(Filter)。每个过滤器其实就是一条规则,比如“如果数据包的目标端口是 80,就放行”。当数据进来,过滤引擎会按优先级一条条比对规则,给出“允许”或“阻止”的判决。
- 基本筛选引擎(BFE):背后的“总调度”
BFE 是一个运行在用户态的系统服务(Base Filtering Engine),是整个 WFP 的管理和控制中心。
它主要干几件事:接收上层应用(比如防火墙管理界面)添加/删除规则的命令;对不同来源的策略做仲裁;把 IPsec 等策略配置分发出去。总之,BFE负责“下命令”,过滤引擎负责“执行”。
- 标注(Callouts):留给开发者的“自定义钩子”
这就是 WFP 最灵活的地方。内置的“允许/阻止”规则不够用?你可以自己写一个标注驱动(Callout Driver),注册一个或多个回调函数(Callout)。
你可以把这个标注挂在任何一个内核层上。当一个数据包匹配了使用该标注的过滤器时,你的 classifyFn 函数就会被调用。在里面你可以做:
- 深度包检测:检查数据内容里有没有病毒特征。
- 数据包修改:比如做 NAT,改写 IP 地址和端口。
- 流修改:比如家长控制,替换或移除数据流里的敏感词。
- 日志记录:记录所有被拦截的流量。
有了 Callout,WFP 就不再只是一个“开关”,而是变成了一个可以深度编程的网络处理平台。
WFP 是怎么分层的?
WFP 的分层是和 TCP/IP 协议栈对应的,从应用层数据一直到网卡出去的裸包,都有对应的过滤点。下面用发送一个TCP数据包的例子简单串一下:
- 应用层(ALE层):应用程序调用 send(),数据刚进内核。ALE_AUTH_CONNECT 层会被触发,这里是“连接授权”阶段,可以拿到进程 PID、程序路径、目的 IP/端口等信息。这是做“应用程序防火墙”最关键的层。
- 传输层(TRANSPORT层):TCP 包已经生成,但还没分片。在 OUTBOUND_TRANSPORT_V4 层可以拿到完整的 TCP 头和负载数据。
- 网络层(IPPACKET层):IP 包已经封装好,可能已经被分片了。在 OUTBOUND_IPPACKET_V4 层可以拿到 IP 头。这一层已经没有进程信息了,适合做 IP 级的过滤和 VPN 隧道封装。
如果数据是从网卡收上来的,顺序正好反过来,从 INBOUND_IPPACKET_V4 → INBOUND_TRANSPORT_V4 → ALE_AUTH_RECV_ACCEPT,一路向上。
使用时怎么选层?
不同的开发目标,选不同的层,以下整理了常用的分层处理类别:
你想做什么 | 推荐层 | 理由 |
禁止某程序联网、按进程控制 | ALE_AUTH_CONNECT / ALE_AUTH_RECV_ACCEPT | 能拿到完整的进程信息,且只处理连接的第一个包,性能好 |
分析 HTTP请求、检测 SQL注入 | STREAM 层(TCP 专用) | 数据已经过 TCP 重组,拿到的是连续的应用层数据流,方便解析 |
分析 DNS包(UDP) | DATAGRAM 层(UDP 专用) | 直接拿到完整的 UDP 数据报,适合 DNS 过滤 |
IP级防火墙、VPN隧道 | IPPACKET 层 | 最底层拦截,但也失去了进程和端口信息 |
小结
WFP 是 Windows 下做网络过滤的“正路”。它把网络协议栈的关键节点都开放出来,让你能用标准化的方式去拦截和处理流量。
虽然写标注驱动还是要啃 WDK 文档,但理解 WFP 这个“插线板”模型,基本概念就清晰了:数据在协议栈里跑,经过一个个“插孔”(层),你的“插头”(Callout)就在那里干活,告诉系统这个包是放行、丢弃、还是修改。