eBPF指定网口丢弃icmp报文

ubuntu 23.10

安装eBPF依赖

# 安装编译工具
apt install -y llvm clang

# 确认内核具有BTF支持,路径存在,内核没有BTF支持,使用vmlinux.h无法通过编译
ls /sys/kernel/btf

# 生成vmlinux.h
# apt install -y linux-tools-generic
apt install -y linux-tools-6.5.0-26-generic
bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h

eBPF丢弃icmp报文

拷贝github.com/cilium/ebpf/examples/headers目录,里面放入vmlinux.h。

代码结构

icmp/drop-icmp.c

#include "../headers/vmlinux.h"
#include "../headers/bpf_endian.h"
#include "../headers/bpf_helpers.h"

#define TC_ACT_SHOT 2
#define TC_ACT_OK 0

#define ETH_P_IP 0x0800

char __license[] SEC("license") = "Dual MIT/GPL";

SEC("tc")
int tc_deny_icmp(struct __sk_buff *skb) {
    void *data_end = (void *)(long)skb->data_end;
    void *data = (void *)(long)skb->data;

    struct ethhdr *eth_hdr = data;
    if ((void *)eth_hdr + sizeof(*eth_hdr) > data_end || eth_hdr->h_proto != bpf_htons(ETH_P_IP)) {
        return TC_ACT_OK;
    }

    struct iphdr *ip_hdr = (void *)eth_hdr + sizeof(*eth_hdr);
    if ((void *)ip_hdr + sizeof(*ip_hdr) > data_end) {
        return TC_ACT_OK;
    }

    if (ip_hdr->protocol == IPPROTO_ICMP) {
        return TC_ACT_SHOT;
    }

    return TC_ACT_OK;
}

编译eBPF程序并加载

# 加-c允许没有main函数,加-target bpf生成ELF,编译优化级别-O2,加-g生成BTF
clang -c icmp/drop-icmp.c -o icmp/drop-icmp.o -target bpf -O2 -g

tc qdisc add dev ens33 clsact
tc filter add dev ens33 egress bpf da obj icmp/drop-icmp.o sec tc
tc filter add dev ens33 ingress bpf da obj icmp/drop-icmp.o sec tc

加载eBPF后无法ping通。

posted on 2024-04-14 12:35  王景迁  阅读(49)  评论(0编辑  收藏  举报

导航