kprobe 是一种动态调试机制,用于debugging,动态跟踪,性能分析,动态修改内核行为等,2004年由IBM发布,是名为Dprobes工具集的底层实现机制[1][2],2005年合入Linux kernel。probe的含义是像一个探针,可以不修改分析对象源码的情况下,获取Kernel的运行时信息。
用于实时显示当前系统的性能统计信息。该命令主要用来观察整个系统当前的状态,比如可以通过查看该命令的输出来查看当前系统最耗时的内核函数或某个用户进程
在本系列的第 1 部分和第 2 部分,我们介绍了 eBPF 虚拟机内部工作原理,在第 3 部分我们研究了基于底层虚拟机机制之上开发和使用 eBPF 程序的主流方式。
当碰到内核线程的资源使用异常时,很多常用的进程级性能工具,并不能直接用到内核线程上。这时,我们就可以使用内核自带的 perf 来观察它们的行为,找出热点函数,进一步定位性能瓶颈。不过,perf 产生的汇总报告并不直观,所以我通常也推荐用火焰图来协助排查。
不必太纠结于当下,也不必太忧虑未来,当你经历过一些事情的时候,眼前的风景已经和从前不一样了。——村上春树
Linux 存在众多 tracing tools,比如 ftrace、perf,他们可用于内核的调试、提高内核的可观测性。众多的工具也意味着繁杂的概念,诸如 tracepoint、trace events、kprobe、eBPF 等,甚至让人搞不清楚他们到底是干什么的。本文尝试理清这些概念。
ply 是 eBPF 的 front-end 前端工具之一,专为 embedded Linux systems 开发,采用 C 语言编写,只需 libc 和内核支持 BPF 就可以运行,不需要外部 kernel 模块,不需要 LLVM,不需要 python。
bpftrace提供了一种快速利用eBPF实现动态追踪的方法,可以作为简单的命令行工具或者入门级编程工具来使用。本文以bpftrace为例,介绍如何利用eBPF实现内核的动态追踪。
Ftrace是Linux Kernel的官方tracing系统,支持Function trace、静态tracepoint、动态Tracepoint的跟踪,还提供各种Tracer,用于统计最大irq延迟、最大函数调用栈大小、调度事件等。
Linux kprobes调试技术是内核开发者们专门为了便于跟踪内核函数执行状态所设计的一种轻量级内核调试技术。利用kprobes技术,内核开发人员可以在内核的绝大多数指定函数中动态的插入探测点来收集所需的调试状态信息而基本不影响内核原有的执行流程。kprobes技术目前提供了3种探测手段:kprobe、jprobe和kretprobe,其中jprobe和kretprobe是基于kprobe实现的,他们分别应用于不同的探测场景中。本文首先简单描述这3种探测技术的原理与区别,然后主要围绕其中的kprobe技术进行分析并给出一个简单的实例介绍如何利用kprobe进行内核函数探测,最后分析kprobe的实现过程(jprobe和kretprobe会在后续的博文中进行分析)。
bpftrace 通过高度抽象的封装来使用 eBPF,大多数功能只需要寥寥几笔就可以运行起来,可以很快让我们搞清楚 eBPF 是什么样的,而暂时不关心 eBPF 复杂的内部机理。由于 bpftrace 深受 AWK 和 c 的影响,bpftrace 使用起来于 AWK 非常相似,那些内核 hook 注入点几乎可以按普通字符串匹配来理解,非常容易上手。
eBPF (Extended Berkeley Packet Filter) 是 Linux 内核上的一个强大的网络和性能分析工具。它允许开发者在内核运行时动态加载、更新和运行用户定义的代码。
本章的我们来学习uprobe ,顾名思义,相对于内核函数/地址的监控,主要用于用户态函数/地址的监控。听起来是不是有点神奇,内核怎么监控用户态函数的调用呢?本章的内容包括:
几乎所有编程接口都可见于:内核源代码的include/uapi/linux/bpf.h文件中
BCC是一个用于跟踪内核和操作程序的工具集,其软件包中包含了一些有用的工具和例子,它扩展了BPF(Berkeley Packet Filters),通常被称为eBPF , 在Linux3.15中首次引入,但大多数BCC的功能需要Libux4.1及以上版本。
本文主要用于演示基于 ebpf 技术来实现对于系统调用跟踪和特定条件过滤,实现基于 BCC[1] 的 Python 前端绑定,过程中对于代码的实现进行了详细的解释,可以作为学习 ebpf 技术解决实际问题的参考样例。
之前使用ftrace的时候需要一系列的配置,使用起来有点繁琐,这里推荐一个ftrace的一个前端工具,它就是trace-cmd
在日常分析外部软件时,遇到的反调试/反注入防护已经越来越多,之前使用的基于 frida 的轻量级沙盒已经无法满足这类攻防水位的需要,因此需要有一种更加深入且通用的方式来对 APP 进行全面的监测和绕过。本文即为对这类方案的一些探索和实践。
在本系列的前一篇文章中,我讨论了如何使用eBPF安全地运行内核内用户空间提供的代码。然而,对于新手来说,eBPF最大的挑战之一是编写程序需要编译并从内核源代码链接到eBPF库。内核开发人员可能总是可以获得内核源代码的副本,但是对于在生产环境机器或客户机器上工作的工程师来说,情况就不一样了。解决这个限制是创建BPF编译器集合的原因之一。该项目包括用于编写、编译和加载eBPF程序的工具链,以及用于调试和诊断性能问题的示例程序和久经考验的工具。
开发人员在内核或者模块的调试过程中,往往会需要要知道其中的一些函数有无被调用、何时被调用、执行是否正确以及函数的入参和返回值是什么等等。
本文讲述如何将基于BCC的BPF应用转换为libbpf + BPF CO-RE。BPF CO-RE可以参见上一篇博文。
前言:ebpf 是现代 Linux 内核提供的非常复杂和强大的技术,它使得 Linux 内核变得可编程,不再是完全的黑盒子。随着 ebpf 的发展和成熟,其应用也越来越广泛,本文介绍如何使用 ebpf 来追踪 Node.js 底层的代码。
本文基于libbpf实现的ebpf例子介绍tracepoint类型ebpf程序调用流程,内核实现以5.4版本为例进行介绍。
作者 | 许庆伟 策划 | 凌敏 随着 eBPF 技术在各种行业领域上的使用和普及,人们在享受着技术变革红利的同时,也遭受着无孔不入的恶意攻击。就像任何事物都有两面性一样,没有任何一项技术只有高高在上的优势,而没有弊端。只有更加清晰地剖析清楚 eBPF 的内核,才能推动它不断地进步,趋利避害,尽可能发挥正向的作用。 1 eBPF 的安全能力是检验其可持续发展的重要指标 日益严峻的 Linux 安全形势 根据安全分析机构 ESG 云原生安全研究,88% 的网络安全专业人士表示,在过去 12 个
问题场景: 云计算IaaS平台上,经常使用libvirt+qemu-kvm做基础平台。libvirt会在/etc/libvirt/qemu/目录下,保存很多份qemu的配置文件,如ubuntu.xml。 作者发现其中的配置文件会在特定的场景下被修改,却不知道哪个进程是凶手。为了找到凶手,作者写下了这个debug工具。 代码分析: 代码路径:https://github.com/pacepi/whotouchmyfile #include <linux/kernel.h> #include <linux/mo
最近发布的 Linux 内核带了一个针对内核的能力强大的 Linux 监控框架。它起源于历史上人们所说的的 BPF。
不需要写main函数,目前知道可以写两种函数,以“kprobe__”开头的函数和自定义函数。bpf函数至少要包含一个参数“ctx”,即使不使用也应该存在,可以声明为“void *ctx”。
网络攻击者通常会利用被攻击网站中存在的漏洞,通过在网页中植入非法暗链对网页内容进行篡改等方式,进行非法牟利或者恶意商业攻击等活动。网页被恶意篡改会影响用户正常访问网页内容,还可能会导致严重的经济损失、品牌损失甚至是政治风险。
为了安全,Linux 中分为用户态和内核态两种运行状态。对于普通进程,平时都是运行在用户态下,仅拥有基本的运行能力。当进行一些敏感操作,比如说要打开文件(open)然后进行写入(write)、分配内存(malloc)时,就会切换到内核态。内核态进行相应的检查,如果通过了,则按照进程的要求执行相应的操作,分配相应的资源。这种机制被称为系统调用,用户态进程发起调用,切换到内核态,内核态完成,返回用户态继续执行,是用户态唯一主动切换到内核态的合法手段(exception 和 interrupt 是被动切换)。
从之前的分析已经得知,.c的eBPF程序会通过BCC等工具编译并加载到内核中,但是具体在内核中,ebpf是如何工作的呢?
利用linux kernel 动态追踪技术,排查问题本身就可能会变成一个非常有趣的过程,让我们遇到线上的诡异问题就感到兴奋,就仿佛好不容易又逮着机会,可以去解一道迷人的谜题。
eBPF is a revolutionary technology with origins in the Linux kernel that can run sandboxed programs in an operating system kernel. It is used to safely and efficiently extend the capabilities of the kernel without requiring to change kernel source code or load kernel modules.
BPF,及伯克利包过滤器Berkeley Packet Filter,最初构想提出于 1992 年,其目的是为了提供一种过滤包的方法,并且要避免从内核空间到用户空间的无用的数据包复制行为。它最初是由从用户空间注入到内核的一个简单的字节码构成,它在那个位置利用一个校验器进行检查 —— 以避免内核崩溃或者安全问题 —— 并附着到一个套接字上,接着在每个接收到的包上运行。几年后它被移植到 Linux 上,并且应用于一小部分应用程序上(例如,tcpdump)。其简化的语言以及存在于内核中的即时编译器(JIT),使 BPF 成为一个性能卓越的工具。
注:本文包括了ebpf的原理介绍、流程分析、相关资料链接、工具编写实战等,可以选择感兴趣的部分直接阅读;鉴于作者语文水平有限,很多地方描述可能不清楚,有错误或疑问欢迎指出交流
将 eBPF 程序附加到跟踪点以及内核和用户应用探针点的能力,使得应用程序和系统本身的运行时行为具有前所未有的可见性。通过赋予应用程序和系统两方面的检测能力,可以将两种视图结合起来,从而获得强大而独特的洞察力来排除系统性能问题。
Linux内核调试技术——kprobe使用与实现(五)-触发kprobe探测和回调
Tcpdump 是Linux 平台常用的网络数据包抓取及分析工具,tcpdump 主要通过libpcap 实现,而libpcap 就是基于eBPF。
在上一篇文章《eBPF动手实践系列二:构建基于纯C语言的eBPF项目》中,我们初步实现了脱离内核源码进行纯C语言eBPF项目的构建。libbpf库在早期和内核源码结合的比较紧密,如今的libbpf库更加成熟,已经完全脱离内核源码独立发展。
对于kprobe功能的实现主要利用了内核中的两个功能特性:异常(尤其是int 3),单步执行(EFLAGS中的TF标志)。
我们可以使用BPF对Linux内核进行跟踪,收集我们想要的内核数据,从而对Linux中的程序进行分析和调试。与其它的跟踪技术相比,使用BPF的主要优点是几乎可以访问Linux内核和应用程序的任何信息,同时,BPF对系统性能影响很小,执行效率很高,而且开发人员不需要因为收集数据而修改程序。
Linux kprobes调试技术是内核开发者们专门为了便于跟踪内核函数执行状态所设计的一种轻量级内核调试技术。利用kprobes技术,内核开发人员可以在内核的绝大多数指定函数中动态的插入探测点来收集所需的调试状态信息而基本不影响内核原有的执行流程。kprobes技术目前提供了3种探测手段:kprobe、jprobe和kretprobe,其中jprobe和kretprobe是基于kprobe实现的,他们分别应用于不同的探测场景中。
在云函数的日常运营中,经常有用户提出要求协助排查网络问题。一般的手段就是使用 tcpdump 抓包,但是部署抓包往往是在问题发生之后,而且抓包后复现的时机也不确定,往往费时费力。本文讲述使用 BPF 记录 TCP 的重传和丢包记录,作为定位网络问题的一种辅助手段。
我们不久前定位了一个Linux内核bug,这个bug会影响所有在特权容器中启用了use-gss-proxy的Linux环境,表现为容器的网络命名空间(net namespace)无法彻底释放,导致容器终止后关联的虚拟网卡未能自动清除,运行时间长的机器上会观察到内存泄露。目前upstream还没有对这个bug的修复,我们内部已经做好了patch待测。 这个问题的定位过程很有借鉴价值,特此与大家分享。 【问题现象】 在k8s环境里,容器终止之后概率性地发生弹性网卡残留现象,而且只有privileged容器
领取专属 10元无门槛券
手把手带您无忧上云