Setiap kali perangkat Anda berselancar di internet—mulai dari membuka website, streaming video, hingga komunikasi aplikasi latar belakang...
Setiap kali perangkat Anda berselancar di internet—mulai dari membuka website, streaming video, hingga komunikasi aplikasi latar belakang—langkah pertama yang selalu dieksekusi adalah penguraian alamat nama domain melalui Domain Name System (DNS). Sayangnya, secara default, hampir seluruh traffic DNS dikirim dalam teks biasa (plaintext) dan dialihkan ke upstream resolver publik milik ISP, Google (8.8.8.8), atau Cloudflare (1.1.1.1). Hal ini membuka celah profiling data perilaku pengguna, pelacakan privasi iklan, hingga potensi manipulasi sensor DNS (DNS hijacking).
Kombinasi antara Pi-hole dan Unbound merupakan standar emas solusi jaringan mandiri. Pi-hole bertindak sebagai DNS Sinkhole di garis depan yang memblokir jutaan domain iklan dan tracker berbahaya sebelum mereka sempat diunduh oleh klien. Sementara itu, Unbound berperan sebagai Recursive DNS Resolver lokal yang berbicara langsung dengan 13 Root DNS Servers dunia (Root hints: a.root-servers.net s.d. m.root-servers.net), mengeliminasi ketergantungan pada DNS perantara mana pun.
Pada artikel ini, kita akan mengemas kedua layanan tersebut ke dalam satu stack terisolasi menggunakan Docker Compose lengkap dengan validasi integritas kriptografis DNSSEC.
1. Arsitektur Alur Resolusi Pi-hole + Unbound
Mekanisme kerja terintegrasi dari stack DNS lokal ini terbagi menjadi tahapan berikut:
- Client Query: Laptop, smartphone, atau IoT mengirim permintaan resolusi DNS (port 53 UDP/TCP) ke IP server Pi-hole lokal.
- Sinkhole Filter (Pi-hole): Pi-hole mencocokkan domain dengan adlists dan regex blacklist lokal. Jika domain terdaftar sebagai iklan, pelacak malware, atau telemetri, Pi-hole langsung membalas dengan respon
0.0.0.0(blocked). - Recursive Lookup (Unbound): Jika domain bersih dan valid, query diteruskan ke Unbound via port khusus (misal: port 5335).
- Iterative Query to Root: Unbound menghubungi Root DNS Server, lalu Top-Level Domain (TLD) Server (.id, .com, .org), hingga Authoritative Nameserver resmi domain tersebut. Unbound juga memverifikasi tanda tangan digital DNSSEC untuk memastikan jawaban DNS tidak dipalsukan di tengah jalan.
- Caching & Delivery: Hasil resolusi di-cache di memori lokal server untuk query berikutnya, sehingga waktu respon berkurang drastis menjadi sub-milidetik (< 1ms).
2. Menonaktifkan Listener Port 53 pada systemd-resolved Host
Distribusi Linux modern seperti Ubuntu Server mengaktifkan systemd-resolved secara default, yang mendengarkan (listen) pada 127.0.0.53:53. Hal ini akan menyebabkan konflik bind: address already in use saat container Docker mencoba membuka port 53.
Jalankan langkah mitigasi berikut di host Linux:
# Nonaktifkan DNSStubListener di systemd-resolved
sudo tee -a /etc/systemd/resolved.conf <<EOF
DNSStubListener=no
EOF
# Update symlink resolv.conf ke file resolv statis
sudo rm -f /etc/resolv.conf
sudo ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
# Restart service systemd-resolved
sudo systemctl restart systemd-resolved
Pastikan port 53 sudah bebas dari proses host:
sudo ss -tulpn | grep :53
# Jika output kosong, port 53 sudah siap digunakan oleh container Docker
3. Menyusun File Konfigurasi Unbound (unbound.conf)
Buat direktori proyek dan siapkan file konfigurasi optimal untuk daemon Unbound:
mkdir -p ~/dns-stack/pihole ~/dns-stack/unbound && cd ~/dns-stack
nano unbound/unbound.conf
Isikan konfigurasi berikut yang telah dioptimalkan untuk performa dan keamanan DNSSEC:
server:
verbosity: 1
interface: 0.0.0.0
port: 5335
do-ip4: yes
do-udp: yes
do-tcp: yes
# Izinkan query hanya dari subnet internal Docker
access-control: 127.0.0.0/8 allow
access-control: 172.16.0.0/12 allow
access-control: 192.168.0.0/16 allow
access-control: 10.0.0.0/8 allow
# Validasi DNSSEC
auto-trust-anchor-file: "/var/lib/unbound/root.key"
# Privasi & Keamanan
hide-identity: yes
hide-version: yes
harden-glue: yes
harden-dnssec-stripped: yes
use-caps-for-id: no
edns-buffer-size: 1232
prefetch: yes
num-threads: 1
# Buffer cache
msg-cache-size: 32m
rrset-cache-size: 64m
4. Menjalankan Stack dengan Docker Compose
Buat file docker-compose.yml di direktori root ~/dns-stack:
nano docker-compose.yml
Gunakan konfigurasi deklaratif berikut:
services:
unbound:
image: mvance/unbound:latest
container_name: unbound
restart: unless-stopped
volumes:
- ./unbound/unbound.conf:/opt/unbound/etc/unbound/unbound.conf:ro
networks:
dns-network:
ipv4_address: 172.20.0.2
pihole:
image: pihole/pihole:latest
container_name: pihole
restart: unless-stopped
depends_on:
- unbound
ports:
- "53:53/tcp"
- "53:53/udp"
- "8088:80/tcp" # Web Dashboard Pi-hole diakses via http://IP_HOST:8088/admin
environment:
TZ: 'Asia/Makassar'
WEBPASSWORD: 'PasswordAdminKuat123!'
FTLCONF_LOCAL_IPV4: '192.168.12.100'
# Hubungkan langsung ke Unbound di port 5335
PIHOLE_DNS_: '172.20.0.2#5335'
DNSSEC: 'true'
volumes:
- ./pihole/etc-pihole:/etc/pihole
- ./pihole/etc-dnsmasq.d:/etc/dnsmasq.d
networks:
dns-network:
ipv4_address: 172.20.0.3
networks:
dns-network:
name: dns-net
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/24
Jalankan stack container:
docker compose up -d
docker compose ps
5. Verifikasi Fungsionalitas & Pengujian Validasi DNSSEC
Uji resolusi DNS langsung ke server lokal Anda menggunakan perintah dig:
# Test resolusi domain umum
dig @127.0.0.1 -p 53 google.com
# Test validasi DNSSEC (Domain dengan DNSSEC valid wajib mengembalikan flag ad: authenticated data)
dig @127.0.0.1 -p 53 sigok.verteiltesysteme.net +dnssec | grep "flags:"
# Test domain dengan DNSSEC corrupt/rusak (Wajib mengembalikan SERVFAIL)
dig @127.0.0.1 -p 53 sigfail.verteiltesysteme.net +dnssec | grep "status: SERVFAIL"
Kesimpulan
Dengan menggabungkan Pi-hole dan Unbound dalam arsitektur container Docker, Anda memiliki kendali penuh atas lalu lintas data jaringan internet Anda. Iklan invasif dan pelacak pihak ketiga diblokir secara terpusat untuk semua perangkat (termasuk Smart TV dan perangkat IoT), sementara riwayat navigasi web Anda tetap menjadi rahasia privat Anda seutuhnya.
COMMENTS