netfiler 协议栈钩子

Netfilter 钩子,就是嵌入 Linux 内核网络协议栈路径上的"钩子点"。当数据包经过时,内核会触发这些钩子点,允许你注册的自定义函数介入,对数据包进行检查、修改或丢弃等处理。

下面这张图可以帮助你更直观地理解这些钩子在网络协议栈中的位置:
网络协议栈
目的为本机
目的为转发
网络接口 (接收)
NF_INET_PRE_ROUTING
路由判断
NF_INET_LOCAL_IN
上层协议 (TCP/UDP)
NF_INET_FORWARD
NF_INET_POST_ROUTING
网络接口 (发送)
本地进程发出
NF_INET_LOCAL_OUT

📍 五大"关口":核心钩子详解

IPv4 协议族定义了 5 个标准的钩子点,贯穿了数据包收发的完整生命周期:

  • NF_INET_PRE_ROUTING (路由前)

    • 时机:数据包刚进入网络栈,在路由判决之前。
    • 典型应用 :适合做目标地址转换(DNAT),比如根据目的IP/端口修改数据包。
  • NF_INET_LOCAL_IN (本地入站)

    • 时机:路由判决后,目标为本机,数据包将发往上层协议。
    • 典型应用 :本机防火墙规则,如限制对SSH端口的访问。
  • NF_INET_FORWARD (转发)

    • 时机:路由判决后,目标为其他主机,数据包将被转发。
    • 典型应用 :作为网关或路由器时,对经过流量进行过滤和管理。
  • NF_INET_LOCAL_OUT (本地出站)

    • 时机:本机进程发出的数据包,在第一次路由判决之后。
    • 典型应用 :限制本机进程的对外访问,或做源地址转换(SNAT)。
  • NF_INET_POST_ROUTING (路由后)

    • 时机 :数据包即将离开网络接口,是离开主机前的最后一站,也是SNAT的最佳位置。

⚙️ 机制与交互:钩子如何工作

每个钩子点上可以注册多个处理函数。为保证调用顺序,引入了优先级的概念:

  • 优先级 :Netfilter 执行钩子函数时,会 按 priority 字段的数值从小到大依次调用 (priority越小,优先级越高)。例如,-200 的优先级就高于 0。
  • 注册数据结构 (nf_hook_ops) :内核模块使用此结构来注册钩子函数,其中就包含协议族(pf)、钩子点(hooknum)和优先级(priority)等关键信息。
  • 常用优先级值 (Linux内核预定义)
    • -400:NF_IP_PRI_RAW (raw 表)
    • -300:NF_IP_PRI_MANGLE (mangle 表)
    • -200:NF_IP_PRI_CONNTRACK (conntrack)
    • -100:NF_IP_PRI_NAT_DST (DNAT)
    • -50:NF_IP_PRI_FILTER (filter 表)
    • 100:NF_IP_PRI_NAT_SRC (SNAT)

➕ 更多钩子:扩展与前沿

除了上述五大钩子,Netfilter 框架还包含几个重要的扩展钩子:

  • Ingress Hook :位于 NF_INET_PRE_ROUTING 之前,是数据包进入协议栈的第一道关卡 ,可以对流量进行早期过滤 。它按网络设备配置 ,而非全局,内核版本要求4.2+,且仅适用于 nftables。
  • Egress Hook :位于 NF_INET_POST_ROUTING 之后,是数据包离开内核前的最后一站 。它同样按网络设备配置 ,内核版本要求5.10+,也仅适用于 nftables。
  • Bridge Hooks (br_netfilter) :当 Linux 被用作网桥时,br_netfilter 模块允许网桥流量"绕道"进入 IPv4/IPv6 的 Netfilter 钩子,从而实现所有流量的统一策略。
  • 其他钩子 :例如 NF_INET_LOCAL_IN 和 NF_INET_LOCAL_OUT 钩子可以根据地址族配置网络地址转换(NAT),而 route 类型的钩子则可以在 IP 头更改后触发新的路由查找。

🛠️ iptables 与 nftables:权限外的说明

这部分的细节属于工具如何使用的问题,我们快速过一下要点:

  • iptables 中的表 :它是 Netfilter 钩子的用户态使用者。在 5 大钩子上注册了不同优先级、不同用途(filter, nat, mangle, raw)的规则。
  • nftables 的改进 :相比 iptables,取消了预定义链 ,让用户显式创建链;并可以使用关键字 (如 raw, filter)来设置优先级。
    • 创建 filter 表基本链示例: nft add chain inet my_table my_input_chain { type filter hook input priority 0; policy drop; }

🚀 eBPF 的介入

eBPF 可以在数据包处理路径的多个阶段 与 Netfilter 交互:在网卡驱动层 使用 XDP (eXpress Data Path) 进行最早期的处理 ,或使用 BPF_PROG_TYPE_NETFILTER 直接 替换传统的 Netfilter 钩子 进行快速决策,也可以从 conntrack 子系统中读取状态信息。

🔧 高级调试技巧

当规则不生效时,nft monitor trace 是一种 实时观察数据包匹配过程 的方法。例如,你可以这样追踪从特定 IP 发出的 ICMP 包:

bash 复制代码
nft add rule ip filter INPUT ip saddr 192.168.1.100 icmp type echo-request meta nftrace set 1
sudo nft monitor trace

若想清除所有跟踪规则,可以使用:

bash 复制代码
nft --check delete rule ip filter INPUT handle <X>

⚠️ 重要:br_netfilter 模块对数据包路径的影响

当 br_netfilter 内核模块被加载时,桥接的数据包处理路径会发生关键变化:

  • 路径改变 :数据包会从 br_netfilter 的钩子重新回到标准的 IPv4/IPv6 Netfilter 钩子进行处理。
  • 后果 :这意味着,原本期望在桥接层(如 bridge 族的 PREROUTING)处理的规则,可能会因为路径改变而不再生效。

🔬 实战:iptables 与 nftables 链的优先级对照

下面的对照表可以帮助你更清晰地理解,当 iptables 和 nftables 规则共存时,它们在同一个 Netfilter 钩子点上的执行顺序:

Netfilter 钩子点 iptables 链 / 表顺序 (优先级由高到低依次执行) nftables 链名示例 (以 priority 数字标识, 数字越小优先级越高)
NF_INET_PRE_ROUTING 1. raw (PREROUTING) 2. mangle (PREROUTING) 3. nat (PREROUTING, DNAT) my_prerouting_raw (prio -300) my_prerouting_mangle (prio -150) my_prerouting_nat (prio -100)
NF_INET_LOCAL_IN 1. mangle (INPUT) 2. filter (INPUT) my_input_mangle (prio -150) my_input_filter (prio 0)
NF_INET_FORWARD 1. mangle (FORWARD) 2. filter (FORWARD) my_forward_mangle (prio -150) my_forward_filter (prio 0)
NF_INET_LOCAL_OUT 1. raw (OUTPUT) 2. mangle (OUTPUT) 3. nat (OUTPUT) 4. filter (OUTPUT) my_output_raw (prio -300) my_output_mangle (prio -150) my_output_nat (prio -100) my_output_filter (prio 0)
NF_INET_POST_ROUTING 1. mangle (POSTROUTING) 2. nat (POSTROUTING, SNAT) my_postrouting_mangle (prio -150) my_postrouting_nat (prio 100)

无论你使用的是 iptables 还是 nftables,它们最终都依赖底层的 Netfilter 钩子。

相关推荐
闲云野鹤在人间7 分钟前
Ubuntu 24.04 安装过程
服务器·数据库·ubuntu
2401_8628808212 分钟前
input 子系统框架 、platform 驱动框架
linux·驱动开发·嵌入式硬件
Liuqy-0512 分钟前
线程的互斥与同步机制——互斥锁、条件变量、无名信号量
linux·开发语言·线程·进程·条件变量·同步·互斥
十年磨一剑~19 分钟前
LVDS 背光控制问题排查与 DTS 修正文档
linux·ubuntu
有毒的教程22 分钟前
Linux底层存储路由配置
linux·运维·网络
瑞克-桑切斯39 分钟前
2、Shell 条件语句
java·linux·服务器
霍格沃兹测试学院-小舟畅学39 分钟前
Playwright MCP:基于页面语义理解的元素定位与浏览器自动化操作
运维·自动化
数字化转型分享点滴1 小时前
机加工MES落地先连设备还是先上工单?一份车间实施参考
python·安全
yangmu32031 小时前
开发网站的完整流程:从0到1上线指南
运维·学习
梦帮科技1 小时前
Linux 内存取证学与 Rootkit 猎杀——Volatility 核心剖析与内核隐藏模块逆向清除
linux·运维·服务器·神经网络·算法·网络安全