【eBPF开发入门】案例(一)之监控网络流量

目标

  • 捕获特定网络接口的流量信息。
  • 了解eBPF与网络子系统的交互。
  • 实时监控系统的入站和出站网络流量。
  • 分析网络数据包的元数据,如源/目的IP、端口和协议类型。

0x01 捕获特定接口流量

准备: 确保你的系统上安装了必要的eBPF工具,包括bcc库。此外,需要对网络配置有基本了解,并具有适当的权限来捕获网络数据包。

操作步骤

  1. 创建一个名为traffic_monitor.py的新文件,并添加以下Python代码。我们将使用Python的BCC库来加载和管理eBPF程序。
from bcc import BPF

# 定义eBPF程序 - 这个程序将在内核中运行,每收到一个数据包就执行一次。
prog = """
#include <bcc/proto.h>
#include <net/sock.h>

// 定义输出数据结构
struct data_t {
    u64 timestamp;
    u32 src_ip;
    u32 dst_ip;
    u16 src_port;
    u16 dst_port;
    u16 protocol;
};
BPF_PERF_OUTPUT(events);

// 定义eBPF程序,将在内核态运行
int trace_packet(struct __sk_buff *skb) {
    u8 *cursor = 0;
    struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
    if (!(ethernet -> type == 0x0800)) {
        return 0; // 忽略非IP包
    }

    struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
    struct data_t data = {};
    data.timestamp = bpf_ktime_get_ns();
    data.src_ip = ip->src;
    data.dst_ip = ip->dst;
    data.protocol = ip->nextp;

    if (ip->nextp == 0x06) {
        struct tcp_t *tcp = cursor_advance(cursor, sizeof(*tcp));
        data.src_port = tcp->src_port;
        data.dst_port = tcp->dst_port;
    } else if (ip->nextp == 0x11) {
        struct udp_t *udp = cursor_advance(cursor, sizeof(*udp));
        data.src_port = udp->src_port;
        data.dst_port = udp->dst_port;
    }

    events.perf_submit(skb, &data, sizeof(data));
    return 0;
}
"""

# 加载eBPF程序
b = BPF(text=prog)

# 将eBPF程序附加到网络接口上
b.attach_xdp("eth0", b.load_func("trace_packet", BPF.XDP))

print("%-12s %-12s %-6s %-6s %-6s %-20s" % ("SRC IP", "DST IP", "SRC PORT", "DST PORT", "PROTOCOL", "TIMESTAMP"))

# 定义回调函数,处理从eBPF程序接收到的数据
def print_event(cpu, data, size):
    event = b["events"].event(data)
    print("%-12s %-12s %-6d %-6d %-6d %-20d" % (inet_ntoa(event.src_ip), inet_ntoa(event.dst_ip), event.src_port, event.dst_port, event.protocol, event.timestamp))

# 将回调函数与Perf Buffer输出关联
b["events"].open_perf_buffer(print_event)

# 主循环,不断地从Perf Buffer中拉取事件并触发回调函数
try:
    while True:
        b.perf_buffer_poll()
except KeyboardInterrupt:
    pass

# 最后,我们需要卸载XDP程序
b.remove_xdp("eth0", 0)

  1. 保存文件后,以适当的权限运行该脚本(例如sudo python traffic_monitor.py),确保你有权限附加eBPF程序到网络接口。
  2. 生成一些网络流量,可以通过浏览网站或使用pingcurl等工具。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值