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内核预定义)
    • -400NF_IP_PRI_RAW (raw 表)
    • -300NF_IP_PRI_MANGLE (mangle 表)
    • -200NF_IP_PRI_CONNTRACK (conntrack)
    • -100NF_IP_PRI_NAT_DST (DNAT)
    • -50NF_IP_PRI_FILTER (filter 表)
    • 100NF_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_INNF_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 链的优先级对照

下面的对照表可以帮助你更清晰地理解,当 iptablesnftables 规则共存时,它们在同一个 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 钩子。

相关推荐
小辰记事本1 小时前
从零读懂RoCEv2数据包构造:从WQE到线缆上的完整旅程
服务器·网络·网络协议·rdma
小鹏linux2 小时前
Ubuntu 22.04 部署开源免费具有精美现代web页面的Casdoor账号管理系统
linux·前端·ubuntu·开源·堡垒机
在角落发呆3 小时前
Linux转发配置:解锁网络互联的核心密码
linux·运维·网络
齐潇宇3 小时前
Zabbix 7 概述与配置
linux·zabbix·监控告警
裴东青5 小时前
10-实战:RuoYi-Cloud的自动化发布
运维·ci/cd·自动化
江公望5 小时前
Ubuntu htop命令,10分钟讲清楚
linux·服务器
哎呦,帅小伙哦5 小时前
Linux 时间:从原子钟到 clock_gettime 的每一面
linux·运维·服务器
sxgzzn5 小时前
新能源场站数智化转型:基于数字孪生与AI的智慧运维管理平台解析
大数据·运维·人工智能
张小姐的猫5 小时前
【Linux】多线程 —— 线程互斥
linux·运维·服务器·c++
CodeMartain5 小时前
Dify Windows 原生部署(无 Docker、纯本地)
运维·docker·容器