0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

pwru的使用方法、经典场景及实现原理

马哥Linux运维 来源:Houmin 作者:Houmin 2022-06-28 17:27 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群


pwru 是 Cilium 推出的基于 eBPF 开发的网络数据包排查工具,它提供了更细粒度的网络数据包排查方案。本文将介绍 pwru 的使用方法和经典场景,并介绍其实现原理。

安装部署

部署要求

pwru 要求内核代码在 5.5 版本之上,--output-skb 要求内核版本在 5.9 之上,并且要求内核开启以下配置:

Option Note
CONFIG_DEBUG_INFO_BTF=y Available since >= 5.3
CONFIG_KPROBES=y
CONFIG_PERF_EVENTS=y
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y

使用方法

Usageof./pwru:
--filter-dst-ipstringfilterdestinationIPaddr
--filter-dst-portuint16filterdestinationport
--filter-funcstringfilterkernelfunctionstobeprobedbyname(exactmatch,supportsRE2regularexpression)
--filter-markuint32filterskbmark
--filter-netnsuint32filternetnsinode
--filter-protostringfilterL4protocol(tcp,udp,icmp)
--filter-src-ipstringfiltersourceIPaddr
--filter-src-portuint16filtersourceport
--output-limit-linesuintexittheprogramafterthenumberofeventshasbeenreceived/printed
--output-metaprintskbmetadata
--output-relative-timestampprintrelativetimestampperskb
--output-skbprintskb
--output-stackprintstack
--output-tupleprintL4tuple

案例演示

下图案例演示了 pwru 展现出快速定位出数据包被 iptables 规则 drop 掉的原因:

becdfe8a-f61e-11ec-ba43-dac502259ad0.gif

在不设置 iptables 规则之前:

bedbc11e-f61e-11ec-ba43-dac502259ad0.png

添加了 iptables 规则之后

iptables-tfilter-IOUTPUT1-mtcp--prototcp--dst1.1.1.1/32-jDROP

可以看到在 nf_hook_slow 函数后发生了变化:

bef9b250-f61e-11ec-ba43-dac502259ad0.png

我们可以看到数据包在 nf_hook_slow 判决为 NF_DROP,调用了 kfree_skb

intnf_hook_slow(structsk_buff*skb,structnf_hook_state*state,
conststructnf_hook_entries*e,unsignedints)
{
unsignedintverdict;
intret;

for(;s< e->num_hook_entries;s++){
verdict=nf_hook_entry_hookfn(&e->hooks[s],skb,state);
switch(verdict&NF_VERDICT_MASK){
caseNF_ACCEPT:
break;
caseNF_DROP:
kfree_skb(skb);
ret=NF_DROP_GETERR(verdict);
if(ret==0)
ret=-EPERM;
returnret;
caseNF_QUEUE:
ret=nf_queue(skb,state,s,verdict);
if(ret==1)
continue;
returnret;
default:
/*ImplicithandlingforNF_STOLEN,aswellasanyother
*nonconventionalverdicts.
*/
return0;
}
}

return1;
}

原理实现

pwru 本质上是向 kprobe 注册了一些 eBPF code,根据 pwru 传入的参数可以更新 eBPF Map,改变限制条件,从而更新输出。

比如在 FilterCfg 里面制定了过滤的 IP 地址和协议等条件

typeFilterCfgstruct{
FilterMarkuint32

//Filterl3
FilterIPv6uint8
FilterSrcIP[16]byte
FilterDstIP[16]byte

//Filterl4
FilterProtouint8
FilterSrcPortuint16
FilterDstPortuint16

//TODO:iftherearemoreoptionslater,thenyoucanconsiderusingabitmap
OutputRelativeTSuint8
OutputMetauint8
OutputTupleuint8
OutputSkbuint8
OutputStackuint8

Padbyte
}

会根据 pwru 传入的参数更新这个 eBPF Map

funcConfigBPFMap(flags*Flags,cfgMap*ebpf.Map){
cfg:=FilterCfg{
FilterMark:flags.FilterMark,
}

ifflags.FilterSrcPort>0{
cfg.FilterSrcPort=byteorder.HostToNetwork16(flags.FilterSrcPort)
}
ifflags.FilterDstPort>0{
cfg.FilterDstPort=byteorder.HostToNetwork16(flags.FilterDstPort)
}


switchstrings.ToLower(flags.FilterProto){
case"tcp":
cfg.FilterProto=syscall.IPPROTO_TCP
case"udp":
cfg.FilterProto=syscall.IPPROTO_UDP
case"icmp":
cfg.FilterProto=syscall.IPPROTO_ICMP
case"icmp6":
cfg.FilterProto=syscall.IPPROTO_ICMPV6
}

//...

iferr:=cfgMap.Update(uint32(0),cfg,0);err!=nil{
log.Fatalf("Failedtosetfiltermap:%v",err)
}
}

在 eBPF code 中,可以看到会读取配置 bpf_map_lookup_elem,然后进而执行真正的 filter:

structconfig{
u32mark;
u8ipv6;
unionaddrsaddr;
unionaddrdaddr;
u8l4_proto;
u16sport;
u16dport;
u8output_timestamp;
u8output_meta;
u8output_tuple;
u8output_skb;
u8output_stack;
u8pad;
}__attribute__((packed));

static__always_inlineint
handle_everything(structsk_buff*skb,structpt_regs*ctx){
structevent_tevent={};

u32index=0;
structconfig*cfg=bpf_map_lookup_elem(&cfg_map,&index);

if(cfg){
if(!filter(skb,cfg))
return0;

set_output(ctx,skb,&event,cfg);
}

event.pid=bpf_get_current_pid_tgid();
event.addr=PT_REGS_IP(ctx);
event.skb_addr=(u64)skb;
event.ts=bpf_ktime_get_ns();
bpf_perf_event_output(ctx,&events,BPF_F_CURRENT_CPU,&event,sizeof(event));

return0;
}

可以看到,这里通过 bpf_perf_event_output 将过滤结果以 Perf event 传递上来。

rd,err:=perf.NewReader(events,os.Getpagesize())
iferr!=nil{
log.Fatalf("Creatingperfeventreader:%s",err)
}
deferrd.Close()

//...
vareventpwru.Event
for{
record,err:=rd.Read()
iferr!=nil{
ifperf.IsClosed(err){
return
}
log.Printf("Readingfromperfeventreader:%s",err)
}

ifrecord.LostSamples!=0{
log.Printf("Perfeventringbufferfull,dropped%dsamples",record.LostSamples)
continue
}

iferr:=binary.Read(bytes.NewBuffer(record.RawSample),binary.LittleEndian,&event);err!=nil{
log.Printf("Parsingperfevent:%s",err)
continue
}

output.Print(&event)

select{
case<-ctx.Done():
  break
default:
continue
}
}

原文标题:pwru: 一款基于 eBPF 的细粒度网络数据包排查工具

文章出处:【微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内核
    +关注

    关注

    4

    文章

    1475

    浏览量

    43089
  • 网络
    +关注

    关注

    14

    文章

    8335

    浏览量

    95555
  • 数据包
    +关注

    关注

    0

    文章

    270

    浏览量

    25657

原文标题:pwru: 一款基于 eBPF 的细粒度网络数据包排查工具

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    RTL9301管理型交换机DHCP Server使用方法

    RTL9301管理型交换机DHCP Server使用方法
    的头像 发表于 02-01 10:52 1488次阅读
    RTL9301管理型交换机DHCP Server<b class='flag-5'>使用方法</b>

    ups电源的作用和使用方法详解

    UPS(不间断电源)是一种重要的电力保护设备,主要用于在电网供电异常时提供临时的后备电源,并改善电源质量。以下是其核心作用和使用方法的详细介绍:一、UPS的主要作用核心:提供不间断电力断电保护:在
    的头像 发表于 01-08 09:21 1792次阅读
    ups电源的作用和<b class='flag-5'>使用方法</b>详解

    UV三防漆的使用方法

    ,紫外线照射下秒级固化成膜,大幅提升生产效率,广泛应用于汽车电子、工业设备、医疗器械等领域。UV三防漆的使用方法UV三防漆的核心原理UV三防漆内含光敏剂,在特定波
    的头像 发表于 12-31 17:19 1678次阅读
    UV三防漆的<b class='flag-5'>使用方法</b>

    芯源IR调制器都有哪些具体使用?使用方法是怎样的?

    芯源IR调制器都有哪些具体使用?以及使用方法是怎样的?
    发表于 12-02 06:33

    图扑软件 3D 场景预加载应用实现

    应用中,资源预加载尤为重要,可有效解决首次加载时的卡顿、白屏及交互延迟等问题。 预加载实现方案 01 基础实现原理 HT for Web 中所有资源的请求都会经过 ht.Default.convertURL 方法,该
    的头像 发表于 12-01 16:04 951次阅读
    图扑软件 3D <b class='flag-5'>场景</b>预加载应用<b class='flag-5'>实现</b>

    堆栈的定义,堆栈的使用方法

    和使用; 对于8086CPU,进出堆栈的只能是2字节的数据。 2 堆栈的使用方法 常用的堆栈相关指令包括PUSH POP PUSHF和POPF,语法如下: PUSH 源操作数;将指定操作数入栈保护 POP
    发表于 11-21 06:49

    教程来啦!LuatOS中的消息通信机制详解及其应用场景

    在资源受限的嵌入式环境中,LuatOS采用消息机制实现模块间解耦与高效通信。通过预定义消息名称(如“new_msg”),开发者可轻松构建响应式程序结构。接下来我们将深入剖析其实现原理与典型使用方法
    的头像 发表于 09-26 18:59 550次阅读
    教程来啦!LuatOS中的消息通信机制详解及其应用<b class='flag-5'>场景</b>

    条码扫码设备的使用方法

    使用方法,能让其充分发挥价值,为各行业的规范化管理提供有力支撑。一、条码扫码设备的主要类型不同场景对条码扫码设备的需求存在差异,目前主流类型可分为四类,适配不同工作
    的头像 发表于 09-17 16:15 1152次阅读
    条码扫码设备的<b class='flag-5'>使用方法</b>

    HT 流畅过渡动画 × 场景切换实现方案

    在图扑 HT 项目中,尤其是复杂应用里,单一场景或图纸通常难以承载所有需求,因此在多个图纸或场景之间进行切换是一种常见的实现方式。本文将深入解析图扑 HT 项目中场景/图纸切换的核心
    的头像 发表于 09-03 14:49 981次阅读
    HT 流畅过渡动画 × <b class='flag-5'>场景</b>切换<b class='flag-5'>实现</b>方案

    锡膏的储存及使用方法详解

    锡膏是一种常用的焊接辅助材料,广泛应用于电子、电器、通讯、仪表等行业的焊接工艺中。正确的储存和使用方法对于保证锡膏的品质和焊接效果至关重要。本文将就锡膏的储存和使用方法进行详细介绍,希望能对广大焊接工作者有所帮助。
    的头像 发表于 07-18 17:36 1652次阅读
    锡膏的储存及<b class='flag-5'>使用方法</b>详解

    单模八芯光纤使用方法指南

    单模八芯光纤(通常指单模8芯束管式或带状光纤)的使用方法涵盖安装、熔接、测试、维护等关键环节,需结合其结构特性和应用场景进行规范操作。以下是具体使用指南: 一、单模八芯光纤结构解析 核心组成: 光纤
    的头像 发表于 06-26 09:51 2589次阅读

    漫画科普 | 功率放大器到底有哪些应用?带你解锁功放经典应用场景!(一)

    漫画科普 | 功率放大器到底有哪些应用?带你解锁功放经典应用场景!(一)
    的头像 发表于 06-20 20:00 1109次阅读
    漫画科普 | 功率放大器到底有哪些应用?带你解锁功放<b class='flag-5'>经典</b>应用<b class='flag-5'>场景</b>!(一)

    odf光纤配线架使用方法

    ODF光纤配线架的使用方法主要包括以下几个步骤: 一、准备工作 工具和材料准备:准备好熔接机、光纤切割刀、光纤剥皮钳、光纤清洁工具(如清洁笔、无尘布)、光纤跳线、光纤熔接套管、扎带等工具和材料
    的头像 发表于 05-22 10:11 1795次阅读

    参考cycx3_uvc_ov5640例程,想进行按键触发拍照,使用方法一,请问怎么实现的?

    参考cycx3_uvc_ov5640例程,想进行按键触发拍照,使用方法一,请问怎么实现的?现在硬件按键触发没有问题,上位机软件拍照也没有问题。 glStatusBuffer[0] = 0x02
    发表于 05-21 07:24

    LCR测试仪的使用方法与注意事项

    LCR测试仪的使用方法、操作注意事项及常见故障处理,帮助读者高效、安全地掌握这一仪器的使用技巧。   二、LCR测试仪的基本使用方法 1. 准备阶段 (1)设备检查:确保测试仪电源线、连接线完好,电源开关关闭。检查测试夹具或探针
    的头像 发表于 04-29 10:36 2w次阅读
    LCR测试仪的<b class='flag-5'>使用方法</b>与注意事项