Debian 13 Trixie
Install dependensi
apt update
apt install -y git llvm clang libbpf-dev libelf-dev libzstd-dev libdw-dev make gcc-multilib iproute2 bpftool
Buka limit memory (RAM)
ulimit -l unlimited
echo "* soft memlock unlimited" >> /etc/security/limits.conf
echo "* hard memlock unlimited" >> /etc/security/limits.conf
Clone repository xpress-dns:
git clone https://github.com/zebaz/xpress-dns.git
cd xpress-dns/src
Edit file xdp_dns_kern.c:
nano xdp_dns_kern.c
Cari blok struct bpf_elf_map, lalu ubah bagian berikut:
struct bpf_elf_map SEC("maps") xdns_a_records = {
.type = BPF_MAP_TYPE_HASH,
.size_key = sizeof(struct dns_query),
.size_value = sizeof(struct a_record),
.max_elem = 65536,
.pinning = 2, //PIN_GLOBAL_NS
};
Replace (sesudah #else dan sebelum #endif)menjadi lebih modern, berikut:
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 9000000); // Kapasitas 9 Juta domain
__type(key, struct dns_query);
__type(value, struct a_record);
__uint(pinning, LIBBPF_PIN_BY_NAME);
} xdns_a_records SEC(".maps");
Sesuaikan jumlah domain yang akan ditampung
Perbaikan fungsi EDNS untuk menghilangkan malformed packet
Cari dan ubah bagian berikut:
static inline void modify_dns_header_response(struct dns_hdr *dns_hdr)
{
//Set query response
dns_hdr->qr = 1;
//Set truncated to 0
//dns_hdr->tc = 0;
//Set authorative to zero
//dns_hdr->aa = 0;
//Recursion available
dns_hdr->ra = 1;
//One answer
dns_hdr->ans_count = bpf_htons(1);
}
Menjadi seperti berikut:
static inline void modify_dns_header_response(struct dns_hdr *dns_hdr)
{
dns_hdr->qr = 1;
dns_hdr->aa = 1;
dns_hdr->ad = 0;
dns_hdr->ra = 1; // <--- TAMBAHKAN INI: Menyatakan Recursion Available
dns_hdr->ans_count = bpf_htons(1);
dns_hdr->auth_count = 0;
#ifdef EDNS
// Fix Malformed Packet: Jika query punya EDNS, lapor balik 1 additional record
if (dns_hdr->add_count > 0) {
dns_hdr->add_count = bpf_htons(1);
} else {
dns_hdr->add_count = 0;
}
#else
dns_hdr->add_count = 0;
#endif
}
Ubah OPT SECTION UDP: menjadi 1232
Cari baris ar_response->size = bpf_htons(512), silakan ubah menjadi ar_response->size = bpf_htons(1232), sehingga seperti berikut:
{
//Check for OPT record (RFC6891)
if(ar->type == bpf_htons(41)){
#ifdef DEBUG
bpf_printk("OPT record found");
#endif
struct ar_hdr *ar_response = (struct ar_hdr *) &dns_buffer[0];
// Kita set ke 1232 sesuai standar DNS Flag Day 2020
ar_response->name = 0;
ar_response->type = bpf_htons(41);
ar_response->size = bpf_htons(1232); // <-- UBAH DI SINI
ar_response->ex_rcode = 0;
ar_response->rcode_len = 0;
*buf_size += sizeof(struct ar_hdr);
}
Kopmilasi (Compile) manual dengan perintah berikut:
Build Kernel Side
clang -target bpf -I /usr/include/bpf -I /usr/include/iproute2 -Wall -D EDNS -O2 -g -c xdp_dns_kern.c -o xdp_dns_kern.o
Build User Side (xdns tool):
clang -Wall -I/usr/include/bpf -I /usr/include/iproute2 -g -o xdns xdp_dns.c -lbpf -lelf -lz
Buat direktori globals jika belum ada:
mkdir -p /sys/fs/bpf/xdp/globals/
Pasang ke interface (sesuaikan dengan nama interface yang akan menerima traffic DNS):
ip link set dev ens18 xdp obj xdp_dns_kern.o section prog
Cek status
ip link show ens18
Operational command
Menambahkan domain:
./xdns add a <domain> <ip sinkhole> <TTL>
Contoh:
./xdns add a example.com 127.0.0.1 60
Menghapus domain:
./xdns remove a <domain> <ip sinkhole>
Contoh:
./xdns remove a example.com 127.0.0.1
Melihat domain yang ada di list:
./xdns list