【博客598】从netfilter hook执行原理分析iptables为什么自定义链无法主动调用只能从其它链跳转过来

news2024/12/26 2:28:36

从netfilter hook执行原理分析iptables为什么自定义链无法主动调用只能从其它链跳转过来

1、netfilter hook执行原理

netfilter 框架是 Linux 网络子系统里的一个核心模块,iptables 就是基于 netfilter 框架实现的一个网络包处理工具。


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

netfilter hook被调用后执行的过程剖析:

  • 所有点位都是通过一个叫 NF_HOOK 的函数来执行的
    nf_hook(pf, hook, net, sk, skb, in, out, okfn)有八个参数:

  • nf_hook参数解析:
    net:网络命名空间
    pf:协议(比如:ipv4的
    hook:点位(比如 output)
    处理的包:sk(socket)
    indev:放数据包进来的网络设备
    outdev:要放数据包出去的网络设备
    okfn:如果执行完 hook 数据包没被扔掉的话, 就掉用这个函数,也就是下一阶段要执行的函数。一个指向函数的指针,该函数将在该 hook 即将终止时调用,通常传入数据包处理路径上的下一个处理函数。

  • nf_hook_slow(skb, &state, hook_head, 0)这个调用中hook_head就是hook钩子函数的链表头,遍历改hook点的钩子函数,比如:对应iptables的规则,用户自定义hook函数等

  • nf_hook 函数根据 pf 和 hook 参数到内核存放 netfilter 规则的钩子数组里取出规则数组,然后在 nf_hook_slow 函数中去匹配并执行规则

  • nf_hook_slow 函数按数组顺序去匹配并执行每一条规则

  • NF_ACCEPT: 在处理路径上正常继续(实际上是在 NF-HOOK 中最后执行传入的 okfn)。

  • 每个钩子函数都有以下返回值,以决定下一步怎么走:
    NF_ACCEPT: 在处理路径上正常继续(实际上是在 NF-HOOK 中最后执行传入的 okfn)。
    NF_DROP: 丢弃数据包,终止处理。
    NF_STOLEN: 数据包已转交,终止处理。
    NF_QUEUE: 将数据包入队后供其他处理。
    NF_REPEAT: 重新调用当前 hook。

内核在处理流量的时候如何调用到netfilter hook:

  • 内核协议栈对PREROUTING的调用:

    Linux 在网络包接收在 IP 层的入口函数是 ip_rcv。网络在这里包碰到的第一个 HOOK 就是 PREROUTING

int ip_rcv(struct sk_buff *skb, ......){ 
    ...... 
    return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, dev, NULL, 
               ip_rcv_finish); 
 
} 
  • 内核协议栈对INPUT的调用:

    NF_HOOK 这个函数会执行到 iptables 中 pre_routing 里的各种表注册的各种规则。
    当处理完后,进入 ip_rcv_finish。在这里函数里将进行路由选择。
    如果发现是本地设备上的接收,会进入 ip_local_deliver 函数。接着是又会执行到 LOCAL_IN 钩子,这也就是我们说的 INPUT 链。

int ip_local_deliver(struct sk_buff *skb){ 
 ...... 
    return NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_IN, skb, skb->dev, NULL, 
               ip_local_deliver_finish); 
 
} 
  • 内核协议栈对OUTPUT的调用:

    Linux 在网络包发送的过程中,首先是发送的路由选择,然后碰到的第一个 HOOK 就是 OUTPUT,然后接着进入 POSTROUTING 链。

int __ip_local_out(struct sk_buff *skb) 
{ 
 struct iphdr *iph = ip_hdr(skb); 
 
 iph->tot_len = htons(skb->len); 
 ip_send_check(iph); 
 return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, skb, NULL, 
         skb_dst(skb)->dev, dst_output); 
} 
  • 内核协议栈对POSTROUTING的调用:

    output处理后,并获取到之前的选路,将进入 ip_output,这里会调用到POSTROUTING,处理完后就发送出去

//file: net/ipv4/ip_output.c 
int ip_output(struct sk_buff *skb) 
{ 
 ... 
 //再次交给 netfilter,完毕后回调 ip_finish_output 
 return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, NULL, dev, 
  ip_finish_output, 
  !(IPCB(skb)->flags & IPSKB_REROUTED)); 
} 
  • 内核协议栈对FORWARD的调用:

    除了接收和发送过程以外,Linux 内核还可以像路由器一样来工作。它将接收到网络包(不属于自己的),然后根据路由表选到合适的网卡设备将其转发出去。
    这个过程中,先是经历接收数据的前半段。在 ip_rcv 中经过 PREROUTING 链,然后路由后发现不是本设备的包,那就进入 ip_forward 函数进行转发,在这里又会遇到 FORWARD 链。最后还会进入 ip_output 进行真正的发送,遇到 POSTROUTING 链。转发过程的这几步和接收过程一模一样的。不过内核路径就要从上面的 input 方法调用开始不一样。非本设备的不会进入 ip_local_deliver,而是会进入到 ip_forward。

//file: net/ipv4/ip_forward.c 
int ip_forward(struct sk_buff *skb) 
{ 
 ...... 
 return NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD, skb, skb->dev, 
         rt->dst.dev, ip_forward_finish); 
} 

hook宏执行流程图解:

在执行 NF-HOOK 宏触发指定的 hook 时,将调用 nf_iterate 函数迭代这个 hook 对应的 nf_hook_ops 链表,并依次调用每一个 nf_hook_ops 的注册函数成员 hookfn。示意图如下:

在这里插入图片描述

这种链式调用回调函数的工作方式,也让 netfilter hook 被称为 Chain
每个回调函数也必须返回一个 netfilter 向量;如果该向量为 NF_ACCEPT,nf_iterate 将会继续调用下一个 nf_hook_ops 的回调函数,直到所有回调函数调用完毕后返回 NF_ACCEPT;如果该向量为 NF_DROP,将中断遍历并直接返回 NF_DROP;如果该向量为 NF_REPEAT,将重新执行该回调函数。 nf_iterate 的返回值也将作为 NF-HOOK 的返回值,网络栈将根据该向量值判断是否继续执行处理函数。

在这里插入图片描述

netfilter hook 的回调函数机制具有以下特性:

  • 回调函数按优先级依次执行,只有上一回调函数返回 NF_ACCEPT 才会继续执行下一回调函数。
  • 任一回调函数都可以中断该 hook 的回调函数执行链,同时要求整个网络栈中止对数据包的处理。

2、为什么自定义链无法主动触发,只能从其它链跳转过来被动触发

自定义链的触发依赖jump target:

跳转目标(jump target)jump target 是跳转到其 他 chain 继续处理的动作。很多内置的 chain,它们和调用它们的 netfilter hook 紧密联系在一起。iptables 也支持管理员创建他们自己的用于管理目的的自定义chain。

为什么自定义链无法主动调用只能从其它链跳转过来:

用户定义的 chain 只能通过从另一个规则跳转(jump)到它,因为它们没有注册到 netfilter hook,因为netfilter hook中没有自定义hook点,只有固定的5个内置点。 用户定义的 chain 可以看作是对调用它的 chain 的扩展。例如,用户定义的 chain 在结 束的时候,可以返回 netfilter hook,也可以继续跳转到其他自定义 chain。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/170872.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年“科学探索奖”申报启动及指南

2023年“科学探索奖”资助不超过50位青年科学家,每位获奖人5年内将获得总计300万元奖金。今年的申报时间为2023年1月1日至3月15日。获奖名单拟定于2023年8月揭晓。本文知识人网小编整理该奖项的概要及申报指南,以飨读者。“科学探索奖”是一项由科学家主…

【高并发内存池】第二弹之threadcache 线程缓存

1.为什么线程向threadcache申请内存不需要加锁? 因为没有把cache设置成全局变量,而是使用了TLS(线程局部存储),作用是当前内存只可当前线程见到,其他线程没有使用权,避免了加锁的操作,保证了线程数据的独立…

基于paddlex图像分类模型训练(一):图像分类数据集切分:文件夹转化为imagenet训练格式

背景 在使用paddlex GUI训练图像分类时,内部自动对导入的分类文件夹进行细分,本文主要介绍其图像分类数据切分源码,或可作为其他项目储备代码:https://github.com/PaddlePaddle/PaddleX/blob/develop/paddlex/tools/dataset_spli…

[Linux]进程概念以及进程状态

🥁作者: 华丞臧. 📕​​​​专栏:【LINUX】 各位读者老爷如果觉得博主写的不错,请诸位多多支持(点赞收藏关注)。如果有错误的地方,欢迎在评论区指出。 推荐一款刷题网站 👉 LeetCode刷题网站 文…

vs2019 + qt5.12.11 打包

目录 你以为打包方式 实际要添加步骤 你以为打包方式 先吐槽一番,感觉vsqt打包有点巨坑,还是说我第一次打包其实都是这样子的 首先我们将生成的.exe弄到一个打包文件夹里面 然后嘞 我用qt自带的打包工具windeployqt exe (因为我的再C盘下…

Mysql基础篇(11)—— MySQL8.0新特性之窗口函数

举例1 假设我现在有这样一个数据表,它显示了某购物网站在每个城市每个区的销售额: CREATE TABLE sales( id INT PRIMARY KEY AUTO_INCREMENT, city VARCHAR(15), county VARCHAR(15), sales_value DECIMAL ); INSERT INTO sales(city,county,sales_val…

【xgboost】XGBoost

XGBoost1. 原理改进及特点1.1 遵循Boosting算法的基本建模流程1.2 平衡精确性与复杂度1.3 降低模型复杂度、提升运行效率1.4 保留部份GBDT属性2. sklearn接口(回归)2.1 导库 & 数据2.2 sklearn api普通训练2.3 sklearn api交叉验证2.4 查看属性接口3. xgboost原生代码(回归…

Redis数据持久化方案

作为集中式缓存的优秀代表,Redis可以帮助我们在项目中完成很多特定的功能。Redis准确的说是一个非关系型数据库,但是由于其超高的并发处理性能,及其对于缓存场景所提供的一系列能力构建,使其成为了分布式系统中的集中缓存的绝佳选…

深入学习Vue.js(十)异步组件和函数式组件

文章目录异步组件需要解决的问题异步组件实现原理1.封装defineAsyncComponent函数2.超时与error3.延迟和Loading组件函数式组件异步组件需要解决的问题 允许用户指定加载出错时要渲染的组件允许用户指定Loading组件,以及展示该组件的延迟时间允许用户设置加载组件的…

8. R语言绘图系统介绍、高级绘图与低级绘图、【绘图参数】、绘图函数包

b站课程视频链接: https://www.bilibili.com/video/BV19x411X7C6?p1 腾讯课堂(最新,但是要花钱,我花99😢😢元买了,感觉讲的没问题,就是知识点结构有点乱,有点废话)&…

筑基一层 —— 高质量C编程建议、详解猜数字游戏

目录 一.修炼必备 二.高质量C编程 2.1 高质量C编程的思维导图(需要思维导图的加qq:972606225获取) 2.2 文件结构 2.3 程序的形式 2.4 命名规则 三.猜数字游戏详解 一.修炼必备 1.入门必备:VS2019社区版,下载地址:Visual S…

torch_geometric -- Pooling Layers

torch_geometric – Pooling Layers global_add_pool 通过在节点维度上添加节点特征来返回批量图级输出,因此对于单个图 它的输出由下式计算 from torch_geometric.nn import global_mean_pool, global_max_pool, global_add_pool import torch as thf [[1,2,3,4…

Wider Face+YOLOV8人脸检测

YOLO系列的算法更新实在太快了,前些天刚学习完YOLOV7,YOLOV8就出来了。今天先理解模型的训练过程,后续再学习V8的网络结构等细节。YOLOV8源码链接:https://github.com/ultralytics/ultralytics1 数据格式转换Wider Face数据格式转…

java -- 14 多态、内部类、常用API

自动类型转换:多态下引用数据类型的类型转换强制类型转换案例:定义usb接口:定义鼠标和键盘的usb实现类,并有自己特有的方法,重写usb接口的方法,里面穿插了多态创建电脑类,把usb接口揉和进去&…

如何改变视频的MD5值?一分钟让你学会操作

肯定很多不是从事自媒体的朋友对MD5不是很熟悉,但其实它类似于人的身份证,只不过我们的身份证是一串数字,而它则是视频的后台编码,所以这也是一些平台用MD5来判断视频是否重复的依据。那么有人会问了,既然MD5这么特殊&…

Java实战:使用Hutool中的MailUtil实现邮件的发送

❤️作者主页:IT技术分享社区 ❤️作者简介:大家好,我是IT技术分享社区的博主,从事C#、Java开发九年,对数据库、C#、Java、前端、运维、电脑技巧等经验丰富。 ❤️荣誉: CSDN博客专家、数据库优质创作者🏆&…

EasyExcel的导入导出使用

1、说明 EasyExcel是阿里出的一款基于Java的、快速、简洁、解决大文件内存溢出的处理Excel的开源工具,本文主要是使用这个工具对Excel导入导出进行讲解。 官网: https://easyexcel.opensource.alibaba.com/github: https://github.com/alib…

达梦主备之备库失联后在线恢复加入集群

一、主库故障重启(备库接管前重启) 主库故障后立即重启,此时主库的守护进程变成 Startup 状态,重新进入守护进程的 启动流程,将数据一致的备库归档设置为有效状态,其余备库归档设置成无效状态,并…

一些工具软件的使用

文章目录010 Editor设置16进制编辑时每行显示的字节数使用列模式编辑VS Code基础操作定义快捷键配置导出/导入列模式将文件中的tab键转换为空格关闭插件自动更新博文链接Beyond Compare文件内容相同依然显示差异过滤文件或文件夹Excel使用组合,进行行、列的折叠使用…

【DX-BT24蓝牙模块-AT命令与手机透传教程】

【DX-BT24蓝牙模块-AT命令与手机透传教程】1. 前言1.1.串口基本参数1.2.AT命令模式和透传模式1.3.模块数据吞吐量2. 接线2.1 模块线序定义2.2 相关AT命令详解2.2.1 命令格式说明2.2.2 回应格式说明2.2.3 AT命令举例说明3. AT命令详解3.1 基础指令3.2 AT指令测试3.3 手机测试4. …