Kỹ thuật hook xdp phòng chống DDoS
Tác giả: admin tháng 3 17, 2023 ・0 comments
Share anh em tham khảo, một trong những phương pháp phòng chống DDoS hiệu quả được nhiều anh em Tây Tàu áp dụng và Firewall.wiki là một trong số đó
Code này cần phải chỉnh sửa nếu áp dụng production.
Ưu điểm: phản ứng nhanh vì xử lí traffic đầu vào giữa card mạng và Kernel giảm tải đáng kể cho webservice.
Mặc định nếu bị DDoS server sẽ full 100%, áp dụng phương pháp này thì tài nguyên giảm 80%
#include <linux/bpf.h>
#include <linux/bkt_cls.h>
#include <netinet/in.h>
#include <linux/ip.h>
#include <linux/if_ether.h>
#include <bpf/bpf_helpers.h>
#include <stdlib.h>
#define THRESHOLD 500 // Ngưỡng traffic
#define TABLE_SIZE 1024 // Kích thước bảng hash
#define BPF_MAP_TYPE_HASH 1
struct bpf_map_def SEC("maps") flood_table = {
.type = BPF_MAP_TYPE_HASH,
.key_size = sizeof(struct in_addr),
.value_size = sizeof(long),
.max_entries = TABLE_SIZE,
};
struct bpf_map_def SEC("maps") blocked_ips = {
.type = BPF_MAP_TYPE_HASH,
.key_size = sizeof(struct in_addr),
.value_size = sizeof(int),
.max_entries = TABLE_SIZE,
};
static void cleanup(void *arg)
{
bpf_map_delete_elem(&flood_table, NULL);
}
SEC("xdp")
int flood_drop(struct xdp_md *ctx)
{
void *data = (void *)(long)ctx->data;
void *data_end = (void *)(long)ctx->data_end;
// Kiểm tra xem gói tin có đầy đủ phần header không
if (data + sizeof(struct ethhdr) + sizeof(struct iphdr) > data_end) {
return XDP_ABORTED;
}
struct ethhdr *eth = data;
if (eth->h_proto != htons(ETH_P_IP)) {
return XDP_PASS;
}
struct iphdr *ip = data + sizeof(struct ethhdr);
if (ip->protocol != IPPROTO_TCP && ip->protocol != IPPROTO_UDP) {
return XDP_PASS;
}
// Lấy địa chỉ IP nguồn
struct in_addr src_ip;
src_ip.s_addr = ip->saddr;
// Kiểm tra xem IP này đã bị block chưa
int *blocked = bpf_map_lookup_elem(&blocked_ips, &src_ip);
if (blocked && *blocked) {
return XDP_DROP;
}
// Tăng giá trị trong bảng hash tương ứng với địa chỉ IP nguồn
long *count = bpf_map_lookup_elem(&flood_table, &src_ip);
if (count) {
(*count)++;
} else {
long init_count = 1;
bpf_map_update_elem(&flood_table, &src_ip, &init_count, BPF_ANY);
}
// Nếu traffic từ địa chỉ IP nguồn vượt quá ngưỡng
if (count && *count > THRESHOLD) {
// Block IP này
int blocked_flag = 1;
bpf_map_update_elem(&blocked_ips, &src_ip, &blocked_flag, BPF_ANY);
return XDP_DROP;
}
return XDP_PASS;
}
Đăng nhận xét