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运维】欢迎添加关注!文章转载请注明出处。

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

    关注

    3

    文章

    1309

    浏览量

    39844
  • 网络
    +关注

    关注

    14

    文章

    7251

    浏览量

    87436
  • 数据包
    +关注

    关注

    0

    文章

    229

    浏览量

    24092

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

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

收藏 人收藏

    评论

    相关推荐

    数字信号处理DSP库文件的使用方法和功能实现

    本文首先介绍数字信号处理(DSP),是指将连续的模拟信号转换为不连续、离散的数字信号并进行处理以提取所需的信号(信息)的过程。然后通过一个简单的Lab来说明DSP库文件的使用方法和功能实现
    的头像 发表于 04-03 14:09 1190次阅读
    数字信号处理DSP库文件的<b class='flag-5'>使用方法</b>和功能<b class='flag-5'>实现</b>

    555集成芯片的使用方法

    555集成芯片的使用方法主要依赖于其特定的引脚功能和电路设计。
    的头像 发表于 03-25 14:39 247次阅读

    C语言循环结构的使用方法

    详细介绍了C语言while循环结构、do-while循环结构、for循环结构、循环退出语句的语法和使用方法
    发表于 11-02 11:26 448次阅读
    C语言循环结构的<b class='flag-5'>使用方法</b>

    AT32 MCU Printf的功能使用方法

    AT32 MCU Printf的功能使用方法
    的头像 发表于 10-27 09:27 441次阅读
    AT32 MCU Printf的功能<b class='flag-5'>使用方法</b>

    AT32F系列主频1MHz的使用方法

    演示AT32F系列 主频1MHz的使用方法。MCU系统时钟只可由HICK、HEXT或PLL提供,其时钟最小只能达到4MHz。为了降低功耗,有时应用期望系统时钟只跑1MHz或者更低,此时就可通过AHB
    发表于 10-27 07:27

    AT32F系列ACC的使用方法

    AT32F系列ACC使用演示AT32F系列ACC的使用方法
    发表于 10-27 06:44

    AT32F系列MCO输出的使用方法

    AT32F系列MCO输出演示AT32F系列MCO输出的使用方法
    发表于 10-27 06:36

    抗弯连接器的使用方法

    抗弯连接器的使用方法 抗弯连接器是一种用于尺寸较小的梁柱连接的专业连接器。它主要通过连接板或者连接钢筋来使得梁柱结构在承受力的同时更加稳定。抗弯连接器是规模小、造价低、强度高,并且可以满足大规模工业
    的头像 发表于 08-24 10:41 1238次阅读

    去耦电容的有效使用方法有哪些

    去耦电容的有效使用方法之一是用多个(而非1个)电容进行去耦。使用多个电容时,使用相同容值的电容时和交织使用不同容值的电容时,效果是不同的。
    发表于 08-02 12:34 288次阅读
    去耦电容的有效<b class='flag-5'>使用方法</b>有哪些

    PTC温限传感器使用方法

    PTC温限传感器使用方法
    的头像 发表于 07-28 15:31 660次阅读
    PTC温限传感器<b class='flag-5'>使用方法</b>

    功率电感器的使用方法

    功率电感器的使用方法
    的头像 发表于 07-28 15:21 584次阅读
    功率电感器的<b class='flag-5'>使用方法</b>

    炭黑含量测试仪:基本原理、使用方法及应用场景

    炭黑含量测试仪是一种用于测量材料中炭黑含量的仪器。本文将介绍炭黑含量测试仪的基本原理、使用方法及其优缺点,并结合实际应用场景阐述其重要性和应用价值。上海和晟HS-TH-3500炭黑含量测试仪基本原理
    的头像 发表于 07-24 11:14 535次阅读
    炭黑含量测试仪:基本原理、<b class='flag-5'>使用方法</b>及应用<b class='flag-5'>场景</b>

    Router产品使用方法

    PCAN-Router系列产品使用方法前情提要上期介绍了虹科PCANRouter系列的功能和一些应用场景,想必大家对虹科PCANRouter系列的产品也有了一些了解。Router正如其名,核心
    的头像 发表于 06-21 10:09 399次阅读
    Router产品<b class='flag-5'>使用方法</b>

    TTL电路分析、工作原理、使用方法

    今天给大家分享的是: TTL电路的分析 、TTL电路 工作原理 、TTL电路 使用方法
    发表于 05-18 09:06 3921次阅读
    TTL电路分析、工作原理、<b class='flag-5'>使用方法</b>

    安全光栅,光幕的使用方法

    安全光栅的使用方法
    的头像 发表于 05-16 09:51 669次阅读
    安全光栅,光幕的<b class='flag-5'>使用方法</b>