Xpress DNS

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