使用ebpf 监控linux内核中的nat转换

news2024/11/15 21:39:48

1.简介

Linux NAT(Network Address Translation)转换是一种网络技术,用于将一个或多个私有网络内的IP地址转换为一个公共的IP地址,以便与互联网通信。

在k8s业务场景中,业务组件之间的关系十分复杂.

由于 Kubernetes 的网络模型假设Pod之间访问时使用的是对方Pod 的实际地址,所以一个Pod内部的应用程序看到的自己的IP地址和端口与集群内其他Pod看到的一样 。它们都是Pod实际分配的IP地址 。 将IP地址和端口在Pod内部和外部都保待一致,也就不需要使用 NAT 进行地址转换了。

一些场景如cilium 并没有使用Netfilter的NAT转换.

2.linux中的NAT转换

linux的NAT转换是基于 Netfilter 网络框架实现的。

Netfilter 是 Linux 内核中一个对数据 包进行控制、修改和过滤(manipulation and filtering)的框架。它在内核协议 栈中设置了若干hook 点,以此对数据包进行拦截、过滤或其他处理。 Netfilter 是最古老的内核框架之一,1998 年开始开发,2000 年合并到 2.4.x 内 核主线版本 [5]。

Netfilter 官方文档:

 

https://www.netfilter.org/documentation/index.html

netfilter是Linux内核的包过滤框架,它提供了一系列的钩子(Hook)供其他模块控制包的流动。这些钩子包括

NF_IP_PRE_ROUTING:刚刚通过数据链路层解包进入网络层的数据包通过此钩子,它在路由之前处理

NF_IP_LOCAL_IN:经过路由查找后,送往本机(目的地址在本地)的包会通过此钩子

NF_IP_FORWARD:不是本地产生的并且目的地不是本地的包(即转发的包)会通过此钩子

NF_IP_LOCAL_OUT:所有本地生成的发往其他机器的包会通过该钩子

NF_IP_POST_ROUTING:在包就要离开本机之前会通过该钩子,它在路由之后处理。

3.使用conntrack读取nat转换

conntrack 是 netfilter一个模块。

NAT是在连接跟踪的基础上实现的,所以conntrack肯定是在NAT之前建立的。

conntrack注册的优先级:

 
enum nf_ip_hook_priorities {
	NF_IP_PRI_FIRST = INT_MIN,
	NF_IP_PRI_RAW_BEFORE_DEFRAG = -450,
	NF_IP_PRI_CONNTRACK_DEFRAG = -400,
	NF_IP_PRI_RAW = -300,
	NF_IP_PRI_SELINUX_FIRST = -225,
	NF_IP_PRI_CONNTRACK = -200,
	NF_IP_PRI_MANGLE = -150,
	NF_IP_PRI_NAT_DST = -100,
	NF_IP_PRI_FILTER = 0,
	NF_IP_PRI_SECURITY = 50,
	NF_IP_PRI_NAT_SRC = 100,
	NF_IP_PRI_SELINUX_LAST = 225,
	NF_IP_PRI_CONNTRACK_HELPER = 300,
	NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
	NF_IP_PRI_LAST = INT_MAX,
};

我们可以看到,NAT是在连接跟踪的基础上实现的,所以连接跟踪肯定是在NAT之前建立的。在上面的优先级中,优先级越小,越容易被先调用。

使用conntrack 查看当前节点NAT 转换情况

sudo conntrack -L -j

 
tcp 6 82 SYN_SENT src=172.19.0.2 dst=192.168.101.98 sport=55628 dport=443 [UNREPLIED] src=192.168.101.98 dst=192.168.1.3 sport=443 dport=55628 mark=0 use=1 conntrack v1.4.6 (conntrack-tools): 1 flow entries have been shown.

所以我们使用ebpf hook conntrack 就可以查看当前节点NAT 转换情况。

4. 使用ebpf hook conntrack

使用ebpf 拦截conntrack,我们主要拦截:


SEC("kprobe/__nf_conntrack_hash_insert")
 SEC("kprobe/ctnetlink_fill_info")

实现主流程 

hook住 __nf_conntrack_hash_insert:

SEC("kprobe/__nf_conntrack_hash_insert")
int BPF_KPROBE(kprobe___nf_conntrack_hash_insert, struct nf_conn *ct,unsigned int hash, unsigned int reply_hash) {
    u32 status = ct_status(ct);
    __maybe_unused possible_net_t p_net = BPF_CORE_READ(ct, ct_net);
    if (!(status&IPS_CONFIRMED)) {
        log_debug("kprobe/__nf_conntrack_hash_insert include IPS_CONFIRMED: netns: %u, status: %x\n", get_netns(&p_net), status);
        return 0;
    }
    if (!(status&IPS_NAT_MASK)) {
        return 0;
    }
    if (!(status&IPS_CONFIRMED) || !(status&IPS_NAT_MASK)) {
        log_debug("kprobe/filter: netns: %u, status: %x\n", get_netns(&p_net), status);
        return 0;
    }


    conntrack_tuple_t orig = {}, reply = {};
    if (nf_conn_to_conntrack_tuples(ct, &orig, &reply) != 0) {
        return 0;
    }

    bpf_map_update_with_telemetry(conntrack, &orig, &reply, BPF_ANY);
    bpf_map_update_with_telemetry(conntrack, &reply, &orig, BPF_ANY);
    increment_telemetry_registers_count();
    return 0;
}

hook住ctnetlink_fill_info:

SEC("kprobe/ctnetlink_fill_info")
int BPF_KPROBE(kprobe_ctnetlink_fill_info, struct nf_conn *ct) {

    proc_t proc = {};
    bpf_get_current_comm(&proc.comm, sizeof(proc.comm));

    if (!proc_t_comm_prefix_equals("system-probe", 12, proc)) {
        log_debug("skipping kprobe/ctnetlink_fill_info invocation from non-system-probe process\n");
        return 0;
    }

    u32 status = ct_status(ct);
    if (!(status&IPS_CONFIRMED) || !(status&IPS_NAT_MASK)) {
        return 0;
    }

    __maybe_unused possible_net_t c_net = BPF_CORE_READ(ct, ct_net);
    log_debug("kprobe/ctnetlink_fill_info: netns: %u, status: %x\n", get_netns(&c_net), status);

    conntrack_tuple_t orig = {}, reply = {};
    if (nf_conn_to_conntrack_tuples(ct, &orig, &reply) != 0) {
        return 0;
    }

    bpf_map_update_with_telemetry(conntrack, &orig, &reply, BPF_ANY);
    bpf_map_update_with_telemetry(conntrack, &reply, &orig, BPF_ANY);
    increment_telemetry_registers_count();

    return 0;
}

自此将kernel中的nat 的sock 五元组采集到了ebpf的map中,上报到用户空间。

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

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

相关文章

浅谈在操控器类中,为何要通过osgGA::CameraManipulator的逆矩阵改变视点位置

在osg代码目录下的include\osgGA目录存放了很多osg自带的操控器类,这些操控器类都派生自osgGA::CameraManipulator,而这个CameraManipulator又派生自osgGA::GUIEventHandler,可见其本质上是个事件处理类。因此它首先会接收事件,比…

月薪20k的软件测试工程师都要具备什么能力?你跟大佬的差距在哪?

第一,强大的业务能力:很熟悉业务流程,熟悉业务模块、数据、架构,测试所需资源。了解测试所需时间。 第二,发现bug能力:一般问题发现的能力,隐性问题发现能力,连带问题发现能力&…

专为实现最高性能和效率而设计,SQN3242UCKGTA、SQN3220SC、SQN3220 LTE-A Cat 6 模块【SKY85735-11射频前端】

一、SQN3242UCKGTA、SQN3220SC、SQN3220 LTE-A Cat 6 模块 1、简介 Sequans 的 Cassiopeia 是 Cat4 和 Cat6 LTE-Advanced 平台系列,包括集成了高性能网络和应用 CPU 的 SQN3220 Cat6 基带 SoC 和 SQN3220SC Cat4 基带 SoC、Sequans 的 SQN3242 LTE 优化收发器、经…

Pyhon-每日一练(1)

🌈write in front🌈 🧸大家好,我是Aileen🧸.希望你看完之后,能对你有所帮助,不足请指正!共同学习交流. 🆔本文由Aileen_0v0🧸 原创 CSDN首发🐒 如…

大华智慧园区前台任意文件上传(1day)

声明 本文仅用于技术交流,请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。 漏洞简介 大华智慧园区综合管理平台是一个集智能化、信息化、网络化、…

3D人脸生成的论文

一、TECA 1、论文信息 2、开源情况:comming soon TECA: Text-Guided Generation and Editing of Compositional 3D AvatarsGiven a text description, our method produces a compositional 3D avatar consisting of a mesh-based face and body and NeRF-based ha…

总结三:计算机网络面经

文章目录 1、简述静态路由和动态路由?2、说说有哪些路由协议,都是如何更新的?3、简述域名解析过程,本机如何干预域名解析?4、简述 DNS 查询服务器的基本流程是什么?DNS 劫持是什么?5、简述网关的…

CCS安装和运行TMS320F28004x第一个程序

1. CCS安装 TI 的MCU或者DSP,官方的集成开发环境是 Code Composer Studio™ ,要开发TI的芯片,首先需要安装 CCS 环境。 CCS 软件可以到下面的 TI 官网下载: https://www.ti.com.cn/tool/cn/CCSTUDIO 下载完之后,点击…

Pandas vs SQL全面对比

前一段时间给大家详解过 Pandas 的用法,今天再来分享下 Pandas 与 SQL 的对比。 Pandas 和 SQL 有很多相似之处,都是对二维表的数据进行查询、处理,都是数据分析中常用的工具。 对于只会 Pandas 或只会 SQL 的朋友,可以通过今天…

【QT5-程序控制电源-RS232-SCPI协议-上位机-基础样例【1】】

【QT5-程序控制电源-RS232-SCPI协议-上位机-基础样例【1】】 1、前言2、实验环境3、自我总结1、基础了解仪器控制-熟悉仪器2、连接SCPI协议3、选择控制方式-程控方式-RS2324、代码编写 4、熟悉协议-SCPI协议5、测试实验-测试指令(1)硬件连接(…

学习记忆——图像篇——记忆古诗词

《长歌行》 青青园中葵,朝露待日晞。 阳春布德泽,万物生光辉。 常恐秋节至,焜黄华叶衰。 百川东到海,何时复西归? 少壮不努力,老大徒伤悲!

wisemodel 始智AI - 小记

文章目录 关于 wisemodel 始智AI 关于 wisemodel 始智AI https://www.wisemodel.cn/home 旨在打造中国版 “HuggingFace” 该社区汇聚了清华 / 智谱 chatglm2-6B、Stable Diffusion V1.5、alphafold2、seamless m4t large 等模型,以及 shareGPT、ultrachat、moss-…

80%测试员被骗,关于jmeter 的一个弥天大谎!

jmeter是目前大家都喜欢用的一款性能测试工具,因为它小巧、简单易上手,所以很多人都愿意用它来做接口测试或者性能测试,因此,在目前企业中,使用各个jmeter的版本都有,其中以jmeter3.x、4.x的应该居多。 但是…

网络安全行业真的内卷了吗?网络安全就业必看

前言 有一个特别流行的词语叫做“内卷”: 城市内卷太严重了,年轻人不好找工作;教育内卷;考研内卷;当然还有计算机行业内卷…… 这里的内卷当然不是这个词原本的意思,而是“过剩”“饱和”的替代词。 按照…

c++ 学习 之 运算符重载 知识要点

我们要好好分清楚一些运算符的结果为 左值还是 右值 赋值与调用

5. Mysql卸载

Mysql卸载 已经成功安装mysql,没有必要卸载,卸载之后不一定再次会安装成功。 双击安装包 检查如下三个目录是否有mysql,有的话,删除掉即可(前提,电脑只有Mysql8,否则mysql其他版本也会被删除)…

c#设计模式-行为型模式 之 状态模式

🚀简介 状态模式是一种行为设计模式,它允许对象在其内部状态改变时改变其行为,我们可以通过创建一个状态接口和一些实现了该接口的状态类来实现状态模式。然后,我们可以创建一个上下文类,它会根据其当前的状态对象来改…

跨境电商卖家必知:如何提升订单好评的技巧大揭秘

随着跨境电商行业的不断发展,订单好评对于卖家来说变得越发重要。好评不仅能够提升产品和店铺的声誉,还能增加购买者的信任度,提高销售额。但是,如何获取更多的订单好评却是一个令卖家头疼的问题。下面将为您分享几个跨境电商订单…

PyTorch 深度学习实战

文章目录 前言1. 环境安装1.Anaconda2.pytorch cuda 环境3.测试 前言 1. 环境安装 1.Anaconda 可以参考这里:Anaconda学习 2.pytorch cuda 环境 我是按照下面的博客一步步完成,亲测有效 Pytorch安装教程(最全最详细版) 我的…

比特米盒子刷CoreELEC

CoreELEC就晶辰定制的Kodi版本,比特米盒子在刷入ATV后通过切换卡载系统可以安装CoreELEC即可安装,实现影音播放自由 1、U盘启动CoreELEC 1.1 、安装【安卓】切换卡载系统 通过U盘在已经刷好atv6.0的比特米盒子安装“切换卡载系统”。比特米盒子刷atv6.…