Networking

DNS Security: Panduan Lengkap Keamanan DNS

Tutorial komprehensif tentang keamanan DNS β€” dari DNSSEC, DNS over HTTPS (DoH), DNS over TLS (DoT), DNS filtering, serangan DNS, hingga implementasi dan best practices untuk administrator jaringan

1. Pengenalan DNS & Keamanan

Domain Name System (DNS) adalah sistem yang menerjemahkan nama domain (contoh: beebanelabs.com) menjadi alamat IP (contoh: 192.168.1.1) yang dipahami oleh komputer. DNS sering disebut sebagai "phonebook of the internet" karena fungsinya yang fundamental dalam navigasi internet.

Namun, DNS pada dasarnya dirancang tanpa fitur keamanan built-in. Protokol DNS asli tidak memiliki autentikasi, enkripsi, atau integritas data. Ini menjadikan DNS sebagai target favorit untuk berbagai serangan seperti DNS poisoning, DNS spoofing, dan DNS hijacking. Keamanan DNS menjadi sangat kritis karena hampir semua aktivitas internet dimulai dengan resolusi DNS.

Anatomi Resolusi DNS

Komponen Fungsi Contoh
DNS ResolverServer yang melakukan resolusi untuk client8.8.8.8 (Google), 1.1.1.1 (Cloudflare)
Root ServerServer root yang menunjuk ke TLD servera.root-servers.net hingga m.root-servers.net
TLD ServerServer untuk Top Level Domain (.com, .id)a.gtld-servers.net (.com TLD)
Authoritative ServerServer yang memiliki data DNS untuk domainns1.cloudflare.com
Recursive ResolverResolver yang mencari jawaban dari root hingga authoritativeISP resolver, public resolver
Diagram: DNS Resolution Flow
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                DNS RESOLUTION FLOW                              β”‚
β”‚                                                                β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”     1. Query              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  Client │─────────────────────────▢ β”‚ Recursive        β”‚   β”‚
β”‚  β”‚ Browser β”‚     beebanelabs.com       β”‚ Resolver         β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     ◀──────────────────  β”‚ (ISP/Google)     β”‚   β”‚
β”‚                   8. Response           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                          β”‚              β–²      β”‚
β”‚                                          β”‚ 2. Query     β”‚ 7.   β”‚
β”‚                                          β–Ό              β”‚ Replyβ”‚
β”‚                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                   β”‚      β”‚
β”‚                   β”‚ Root Server      β”‚β”€β”€β”€β”€β”€β”€β”€β”˜           β”‚      β”‚
β”‚                   β”‚ (.com ?)         β”‚                   β”‚      β”‚
β”‚                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                   β”‚      β”‚
β”‚                                          β”‚ 3. Referral  β”‚ 6.   β”‚
β”‚                                          β–Ό              β”‚ Replyβ”‚
β”‚                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                   β”‚      β”‚
β”‚                   β”‚ TLD Server       β”‚β”€β”€β”€β”€β”€β”€β”€β”˜           β”‚      β”‚
β”‚                   β”‚ (.com)           β”‚                   β”‚      β”‚
β”‚                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                   β”‚      β”‚
β”‚                                          β”‚ 4. Referral  β”‚ 5.   β”‚
β”‚                                          β–Ό              β”‚ Replyβ”‚
β”‚                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                   β”‚      β”‚
β”‚                   β”‚ Authoritative    β”‚β”€β”€β”€β”€β”€β”€β”€β”˜           β”‚      β”‚
β”‚                   β”‚ NS beebanelabs   β”‚                   β”‚      β”‚
β”‚                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                   β”‚      β”‚
β”‚                                                                β”‚
β”‚  Attack Points: Poisoning bisa terjadi di SETIAP tahap!       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
⚠️ Peringatan

Tutorial ini ditujukan untuk edukasi keamanan. Gunakan pengetahuan ini untuk mempertahankan jaringan, bukan untuk menyerang. Manipulasi DNS tanpa izin adalah kejahatan siber.

2. Teknik Serangan DNS

2.1 DNS Cache Poisoning

DNS Cache Poisoning adalah teknik memasukkan data DNS palsu ke dalam cache resolver. Ketika resolver menyimpan record palsu, semua user yang menggunakan resolver tersebut akan diarahkan ke server yang salah.

Concept β€” DNS Cache Poisoning Attack
# ===== DNS CACHE POISONING =====

# PRINSIP:
# 1. Resolver menerima query untuk domain target
# 2. Resolver mengirim query ke authoritative server
# 3. Attacker MENGIRIM response palsu SEBELUM
#    response asli datang (race condition)
# 4. Jika response palsu diterima duluan, resolver
#    menyimpan IP palsu di cache

# FAKTOR KUNCI:
# - Transaction ID (16 bit) harus cocok β†’ bisa di-brute force
# - Source port harus cocok β†’ setelah Kaminsky fix, port random
# - TTL cache β†’ semakin lama semakin berbahaya

# ===== KAMINSKY ATTACK (2008) =====
# Teknik yang dikembangkan oleh Dan Kaminsky:
#
# 1. Attacker query subdomain random:
#    random123.target.com β†’ Resolver belum punya di cache
#
# 2. Resolver query authoritative server untuk target.com
#
# 3. Attacker flood resolver dengan response palsu:
#    random123.target.com β†’ 1.2.3.4 (IP attacker)
#    + NS record palsu: target.com β†’ ns.attacker.com
#
# 4. Jika salah satu response palsu diterima duluan,
#    SELURUH target.com diarahkan ke attacker
#
# 5. Karena NS record juga dipalsukan,
#    SEMUA subdomain target.com juga ikut dipalsukan

# ===== DETEKSI DNS CACHE POISONING =====

# Cek apakah DNS resolver mengembalikan IP yang benar
dig @8.8.8.8 beebanelabs.com A
# Bandingkan dengan authoritative server
dig @ns1.cloudflare.com beebanelabs.com A

# Monitor perubahan IP yang mencurigakan
# Script monitoring:
#!/bin/bash
DOMAIN="beebanelabs.com"
EXPECTED_IP="104.21.xx.xx"

while true; do
    RESOLVED_IP=$(dig +short $DOMAIN @8.8.8.8)
    if [ "$RESOLVED_IP" != "$EXPECTED_IP" ]; then
        echo "[ALERT] DNS mismatch! Expected: $EXPECTED_IP, Got: $RESOLVED_IP"
        # Kirim notifikasi
    fi
    sleep 60
done

2.2 DNS Spoofing & Man-in-the-Middle

Tools β€” DNS Spoofing Techniques
# ===== DNS SPOOFING TOOLS =====

# 1. BETTERCAP β€” Network Attack Framework
# DNS spoofing di jaringan lokal
sudo bettercap -iface eth0

# Di Bettercap console:
# > set dns.spoof.domains target.com
# > set dns.spoof.address 192.168.1.100  # IP attacker
# > dns.spoof on
# > arp.spoof on

# Semua request ke target.com di jaringan lokal
# akan diarahkan ke 192.168.1.100

# 2. ETTERCAP β€” Man-in-the-Middle
# Edit /etc/ettercap/etter.dns:
# target.com    A   192.168.1.100
# *.target.com  A   192.168.1.100

sudo ettercap -T -q -i eth0 -M arp:remote /192.168.1.1// /192.168.1.100//

# 3. DNSCHEF β€” DNS Proxy untuk Testing
# Setup DNS proxy yang mengembalikan IP palsu
sudo dnschef --fakeip 192.168.1.100 --fakedomains target.com --interface 0.0.0.0

# Konfigurasi lebih detail:
sudo dnschef --nameservers 8.8.8.8 \
    --fakedomains target.com,*.target.com \
    --fakeip 192.168.1.100 \
    --interface 192.168.1.50

# 4. MITMf β€” Man-in-the-Middle Framework
sudo python mitmf.py --arp --spoof --dns --gateway 192.168.1.1 --target 192.168.1.50

# ===== DETEKSI DNS SPOOFING =====

# 1. Bandingkan respon dari beberapa resolver
dig @8.8.8.8 target.com A
dig @1.1.1.1 target.com A
dig @9.9.9.9 target.com A
# Jika berbeda = kemungkinan poisoning

# 2. Gunakan DNSSEC validation
dig +dnssec target.com A

# 3. Monitor ARP table untuk spoofing
arp -a | grep gateway_ip
# Jika MAC address berubah = ARP spoofing terjadi

2.3 DNS Hijacking

Concept β€” DNS Hijacking Methods
# ===== DNS HIJACKING METHODS =====

# 1. REGISTRAR HIJACKING
# Attacker mendapatkan akses ke akun registrar domain
# dan mengubah nameserver record
#
# Cara:
# - Phishing email admin domain registrar
# - Credential stuffing akun registrar
# - Social engineering registrar support
#
# Contoh kasus: MyEtherWallet (2018) β€” DNS hijack rugi $17M

# 2. ROUTER DNS HIJACKING
# Attacker mengubah konfigurasi DNS di router korban
# dengan mengakses admin panel router
#
# Cara:
# - Default credentials (admin:admin)
# - Exploit kerentanan router
# - CSRF attack pada admin panel
#
# Ubah DNS server di router:
# Primary DNS: attacker.dns.server
# Secondary DNS: 8.8.8.8 (agar internet tetap jalan)

# 3. LOCAL DNS HIJACKING
# Mengubah konfigurasi DNS di komputer korban
#
# Windows:
# netsh interface ip set dns "Ethernet" static attacker.dns.server
#
# Linux:
# echo "nameserver attacker.dns.server" > /etc/resolv.conf
#
# macOS:
# networksetup -setdnsservers Wi-Fi attacker.dns.server

# 4. MALWARE DNS HIJACKING
# Malware yang mengubah DNS settings secara diam-diam
# Contoh: DNSChanger malware
# - Mengubah DNS server di OS
# - Menginstall rogue DHCP server
# - Mengubah DNS di router via UPnP

# ===== PENCEGAHAN =====
# 1. Aktifkan DNSSEC pada domain
# 2. Gunakan DNS over HTTPS (DoH) atau DNS over TLS (DoT)
# 3. Lock registrar account dengan 2FA
# 4. Monitor perubahan DNS record secara berkala
# 5. Gunakan registry lock service
# 6. Amankan router dari akses tidak sah

2.4 DNS Amplification (DDoS)

Concept β€” DNS Amplification DDoS
# ===== DNS AMPLIFICATION ATTACK =====

# DNS Amplification adalah serangan DDoS yang memanfaatkan
# perbedaan ukuran antara DNS query dan DNS response

# PRINSIP:
# 1. Attacker mengirim DNS query ke open resolver
#    dengan SOURCE IP korban (IP spoofing)
# 2. Resolver mengirim response ke korban
# 3. Response JAUH lebih besar dari query (amplifikasi)
# 4. Banyak resolver = korban kebanjiran traffic

# AMPLIFICATION FACTOR:
# Query size: ~60 bytes
# Response size: ~3000 bytes (ANY record untuk domain besar)
# Amplification: ~50x!

# CONTOH:
# 1 Gbps traffic attacker β†’ 50 Gbps traffic ke korban

# DNS RECORD YANG MEMILIKI AMPLIFICATION TERTINGGI:
# Record ANY (ANY query semua record type)
# Record TXT (bisa berisi data besar)
# Record MX (mail server records)

# ===== PENCEGAHAN =====
# 1. Rate limiting pada DNS resolver
# 2. Response Rate Limiting (RRL)
# 3. Jangan jalankan open resolver
# 4. BCP38/BCP84 (anti-spoofing)
# 5. Implementasi DNS Response Rate Limiting

# ===== KONFIGURASI BIND9 RRL =====
# Tambahkan di /etc/bind/named.conf.options:
# rate-limit {
#     responses-per-second 10;
#     window 5;
# };

# ===== KONFIGURASI UNBOUND RRL =====
# Tambahkan di /etc/unbound/unbound.conf:
# ip-rate-limit: 100
# ratelimit: 1000

3. DNSSEC: DNS Security Extensions

DNSSEC (DNS Security Extensions) adalah sekumpulan ekstensi untuk DNS yang menambahkan autentikasi dan integritas data pada respons DNS. DNSSEC menggunakan kriptografi asimetris (digital signatures) untuk memastikan bahwa data DNS yang diterima benar-benar berasal dari sumber yang sah dan tidak dimanipulasi selama transit.

3.1 Konsep Dasar DNSSEC

Diagram: DNSSEC Chain of Trust
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  DNSSEC CHAIN OF TRUST                          β”‚
β”‚                                                                β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚  β”‚  ROOT ZONE KSK (Key Signing Key)                  β”‚         β”‚
β”‚  β”‚  β€’ Trusted by all DNSSEC validators               β”‚         β”‚
β”‚  β”‚  β€’ Manually verified (root trust anchor)          β”‚         β”‚
β”‚  β”‚  β€’ Signs ROOT ZSK                                 β”‚         β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚                     β”‚ Signs                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚  β”‚  ROOT ZSK (Zone Signing Key)                      β”‚         β”‚
β”‚  β”‚  β€’ Signs all records in root zone                 β”‚         β”‚
β”‚  β”‚  β€’ Creates DS record for TLD (.com)               β”‚         β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚                     β”‚ DS record                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚  β”‚  .COM ZSK                                      β”‚         β”‚
β”‚  β”‚  β€’ Signs all records in .com zone                β”‚         β”‚
β”‚  β”‚  β€’ Creates DS record for beebanelabs.com         β”‚         β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚                     β”‚ DS record                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚  β”‚  beebanelabs.com ZSK                             β”‚         β”‚
β”‚  β”‚  β€’ Signs all records in beebanelabs.com zone     β”‚         β”‚
β”‚  β”‚  β€’ RRSIG for each A, AAAA, MX, etc.             β”‚         β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚                                                                β”‚
β”‚  Verifikasi: Resolver memverifikasi RRSIG dari                β”‚
β”‚  authoritative β†’ DS dari parent β†’ KSK dari root               β”‚
β”‚  = CHAIN OF TRUST lengkap!                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Bash β€” DNSSEC Commands & Verification
# ===== DNSSEC COMMANDS =====

# 1. Cek apakah domain mendukung DNSSEC
dig +dnssec beebanelabs.com A

# Perhatikan output ada RRSIG record:
# beebanelabs.com.  300  IN  A  104.21.xx.xx
# beebanelabs.com.  300  IN  RRSIG  A 13 2 300 (
#                 20260701000000 20260601000000
#                 12345 beebanelabs.com.
#                 Base64Signature... )

# 2. Cek DS record di parent zone
dig +short beebanelabs.com DS

# 3. Cek DNSKEY record
dig +short beebanelabs.com DNSKEY

# 4. Verifikasi chain of trust
delv @8.8.8.8 beebanelabs.com A +rtrace

# 5. Online DNSSEC validation tools:
# - https://dnssec-analyzer.verisignlabs.com
# - https://dnssec-debugger.verisignlabs.com
# - https://zonemaster.net

# ===== DNSSEC SIGNING ZONE (BIND9) =====

# 1. Generate keys untuk zone
# KSK (Key Signing Key)
dnssec-keygen -a ECDSAP256SHA256 -f KSK beebanelabs.com

# ZSK (Zone Signing Key)
dnssec-keygen -a ECDSAP256SHA256 beebanelabs.com

# 2. Include keys di zone file
# Tambahkan di zone file:
# $INCLUDE "Kbeebanelabs.com.+013+12345.key"
# $INCLUDE "Kbeebanelabs.com.+013+67890.key"

# 3. Sign zone
dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) \
    -N INCREMENT -o beebanelabs.com -t db.beeebanelabs.com

# 4. Update named.conf untuk include signed zone
# zone "beebanelabs.com" {
#     type master;
#     file "db.beeebanelabs.com.signed";
#     key-directory "/etc/bind/keys";
#     inline-signing yes;
#     auto-dnssec maintain;
# };

# 5. Reload BIND
# rndc reload beebanelabs.com

# ===== VALIDASI DNSSEC DI CLIENT =====

# Linux (systemd-resolved):
# Edit /etc/systemd/resolved.conf:
# [Resolve]
# DNSSEC=allow-downgrade

# Unbound (recursive resolver):
# server:
#     module-config: "validator iterator"
#     auto-trust-anchor-file: "/var/lib/unbound/root.key"

# dig dengan DNSSEC validation:
dig +dnssec +cd beebanelabs.com A
# +cd = Checking Disabled (skip validation)

4. DNS over HTTPS (DoH) & DNS over TLS (DoT)

DoH dan DoT adalah protokol yang mengenkripsi query DNS untuk mencegah eavesdropping dan manipulasi oleh pihak ketiga.

4.1 Perbandingan DoH vs DoT

Aspek DNS over HTTPS (DoH) DNS over TLS (DoT)
Port443 (sama dengan HTTPS)853
ProtokolHTTP/2 atau HTTP/3TLS 1.2/1.3
StealthSulit dideteksi (baur dengan HTTPS)Mudah diblokir (port khusus)
KompatibilitasDidukung browser modernMemerlukan client khusus
ImplementasiClient-side (browser) atau OS-levelOS-level atau resolver-level
StandarRFC 8484RFC 7858
Bash β€” DoH & DoT Implementation
# ===== DNS OVER HTTPS (DoH) =====

# 1. TEST DoH dengan curl
# Cloudflare DoH
curl -s -H 'accept: application/dns-json' \
    'https://cloudflare-dns.com/dns-query?name=beebanelabs.com&type=A'

# Google DoH
curl -s -H 'accept: application/dns-json' \
    'https://dns.google/resolve?name=beebanelabs.com&type=A'

# Quad9 DoH
curl -s -H 'accept: application/dns-json' \
    'https://dns.quad9.net/dns-query?name=beebanelabs.com&type=A'

# 2. Menggunakan DoH di Firefox
# Settings β†’ Network Settings β†’ Enable DNS over HTTPS
# Provider: Cloudflare (default) atau Custom

# 3. Menggunakan DoH di Chrome
# Settings β†’ Privacy β†’ Security β†’ Use secure DNS
# Provider: Google Public DNS atau Custom

# 4. DoH di Linux dengan systemd-resolved
# Edit /etc/systemd/resolved.conf:
# [Resolve]
# DNS=1.1.1.1 9.9.9.9
# DNSOverTLS=yes
# DNSSEC=allow-downgrade

# Restart systemd-resolved:
# sudo systemctl restart systemd-resolved

# ===== DNS OVER TLS (DoT) =====

# 1. Test DoT dengan kdig (knot-dnsutils)
kdig -d @1.1.1.1 +tls beebanelabs.com

# 2. Setup DoT dengan Stubby (DNS Privacy Daemon)
# Install:
sudo apt install stubby

# Edit /etc/stubby/stubby.yml:
# resolution_type: GETDNS_RESOLUTION_STUB
# dns_transport_list:
#   - GETDNS_TRANSPORT_TLS
# tls_authentication: GETDNS_AUTHENTICATION_REQUIRED
# tls_query_padding_blocksize: 128
# listen_addresses:
#   - 127.0.0.1@5353
#   - 0::1@5353
# upstream_recursive_servers:
#   - address_data: 1.1.1.1
#     tls_auth_name: "cloudflare-dns.com"
#   - address_data: 9.9.9.9
#     tls_auth_name: "dns.quad9.net"

# 3. Konfigurasi Unbound untuk upstream DoT
# server:
#     do-tcp: yes
#     tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
#
# forward-zone:
#     name: "."
#     forward-tls-upstream: yes
#     forward-addr: 1.1.1.1@853#cloudflare-dns.com
#     forward-addr: 9.9.9.9@853#dns.quad9.net

# ===== PUBLIC DoH/DoT PROVIDERS =====
# Provider        DoH URL                              DoT Port
# Cloudflare      https://cloudflare-dns.com/dns-query  853
# Google          https://dns.google/resolve             853
# Quad9           https://dns.quad9.net/dns-query        853
# NextDNS         https://dns.nextdns.io                 853
# AdGuard         https://dns.adguard-dns.com/dns-query  853

5. DNS Filtering & Sinkholing

Implementation β€” DNS Filtering Solutions
# ===== DNS FILTERING & SINKHOLING =====

# DNS Filtering memblokir akses ke domain berbahaya
# dengan mengembalikan IP yang tidak valid atau
# mengarahkan ke halaman peringatan

# ===== PI-HOLE: DNS FILTERING UNTUK JARINGAN =====

# 1. Install Pi-hole
curl -sSL https://install.pi-hole.net | bash

# 2. Konfigurasi blocklists di /etc/pihole/adlists.list:
# https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
# https://mirror1.malwaredomains.com/files/justdomains
# https://zeustracker.abuse.ch/blocklist.php?download=domainblocklist
# https://s3.amazonaws.com/lists.disconnect.me/simple_malvertising.txt
# https://raw.githubusercontent.com/PolishFiltersTeam/KADhosts/master/KADhosts.txt

# 3. Tambahkan domain manual ke blacklist:
# Pi-hole Admin β†’ Blacklist β†’ Tambah domain

# 4. Custom DNS entries (local DNS):
# Edit /etc/pihole/custom.list:
# 192.168.1.10  server.local
# 192.168.1.20  nas.local

# ===== UNBOUND: DNS SINKHOLING =====
# Konfigurasi Unbound sebagai recursive resolver dengan sinkholing

# Tambahkan di /etc/unbound/unbound.conf:
# server:
#     interface: 0.0.0.0
#     access-control: 192.168.1.0/24 allow
#
#     # Sinkhole domain berbahaya
#     local-zone: "malware-domain.com" redirect
#     local-data: "malware-domain.com A 0.0.0.0"
#
#     local-zone: "phishing-site.com" redirect
#     local-data: "phishing-site.com A 0.0.0.0"
#
#     # Block TLD mencurigakan
#     local-zone: "xyz" always_nxdomain
#     local-zone: "top" always_nxdomain
#     local-zone: "club" always_nxdomain

# ===== SURICATA + DNS FILTERING =====
# DNS-based IDS rules untuk mendeteksi DNS tunneling:

# alert dns any any -> any any (msg:"DNS Tunnel Suspected"; \
#     dns.query; content:"tunnel"; nocase; \
#     threshold: type both, track by_src, count 100, seconds 60; \
#     sid:1000001; rev:1;)

# alert dns any any -> any any (msg:"DGA Domain Detected"; \
#     dns.query; pcre:"/^[a-z]{20,}\.(com|net|org)$/i"; \
#     sid:1000002; rev:1;)

# ===== DNS RESPONSE POLICY ZONES (RPZ) =====
# BIND9 mendukung RPZ untuk DNS filtering real-time

# Tambahkan di named.conf:
# zone "rpz.example.com" {
#     type master;
#     file "db.rpz.example.com";
#     allow-query { none; };
# };

# Di db.rpz.example.com:
# $TTL 300
# @   IN  SOA  ns1.example.com. admin.example.com. (
#         2026062601  ; Serial
#         3600        ; Refresh
#         900         ; Retry
#         604800      ; Expire
#         300 )       ; Negative TTL
#     IN  NS   ns1.example.com.
#
# ; Block specific domains
# malware-site.com    CNAME   .
# phishing-site.com   CNAME   .
# *.malware-domain.com CNAME  .
#
# ; Redirect to sinkhole
# c2-server.com       A       192.168.1.254

6. DNS Server Hardening

BIND9 β€” DNS Server Hardening
# ===== BIND9 HARDENING =====
# /etc/bind/named.conf.options

options {
    directory "/var/cache/bind";
    
    # 1. RESTRICT ACCESS
    # Hanya izinkan jaringan lokal untuk query
    allow-query {
        localhost;
        192.168.1.0/24;
        10.0.0.0/8;
    };
    
    # Hanya izinkan transfer zone ke secondary NS
    allow-transfer {
        secondary-ns-ip;
        none;
    };
    
    # 2. DISABLE RECURSION UNTUK AUTHORITATIVE SERVER
    recursion no;
    allow-recursion { none; };
    
    # Untuk recursive resolver:
    # recursion yes;
    # allow-recursion { localhost; 192.168.1.0/24; };
    
    # 3. RATE LIMITING
    rate-limit {
        responses-per-second 10;
        referrals-per-second 5;
        nodata-per-second 5;
        nxdomains-per-second 5;
        errors-per-second 5;
        all-per-second 20;
        window 15;
        slip 2;
        ipv4-prefix-length 24;
        ipv6-prefix-length 56;
        max-table-size 20000;
        min-table-size 500;
    };
    
    # 4. HIDE VERSION INFO
    version "not disclosed";
    hostname none;
    server-id none;
    
    # 5. QUERY LOGGING (untuk monitoring)
    # querylog yes;  # Aktifkan hanya untuk debugging
    
    # 6. PREVENT CACHE POISONING
    # Randomize source port
    query-source port *;
    query-source-v6 port *;
    
    # 7. DNSSEC VALIDATION
    dnssec-validation auto;
    
    # 8. MAX CACHE SIZE
    max-cache-size 256m;
    max-cache-ttl 3600;
    max-ncache-ttl 900;
    
    # 9. LIMIT QUERY SIZE
    max-query-size 4096;
    
    # 10. PREVENT AMPLIFICATION
    minimal-responses yes;
    fetch-glue no;
};

# ===== ZONE TRANSFER PROTECTION =====
# Pastikan zone transfer hanya ke authorized secondary NS
# zone "beebanelabs.com" {
#     type master;
#     file "db.beeebanelabs.com";
#     allow-transfer { secondary-ns-ip; };
#     also-notify { secondary-ns-ip; };
# };

# ===== CHROOT JAIL =====
# Jalankan BIND dalam chroot untuk isolasi
# sudo named -t /var/lib/named -u bind

# ===== FILE PERMISSIONS =====
# Pastikan permission file BIND yang benar:
# sudo chown root:bind /etc/bind
# sudo chmod 750 /etc/bind
# sudo chown root:bind /etc/bind/named.conf
# sudo chmod 640 /etc/bind/named.conf

7. Monitoring & Logging DNS

Python β€” DNS Monitoring Script
# ===== DNS MONITORING & DETECTION =====

import dns.resolver
import dns.query
import dns.rdatatype
import json
import time
import logging
from datetime import datetime

class DNSMonitor:
    def __init__(self, domains_to_monitor, trusted_resolvers=None):
        self.domains = domains_to_monitor
        self.resolvers = trusted_resolvers or ['8.8.8.8', '1.1.1.1', '9.9.9.9']
        self.baseline = {}
        self.logger = logging.getLogger('DNSMonitor')
        
    def get_records(self, domain, resolver_ip, record_type='A'):
        """Ambil DNS record dari resolver spesifik"""
        try:
            resolver = dns.resolver.Resolver()
            resolver.nameservers = [resolver_ip]
            resolver.timeout = 5
            resolver.lifetime = 10
            
            answers = resolver.resolve(domain, record_type)
            return sorted([str(rdata) for rdata in answers])
        except Exception as e:
            self.logger.error(f"Error querying {domain} via {resolver_ip}: {e}")
            return None
    
    def establish_baseline(self):
        """Bangun baseline untuk semua domain"""
        self.logger.info("Establishing DNS baseline...")
        
        for domain in self.domains:
            self.baseline[domain] = {}
            for resolver in self.resolvers:
                records = self.get_records(domain, resolver)
                self.baseline[domain][resolver] = records
                self.logger.info(f"Baseline {domain} via {resolver}: {records}")
    
    def check_consistency(self, domain):
        """Cek konsistensi respon dari beberapa resolver"""
        results = {}
        for resolver in self.resolvers:
            records = self.get_records(domain, resolver)
            results[resolver] = records
        
        # Bandingkan semua resolver
        unique_results = set(str(v) for v in results.values() if v)
        
        if len(unique_results) > 1:
            self.logger.warning(
                f"DNS INCONSISTENCY DETECTED for {domain}!"
            )
            self.logger.warning(f"Results: {json.dumps(results, indent=2)}")
            return False, results
        
        return True, results
    
    def check_for_changes(self, domain):
        """Cek perubahan dari baseline"""
        for resolver in self.resolvers:
            current = self.get_records(domain, resolver)
            baseline = self.baseline.get(domain, {}).get(resolver)
            
            if current and baseline and current != baseline:
                self.logger.warning(
                    f"DNS CHANGE DETECTED for {domain} via {resolver}!"
                )
                self.logger.warning(f"Baseline: {baseline}")
                self.logger.warning(f"Current:  {current}")
                return True
        
        return False
    
    def check_dnssec(self, domain):
        """Validasi DNSSEC untuk domain"""
        try:
            resolver = dns.resolver.Resolver()
            resolver.use_edns(0, dns.flags.DO, 4096)
            
            answer = resolver.resolve(domain, 'DNSKEY')
            
            # Cek apakah ada DNSKEY record
            has_ksk = False
            has_zsk = False
            
            for rdata in answer:
                if rdata.flags & 256:  # ZSK
                    has_zsk = True
                if rdata.flags & 257:  # KSK
                    has_ksk = True
            
            if has_ksk and has_zsk:
                return True, "DNSSEC properly configured"
            else:
                return False, "DNSKEY records incomplete"
                
        except dns.resolver.NoAnswer:
            return False, "No DNSKEY records found"
        except Exception as e:
            return False, f"DNSSEC check error: {e}"
    
    def detect_dga_domains(self, domain):
        """Deteksi domain yang kemungkinan DGA (Domain Generation Algorithm)"""
        import math
        
        # Analisis entropy dari domain name
        domain_name = domain.split('.')[0]
        
        # Hitung entropy Shannon
        freq = {}
        for char in domain_name:
            freq[char] = freq.get(char, 0) + 1
        
        length = len(domain_name)
        entropy = -sum(
            (count/length) * math.log2(count/length) 
            for count in freq.values()
        )
        
        # Indikator DGA:
        # - Entropy tinggi (> 3.5)
        # - Panjang nama domain tinggi (> 12)
        # - Ratio consonant:vowel tinggi
        vowels = sum(1 for c in domain_name.lower() if c in 'aeiou')
        consonants = sum(1 for c in domain_name.lower() if c.isalpha() and c not in 'aeiou')
        
        is_suspicious = False
        reasons = []
        
        if entropy > 3.5:
            is_suspicious = True
            reasons.append(f"High entropy: {entropy:.2f}")
        
        if len(domain_name) > 12:
            is_suspicious = True
            reasons.append(f"Long domain: {len(domain_name)} chars")
        
        if vowels > 0 and consonants / max(vowels, 1) > 5:
            is_suspicious = True
            reasons.append(f"Low vowel ratio: {consonants/max(vowels,1):.1f}")
        
        return is_suspicious, reasons
    
    def run_monitoring(self, interval=300):
        """Jalankan monitoring loop"""
        self.establish_baseline()
        
        while True:
            for domain in self.domains:
                # Cek konsistensi
                consistent, results = self.check_consistency(domain)
                if not consistent:
                    self.alert("INCONSISTENCY", domain, results)
                
                # Cek perubahan
                if self.check_for_changes(domain):
                    self.alert("CHANGE", domain, results)
                
                # Cek DNSSEC
                dnssec_ok, dnssec_msg = self.check_dnssec(domain)
                if not dnssec_ok:
                    self.alert("DNSSEC", domain, dnssec_msg)
            
            time.sleep(interval)
    
    def alert(self, alert_type, domain, details):
        """Kirim alert"""
        message = f"[{alert_type}] {domain}: {details}"
        self.logger.critical(message)
        # Tambahkan integrasi dengan alerting system:
        # - Email notification
        # - Slack/Teams webhook
        # - SIEM integration
        # - PagerDuty/OpsGenie

# ===== JALANKAN =====
# monitor = DNSMonitor(
#     domains_to_monitor=[
#         'beebanelabs.com',
#         'example.com',
#         'bank.com'
#     ],
#     trusted_resolvers=['8.8.8.8', '1.1.1.1', '9.9.9.9']
# )
# monitor.run_monitoring(interval=300)

8. Implementasi Praktis

Bash β€” Complete DNS Security Setup
# ===== COMPLETE DNS SECURITY SETUP =====

# ===== SETUP 1: UNBOUND (Recursive Resolver + DoT) =====

# Install Unbound
sudo apt update && sudo apt install unbound unbound-host

# Konfigurasi /etc/unbound/unbound.conf:
cat <<'EOF' | sudo tee /etc/unbound/unbound.conf
server:
    # Network
    interface: 0.0.0.0
    interface: ::0
    access-control: 127.0.0.0/8 allow
    access-control: 192.168.1.0/24 allow
    access-control: 10.0.0.0/8 allow
    
    # Security
    hide-identity: yes
    hide-version: yes
    harden-glue: yes
    harden-dnssec-stripped: yes
    harden-referral-path: yes
    harden-algo-downgrade: yes
    harden-large-queries: yes
    harden-short-bufsize: yes
    
    # Privacy
    qname-minimisation: yes
    minimise-resolver: yes
    rrset-roundrobin: yes
    
    # Performance
    msg-cache-size: 64m
    rrset-cache-size: 128m
    cache-max-ttl: 86400
    cache-min-ttl: 300
    prefetch: yes
    prefetch-key: yes
    
    # DoT upstream (DNS over TLS)
    tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
    
    # DNSSEC
    auto-trust-anchor-file: "/var/lib/unbound/root.key"
    
    # Rate limiting
    ip-rate-limit: 100
    ratelimit: 1000
    
    # Logging
    verbosity: 1
    log-queries: yes
    log-replies: yes
    logfile: /var/log/unbound/unbound.log

# Forward zone dengan DoT
forward-zone:
    name: "."
    forward-tls-upstream: yes
    forward-addr: 1.1.1.1@853#cloudflare-dns.com
    forward-addr: 1.0.0.1@853#cloudflare-dns.com
    forward-addr: 9.9.9.9@853#dns.quad9.net
    forward-addr: 149.112.112.112@853#dns.quad9.net
EOF

# Restart Unbound
sudo systemctl restart unbound
sudo systemctl enable unbound

# Test
dig @127.0.0.1 beebanelabs.com A
delv @127.0.0.1 beebanelabs.com A

# ===== SETUP 2: PI-HOLE + UNBOUND =====

# Install Pi-hole (menggunakan Unbound sebagai upstream)
curl -sSL https://install.pi-hole.net | bash
# Saat ditanya upstream DNS, pilih custom: 127.0.0.1#5335

# Unbound listen di port 5335 untuk Pi-hole:
# server:
#     interface: 127.0.0.1
#     port: 5335
#     do-ip4: yes
#     do-ip6: no
#     do-udp: yes
#     do-tcp: yes

# ===== SETUP 3: MONITORING =====
# Install DNS monitoring tools
sudo apt install dnstop iftop nethogs

# Real-time DNS query monitoring
sudo dnstop eth0

# DNS query logging dengan tcpdump
sudo tcpdump -i eth0 port 53 -n -l | tee /var/log/dns_queries.log

# DNS tunneling detection
# Monitor untuk query yang sangat panjang atau subdomain mencurigakan
grep -E "\.([a-z0-9]{30,})\." /var/log/dns_queries.log

9. Best Practices & Checklist

πŸ“‹ DNS Security Checklist
  1. Aktifkan DNSSEC β€” Sign zone dan validasi DNSSEC di resolver
  2. Gunakan DoH/DoT β€” Enkripsi query DNS untuk privasi
  3. Restrict Access β€” Jangan jalankan open resolver
  4. Rate Limiting β€” Implementasi RRL untuk mencegah amplifikasi
  5. Hide Version β€” Sembunyikan versi DNS server
  6. Split Architecture β€” Pisahkan authoritative dan recursive resolver
  7. Zone Transfer Protection β€” Restrict AXFR/IXFR
  8. Monitor & Log β€” Log semua query dan monitor anomali
  9. Regular Updates β€” Selalu update DNS software
  10. DNS Filtering β€” Implementasi blocklist untuk malware/phishing
  11. Incident Response β€” Siapkan plan untuk insiden DNS
  12. Registrar Security β€” Amankan akun registrar dengan 2FA dan registry lock

10. Quiz Pemahaman

Uji pemahaman Anda tentang DNS Security:

Pertanyaan 1: Apa fungsi utama DNSSEC?

a) Mengenkripsi semua traffic DNS
b) Memvalidasi integritas dan autentikasi data DNS menggunakan digital signatures
c) Mempercepat resolusi DNS
d) Mengganti protokol DNS dengan yang baru

Pertanyaan 2: Apa perbedaan utama antara DoH dan DoT?

a) DoH lebih lambat dari DoT
b) DoH menggunakan port 443 (baur dengan HTTPS), DoT menggunakan port 853
c) DoH hanya untuk browser, DoT hanya untuk server
d) Tidak ada perbedaan

Pertanyaan 3: Apa yang dimaksud dengan DNS Sinkholing?

a) Menghapus semua DNS record
b) Mengarahkan domain berbahaya ke IP yang tidak valid atau server monitoring
c) Mengenkripsi DNS cache
d) Mempercepat DNS resolution

Pertanyaan 4: Bagaimana cara mencegah DNS Amplification DDoS?

a) Menggunakan DNSSEC
b) Menggunakan DoH/DoT
c) Response Rate Limiting (RRL) dan anti-spoofing (BCP38)
d) Mengganti DNS server

Pertanyaan 5: Mengapa sebaiknya authoritative DNS dan recursive resolver dipisah?

a) Agar lebih murah
b) Untuk mengurangi attack surface dan mencegah cache poisoning
c) Agar DNS lebih cepat
d) Karena tidak bisa dijalankan bersamaan
πŸ” Zoom
100%
🎨 Tema