当前位置: 首页 > news >正文

ebpf 采集ebpf 采集tag+tcp五元组 - liyan

基于ebpf的丰富的特性能够获取服务很多的信息,不同特性的组合更是可以达到极强的数据整合能力。比如通过uprobe便捷的获取业务信息后,结合kprobe来获取系统调用里的内容,可以获取一般侵入式可观测代码无法获取的内容。笔者最近遇到的一个实际问题是:获取服务A的接口/a响应后,向下游B发起的请求时,所使用的传输层五元组,同时带上结合一些/a触发时的一些内容,比如caller_fun或者traceId
这里值得说明的是,用户态请求的是一个域名。域名的解析是在golanghttp里完成的。但是请注意,golang发起tcp请求时,local port设置的是0,然后由内核态的tpc处理来选择一个空闲的port作为socket里的lport。这部分的信息通过代码的埋点显然是无法获取的(详情可参考TCP连接中客户端的端口号是如何确定的?)。
下面介绍下实现效果及思路。

关于bpftrace使用的介绍,可以参见:bpftrace 无侵入遍历golang链表,关于ebpf来进行数据采集的实践,可以参见ebpf采集mysql请求信息及ebpf对应用安全的思考。

实现效果

服务端启动、触发的效果:

# 启动目标服务
./caller_tuple
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.- using env:	export GIN_MODE=release- using code:	gin.SetMode(gin.ReleaseMode)[GIN-debug] GET    /echo                     --> main.Echo (3 handlers)
# 这里触发一次接口调用
[GIN] 2023/02/24 - 22:05:29 | 200 |   85.618975ms |       127.0.0.1 | GET      "/echo"

bpftrace 采集端的效果:

# 启动采集
bpftrace ./caller.bt
Attaching 3 probes...
start to gather caller info.
get caller path: /echo
# 将 caller_path 和 传输层五元组结合起来(本机的IP实际上是输出的,但是为了信息安全,就使用 0.0.0.0 来代替了)
caller info: /echo
3326691  caller_tuple     0.0.0.0                            38610  110.242.68.66                           80

代码实现

这里分别上一下目标服务caller_func以及采集脚本caller.bt的代码,来说明下实现思路。

// ./caller_tuple/main.go
package mainimport ("net/http""github.com/gin-gonic/gin"
)type Resp struct {Errno int64  `json:"errno"`Msg   string `json:"msg"`
}func Echo(c *gin.Context) {req, _ := http.NewRequest(http.MethodGet, "http://baidu.com", nil)client := http.Client{}resp, err := client.Do(req)if err != nil {c.JSON(http.StatusOK, &Resp{Errno: 1, Msg: "request error"})return}defer resp.Body.Close()c.JSON(http.StatusOK, &Resp{Errno: 0, Msg: "ok"})return
}func main() {r := gin.Default()srv := &http.Server{Addr: "0.0.0.0:3344",}r.GET("/echo", Echo)srv.Handler = rsrv.ListenAndServe()
}// caller_tuple/caller.bt
#!/usr/bin/env bpftrace#define AF_INET 2struct sock_common {union {struct {__be32 skc_daddr;__be32 skc_rcv_saddr;};};union {unsigned int skc_hash;__u16 skc_u16hashes[2];};union {struct {__be16 skc_dport;__u16 skc_num;};};short unsigned int skc_family;
};struct sock {struct sock_common __sk_common;
};BEGIN{printf("start to gather caller info.
");@caller[pid] = "none";
}// 这里通过 uprobe 来便捷的获取会话信息。同时将信息写入bpf_map
uprobe:./caller_tuple:"net/http.serverHandler.ServeHTTP"{$req_ptr = sarg3;$method_ptr = *(uint64*)($req_ptr);$method_len = *(uint64*)($req_ptr+8);/* read request.url.Path */$url_ptr = *(uint64*)($req_ptr + 16);$path_ptr = *(uint64*)($url_ptr+56);$path_len = *(uint64*)($url_ptr+64);printf("get caller path: %s
", str($path_ptr, $path_len));// 这里使用 pid 来作为 key 只是为了实现方便。实际可以采取其他更有区分性的内容。@caller_ptr[pid]=$path_ptr;@caller_len[pid]=$path_len;
}// 通过 kprobe 来获取用户态无法获取的内容。同时通过 bpf_map 来控制生效及内容的交互。
kprobe:tcp_connect
{if (@caller_ptr[pid] == 0){return;}$ptr = @caller_ptr[pid];$len = @caller_len[pid];printf("caller info: %s
", str($ptr, $len));@caller_ptr[pid] = 0;@caller_len[pid] = 0;$sk = ((struct sock *) arg0);$inet_family = $sk->__sk_common.skc_family;if ($inet_family == AF_INET) {$daddr = ntop($sk->__sk_common.skc_daddr);$saddr = ntop($sk->__sk_common.skc_rcv_saddr);$lport = $sk->__sk_common.skc_num;$dport = $sk->__sk_common.skc_dport;$dport = (((($dport) >> 8) & 0xff) | ((($dport) & 0xff) << 8));printf("%-8d %-16s ", pid, comm);printf("%-39s %-6d %-39s %-6d
", $saddr, $lport, $daddr, $dport);}
}

这样就达到了笔者的目标。这只是ebpf应用的一个简单的场景,更多的metric采集内容仍在进行。
以上,周末愉快!

http://www.jsqmd.com/news/417094/

相关文章:

  • 正则替换拷贝
  • emacs-若干语言 lsp 配置备注 - liyan
  • Linux sed 命令
  • 【面板数据】更新-省级产业结构高级化及合理化数据-含代码(2000-2024年)
  • AgentRun 实践指南:Agent 的宝藏工具——All-In-One Sandbox
  • Emacs 字符操作快捷键 - liyan
  • 全国艺术留学推荐,看看满足条件后哪个学校和中介通过率更高 - mypinpai
  • win10 安装ffmpeg
  • 浙江杭泰产品质量与种类情况,在多地服务的费用贵吗 - 工业推荐榜
  • Gemini 3.1 Flash Image (Nano Banana 2) API 评测:从参数到落地,我替你踩了坑 - 147API
  • 2026年化工生产用氨水采购指南:脱硫/电子级/食品级氨水专业供应商推荐 - 品牌推荐官
  • 岱宇国际在上海的口碑排名,看看其技术实力、品牌知名度和用户体验 - myqiye
  • 分析2026年宁德性价比高的全屋定制,生产厂合作案例多的排名 - 工业品牌热点
  • Rust枚举OptionT
  • 2026年GEO营销风向标:国内领先的GEO整合营销服务商排名及TOP 3选型指南 - 资讯焦点
  • 2026年最新喷胶厂商实力排行榜:基于环保性能与市场口碑的五大公司权威推荐榜单 - 十大品牌榜
  • 2026年全国聚丙烯纤维厂家权威榜单 靠谱优质实力强 抗裂增强适配多工程场景 - 深度智识库
  • 暑期亲子草原游,呼和浩特哪家旅行社有牧民体验?手把手教你选对呼和浩特亲子草原游,3步识别真动手、真牧户、真安全 - 资讯焦点
  • project管理工具哪个好?2026年project管理工具推荐与排名,解决定制化与安全痛点 - 十大品牌推荐
  • 2026实验室排风厂家五大推荐:迅领实验室领衔,打造安全高效实验环境 - 深度智识库
  • js--28
  • project管理软件哪个好?2026年project管理软件推荐与排名,解决复杂项目与效能度量核心痛点 - 十大品牌推荐
  • 计算机毕业设计springboot高校学生社团管理系统 基于SpringBoot框架的大学生社团活动管理平台设计与实现 高校学生组织数字化运营系统——以社团管理为核心的信息化解决方案
  • 2026清洁度分析仪源头厂家最新排名,西恩士这些企业值得关注 - 工业干货社
  • 聚焦2026国内诚信的间歇式智适应动力模块生产商,压力有关型动力模块/分布式动力模块,间歇式智适应动力模块供应商推荐 - 品牌推荐师
  • 2026年2月广信区门窗店推荐,门窗隔热条材质优劣解析 - 品牌鉴赏师
  • FastAPI + Ollama 实战:搭一个能查天气的AI助手
  • 跨组织协同如何选型?2026年project管理工具推荐与评价,聚焦集成与扩展痛点 - 十大品牌推荐
  • 2026年project管理软件哪个好?全面评测与推荐,针对成本效益与合规痛点 - 十大品牌推荐
  • 新佳源环保可靠吗,在泰州为企业提供环保服务有哪些优势 - 工业推荐榜