suricata的af_xdp模式研究(一)

476 阅读1分钟

suricata在af_xdp模式下挂载的是哪个ebpf程序

  • 编译suricata添加af_xdp的支持
    • 编译
  • 运行af-xdp模式
    • 启动
      ./src/suricata -c suricata.yaml --af-xdp
    • 问题
      运行--af-xdp模式后,无法再通过ssh登录服务器需要分析原因
    • 排查
      • 利用xdp-loader查看 1724638491439.png
      • 利用bpfprog程序查看挂载的xdp程序 1724638171228.png 如图可以看到suricata程序默认挂载了xdp_dispatcher程序到eth0网卡
      • 综上,suricata默认加载libxdp库中的xsk_def_prog程序,这个程序默认会redirect所有流量

修改suricata源码支持加载自定义xdp程序

编写一个xdp程序实现只redirect udp流量

/* SPDX-License-Identifier: GPL-2.0 */

#include <linux/bpf.h>
#include <linux/in.h>
#include <bpf/bpf_helpers.h>
#include <xdp/xdp_helpers.h>

/* Defines xdp_stats_map */
#include "xdp/parsing_helpers.h"

struct {
        __uint(type, BPF_MAP_TYPE_XSKMAP);
        __type(key, __u32);
        __type(value, __u32);
        __uint(max_entries, 64);
} xsk SEC(".maps");

SEC("xdp")
int xdp_udp_filter_prog(struct xdp_md *ctx)
{

    void *data_end = (void *)(long)ctx->data_end;
    void *data = (void *)(long)ctx->data;
    struct hdr_cursor nh;
    struct ethhdr *eth;
    int eth_type;

    nh.pos = data;
    eth_type = parse_ethhdr(&nh, data_end, &eth);

    if (eth_type != bpf_htons(ETH_P_IP))
            return XDP_PASS;

    struct iphdr *iphdr;
    int ip_type;
    ip_type = parse_iphdr(&nh, data_end, &iphdr);
    if (ip_type != IPPROTO_UDP)
            return XDP_PASS;

    return bpf_redirect_map(&xsk, 0, 0);
}

char _license[] SEC("license") = "GPL";

编译后生成一个.o文件

启动suricata加载生成后的.o文件

  • 可以看到suricata成功的加载了我们刚刚编译的xdp_udp_filter_prog程序 1724659313672.png
  • 得分析为啥把8081端口干掉了