TrustPositif To RPZ Binary adalah file biner yang mengonversi daftar domain TrustPositif dari Kominfo menjadi format DNS RPZ. Mendukung fitur WhiteList dan Google SafeSearch (terbaru!). ✨ Aplikasi ini dirancang khusus untuk digunakan pada DNS BIND9 di distribusi Linux Debian atau Ubuntu (minimum Debian 12 / Ubuntu 22.04). Saat ini, belum diuji pada Unbound atau distribusi Linux lainnya. Spesifikasi minimum: CPU 2 Core, RAM 8GB. Disarankan menggunakan CPU 4 Core dan RAM 16GB atau lebih untuk performa yang lebih optimal.
Membuat DNS Recursive + Filter TrustPositif Sendiri Seperti Yang Selayaknya Di Gunakan Oleh Internet Service Provider (ISP) Di Indonesia 🌐
Anda dapat mengunduh dan mengeksekusi skrip instalasi secara otomatis dengan menggunakan salah satu perintah di bawah ini (silakan pilih salah satu, curl atau wget).
Menggunakan curl (Rekomendasi): 📥
curl -sSL https://raw.githubusercontent.com/alsyundawy/TrustPositif-To-RPZ-Binary/refs/heads/main/bind9_dns_rpz_setup_configurator.sh | bash
Menggunakan wget (Alternative): 📥
wget -qO- https://raw.githubusercontent.com/alsyundawy/TrustPositif-To-RPZ-Binary/refs/heads/main/bind9_dns_rpz_setup_configurator.sh | bash
Source Code dari file bind9_dns_rpz_setup_configurator.sh: 💻
#!/usr/bin/env bash
# ============================================================
# Nama : INSTALL_BIND9_RPZ_SETUP_CONFIGURATOR.SH
# Deskripsi : Skrip otomasi komprehensif untuk instalasi dan konfigurasi
# BIND9 DNS Server terintegrasi dengan Response Policy Zone (RPZ).
# Fitur utama meliputi:
# - Deteksi OS (Ubuntu 22.04+ / Debian 11+) & tipe virtualisasi.
# - Penanganan konflik Port 53 secara lebih aman.
# - Pilihan multi-sumber sinkronisasi database RPZ (GitHub / Komdigi).
# - Unduhan konfigurasi, binary RPZ, dan penjadwalan pembaruan (12 jam).
# - Validasi konfigurasi BIND sebelum reload.
# - Pemuatan ulang RPZ menggunakan rndc reload setelah RPZ berjalan.
# - Perbaikan struktur jaringan dasar melalui /etc/resolv.conf.
# Penulis : Harry Dertin Sutisna Alsyundawy
# Kontak : alsyundawy@gmail.com, +628568515212 (WhatsApp/Telegram/Call)
# Homepage : https://alsyundawy.com
# Repositori : https://github.com/alsyundawy/TrustPositif-To-RPZ-Binary
# Dibuat : 24 Januari 2025
# Diperbarui : 13 Juni 2026
# Versi : 2.3
# Lisensi : MIT
# ============================================================
#
# DOCNOTE v2.3:
# - Debian minimal dikunci ke Debian 11 (Bullseye); Debian 10 ke bawah ditolak.
# - Ubuntu minimal tetap Ubuntu 22.04 (Jammy); Ubuntu 20.04 ke bawah ditolak.
# - Struktur utama skrip dipertahankan agar kompatibel dengan alur v2.2.
# - Reload BIND setelah RPZ berjalan dilakukan dengan rndc reload.
# - Konfigurasi BIND divalidasi sebelum restart/reload untuk mencegah named gagal load.
#
# CHANGELOG v2.3:
# - FIX : Banner diselaraskan dari Debian 12+ menjadi Debian 11+.
# - FIX : check_root dipindahkan lebih awal agar non-root tidak gagal saat membuat log.
# - FIX : Logging dibuat lebih aman; gagal menulis log tidak menghentikan skrip.
# - FIX : Validasi versi OS dibuat lebih robust menggunakan angka major version.
# - FIX : Duplikasi pesan sukses RPZ dihapus.
# - SECURITY: Download file dilakukan atomik melalui file sementara sebelum overwrite target.
# - SECURITY: File konfigurasi utama dibackup dengan timestamp agar tidak tertimpa backup lama.
# - SECURITY: Penanganan port 53 tidak lagi membunuh proses unknown secara brutal.
# - SECURITY: /etc/resolv.conf dibackup sebelum diubah.
# - LOGIC : Service BIND dideteksi otomatis antara named/bind9.
# - LOGIC : Cron RPZ diperbarui agar menjalankan RPZ lalu rndc reload.
# - LOGIC : named-checkconf -z dijalankan setelah RPZ untuk test-load zone primary.
# - CLEANUP : Paket wildcard libidn* diganti paket eksplisit idn2/libidn2-0.
#
# ============================================================
# Pengaturan keamanan eksekusi:
# -e : hentikan skrip jika ada perintah yang gagal
# -u : cegah penggunaan variabel yang belum diatur
# -o pipefail : pipeline gagal jika salah satu bagian gagal
set -euo pipefail
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export DEBIAN_FRONTEND=noninteractive
# ------------------------------------------------------------
# Variabel warna untuk output terminal
# ------------------------------------------------------------
readonly CYAN='\033[1;36m'
readonly YELLOW='\033[1;33m'
readonly GREEN='\033[1;32m'
readonly MAGENTA='\033[1;35m'
readonly NC='\033[0m'
# ------------------------------------------------------------
# Lokasi direktori dan URL yang digunakan
# ------------------------------------------------------------
readonly BIND_DIR="/etc/bind"
readonly ZONES_DIR="${BIND_DIR}/zones"
readonly RPZ_BINARY="/usr/local/bin/rpz"
readonly LOG_FILE="/var/log/install_bind9_rpz.log"
readonly REPO_URL="https://raw.githubusercontent.com/alsyundawy/TrustPositif-To-RPZ-Binary/refs/heads/main/bind"
RPZ_URL="https://raw.githubusercontent.com/alsyundawy/TrustPositif-To-RPZ-Binary/refs/heads/main/rpz"
# Daftar berkas konfigurasi yang akan diambil dari repositori
readonly -a CONFIG_FILES=(
"named.conf.local"
"named.conf.options"
"zones/alsyundawy_safesearch.zones"
"zones/alsyundawy_whitelist.zones"
)
# Opsi APT non-interaktif yang tetap mempertahankan konfigurasi lokal lama bila ada konflik.
readonly -a APT_OPTS=(
-y
-qq
-o Dpkg::Options::=--force-confdef
-o Dpkg::Options::=--force-confold
)
# ============================================================
# Fungsi bantuan (logging dan validasi)
# ============================================================
log() {
local level="$1"
local message="$2"
local color="${3:-$NC}"
local timestamp
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
printf '%b[%s] %s%b\n' "${color}" "${level}" "${message}" "${NC}"
printf '[%s] [%s] %s\n' "${timestamp}" "${level}" "${message}" >> "${LOG_FILE}" 2>/dev/null || true
}
info() { log "INFO" "$1" "$CYAN"; }
warn() { log "WARN" "$1" "$YELLOW"; }
success() { log "OK" "$1" "$GREEN"; }
error_exit() {
log "ERROR" "$1" "$MAGENTA"
exit 1
}
backup_file() {
local target="$1"
if [ -e "${target}" ] || [ -L "${target}" ]; then
local backup="${target}.bak.$(date '+%Y%m%d-%H%M%S')"
cp -a "${target}" "${backup}" || error_exit "Gagal membuat backup: ${backup}"
success "Backup dibuat: ${backup}"
fi
}
check_url() {
local url="$1"
info "Memeriksa URL: ${url}"
if curl --head --silent --fail --location --connect-timeout 10 --max-time 20 "${url}" > /dev/null 2>&1; then
return 0
fi
# Fallback untuk endpoint yang menolak HTTP HEAD tetapi menerima GET.
if curl --silent --fail --location --connect-timeout 10 --max-time 20 --range 0-0 "${url}" > /dev/null 2>&1; then
return 0
fi
error_exit "URL tidak dapat diakses atau tidak valid: ${url}"
}
download_file() {
local url="$1"
local destination="$2"
local dir
local tmp_file
dir=$(dirname "${destination}")
mkdir -p "${dir}" || error_exit "Gagal membuat direktori: ${dir}"
tmp_file=$(mktemp "${dir}/.download.XXXXXX") || error_exit "Gagal membuat file sementara di: ${dir}"
info "Mengunduh: ${url} -> ${destination}"
if ! wget --quiet --timeout=30 --tries=3 "${url}" -O "${tmp_file}"; then
rm -f "${tmp_file}"
error_exit "Gagal mengunduh file dari: ${url}"
fi
if [ ! -s "${tmp_file}" ]; then
rm -f "${tmp_file}"
error_exit "File hasil unduhan kosong: ${url}"
fi
mv -f "${tmp_file}" "${destination}" || {
rm -f "${tmp_file}"
error_exit "Gagal memindahkan file sementara ke: ${destination}"
}
}
set_permissions() {
local target="$1"
local owner="$2"
local permissions="$3"
info "Mengatur izin ${permissions} dan kepemilikan ${owner} untuk: ${target}"
chown "${owner}" "${target}" || error_exit "Gagal mengatur kepemilikan untuk: ${target}"
chmod "${permissions}" "${target}" || error_exit "Gagal mengatur izin untuk: ${target}"
}
# ============================================================
# Pemasangan dependensi otomatis
# ============================================================
ensure_command() {
local cmd="$1"
local pkg="$2"
if command -v "${cmd}" > /dev/null 2>&1; then
info "Perintah '${cmd}' tersedia."
return 0
fi
warn "Perintah '${cmd}' tidak ditemukan. Akan diinstal dari paket '${pkg}'..."
apt-get "${APT_OPTS[@]}" install "${pkg}" || \
error_exit "Gagal menginstal paket '${pkg}' yang menyediakan '${cmd}'."
success "Paket '${pkg}' berhasil diinstal."
}
install_dependencies() {
info "Memperbarui cache paket untuk keperluan dependensi awal..."
apt-get update -qq || error_exit "Gagal menjalankan apt-get update. Periksa koneksi dan repositori."
ensure_command "curl" "curl"
ensure_command "wget" "wget"
ensure_command "systemctl" "systemd"
ensure_command "ss" "iproute2"
ensure_command "netstat" "net-tools"
ensure_command "fuser" "psmisc"
ensure_command "crontab" "cron"
}
# ============================================================
# Validasi sistem operasi
# ============================================================
check_os_version() {
if [ ! -f /etc/os-release ]; then
warn "Tidak dapat mendeteksi distribusi. Melewati pemeriksaan versi."
return
fi
# shellcheck disable=SC1091
. /etc/os-release
local os_id="${ID:-unknown}"
local version_id="${VERSION_ID:-0}"
local major_version="${version_id%%.*}"
if ! [[ "${major_version}" =~ ^[0-9]+$ ]]; then
error_exit "VERSION_ID tidak valid atau tidak numerik: ${version_id}"
fi
case "${os_id}" in
debian)
if [ "${major_version}" -lt 11 ]; then
error_exit "Debian versi ${version_id} tidak didukung. Minimal Debian 11 (Bullseye). Debian 10 ke bawah ditolak."
fi
if [ "${major_version}" -lt 13 ]; then
warn "Debian ${version_id} terdeteksi. Didukung, namun rekomendasi operasional tetap Debian 13 atau lebih tinggi agar memperoleh BIND versi lebih baru."
else
success "Debian ${version_id} memenuhi syarat."
fi
;;
ubuntu)
if [ "${major_version}" -lt 22 ]; then
error_exit "Ubuntu versi ${version_id} tidak didukung. Minimal Ubuntu 22.04 (Jammy). Rekomendasi Ubuntu 24.04 atau lebih tinggi."
fi
if [ "${major_version}" -lt 24 ]; then
warn "Ubuntu ${version_id} terdeteksi. Didukung, namun rekomendasi operasional tetap Ubuntu 24.04 atau lebih tinggi untuk BIND 9.18+."
else
success "Ubuntu ${version_id} memenuhi syarat."
fi
;;
*)
error_exit "Distribusi '${os_id}' tidak didukung. Skrip ini hanya mendukung minimal Ubuntu 22.04 (Jammy) dan Debian 11 (Bullseye)."
;;
esac
}
# ============================================================
# Deteksi virtualisasi dan instalasi guest tools
# ============================================================
detect_virtualization() {
info "Mendeteksi lingkungan virtualisasi..."
local virt=""
# Cek menggunakan systemd-detect-virt jika tersedia.
if command -v systemd-detect-virt > /dev/null 2>&1; then
virt=$(systemd-detect-virt 2>/dev/null || true)
fi
# Jika tidak terdeteksi, coba baca dari DMI.
if [ -z "${virt}" ] && [ -f /sys/class/dmi/id/product_name ]; then
local product
product=$(cat /sys/class/dmi/id/product_name 2>/dev/null || true)
case "${product,,}" in
*vmware*) virt="vmware" ;;
*kvm*|*qemu*) virt="kvm" ;;
*proxmox*) virt="kvm" ;;
esac
fi
if [ -z "${virt}" ] && command -v lscpu > /dev/null 2>&1; then
local lscpu_out
lscpu_out=$(lscpu 2>/dev/null || true)
if printf '%s\n' "${lscpu_out}" | grep -qi "hypervisor vendor"; then
local hv
hv=$(printf '%s\n' "${lscpu_out}" | awk -F: 'tolower($1) ~ /hypervisor vendor/ {gsub(/^[ \t]+|[ \t]+$/, "", $2); print $2; exit}')
case "${hv,,}" in
*vmware*) virt="vmware" ;;
*kvm*) virt="kvm" ;;
esac
fi
fi
case "${virt}" in
vmware)
success "Terdeteksi VMware. Memasang open-vm-tools..."
apt-get "${APT_OPTS[@]}" install open-vm-tools || \
warn "Gagal memasang open-vm-tools, lanjut tanpa tools tamu."
;;
kvm)
success "Terdeteksi KVM/QEMU (Proxmox VE mungkin). Memasang qemu-guest-agent..."
apt-get "${APT_OPTS[@]}" install qemu-guest-agent || \
warn "Gagal memasang qemu-guest-agent, lanjut tanpa agen tamu."
;;
*)
success "Mesin fisik (baremetal) atau virtualisasi tidak teridentifikasi. Melewati instalasi guest tools."
;;
esac
}
# ============================================================
# Pemilihan sumber RPZ
# ============================================================
choose_rpz_source() {
echo ""
info "PILIH SUMBER DATABASE RPZ YANG AKAN DIGUNAKAN:"
info " 1) GITHUB (DEFAULT)"
info " 2) KOMDIGI"
info " 3) ALSYUNDAWY DATABASE"
local rpz_choice
read -rp "Masukkan pilihan [1/2/3, default: 1]: " rpz_choice </dev/tty || rpz_choice=1
rpz_choice="${rpz_choice:-1}"
case "${rpz_choice}" in
2)
info "MENGGUNAKAN DATABASE RPZ DARI KOMDIGI."
RPZ_URL="https://raw.githubusercontent.com/alsyundawy/TrustPositif-To-RPZ-Binary/refs/heads/main/rpz-komdigi-database"
;;
3)
info "MENGGUNAKAN DATABASE RPZ DARI ALSYUNDAWY DATABASE."
RPZ_URL="https://raw.githubusercontent.com/alsyundawy/TrustPositif-To-RPZ-Binary/refs/heads/main/rpz-alsyundawy-database"
;;
*)
info "MENGGUNAKAN DATABASE RPZ DARI GITHUB (DEFAULT)."
RPZ_URL="https://raw.githubusercontent.com/alsyundawy/TrustPositif-To-RPZ-Binary/refs/heads/main/rpz"
;;
esac
}
# ============================================================
# Tahapan instalasi dan konfigurasi
# ============================================================
check_root() {
if [ "${EUID}" -ne 0 ]; then
if ! command -v sudo > /dev/null 2>&1; then
printf 'ERROR: Skrip ini memerlukan hak akses root dan sudo tidak tersedia. Jalankan sebagai root.\n' >&2
exit 1
fi
warn "Skrip ini memerlukan hak akses root. Meminta elevasi..."
exec sudo -E bash "$0" "$@"
# exec mengganti proses; baris setelah ini tidak akan pernah tercapai.
fi
}
show_banner() {
local script_name="INSTALL_BIND9_RPZ_SETUP_CONFIGURATOR.SH"
local os_info="Unknown OS"
local kernel_info
if [ -f /etc/os-release ]; then
# shellcheck disable=SC1091
os_info=$(. /etc/os-release 2>/dev/null && echo "${PRETTY_NAME:-Unknown OS}")
fi
kernel_info=$(uname -r)
echo -e "${MAGENTA}"
echo "============================================================"
echo " PROGRAM : BIND9 DNS Server + RPZ Installer & Configurator"
echo " SCRIPT : ${script_name}"
echo " DESC : Skrip otomasi instalasi & konfigurasi BIND9"
echo " terintegrasi RPZ dengan dukungan multi-sumber,"
echo " penanganan port 53, setup resolv.conf,"
echo " auto-reload layanan setelah RPZ berjalan,"
echo " deteksi OS (Ubuntu 22.04+ / Debian 11+),"
echo " dan tipe virtualisasi."
echo "------------------------------------------------------------"
echo " AUTHOR : Harry Dertin Sutisna Alsyundawy"
echo " LICENSE : MIT License (Free & Open Source)"
echo " REPOS : github.com/alsyundawy/TrustPositif-To-RPZ-Binary"
echo "------------------------------------------------------------"
echo " CONTACT : alsyundawy@gmail.com"
echo " +628568515212 (WhatsApp/Telegram/Call)"
echo " HOMEPAGE: https://alsyundawy.com"
echo "------------------------------------------------------------"
echo " VERSION : 2.3"
echo " UPDATED : 13 Juni 2026"
echo " CREATED : 24 Januari 2025"
echo " TARGET : Debian >=11, Ubuntu >=22.04, BIND9 + RPZ"
echo "------------------------------------------------------------"
echo " SYSTEM : ${os_info}"
echo " KERNEL : ${kernel_info}"
echo " LOGFILE : ${LOG_FILE}"
echo "============================================================"
echo -e "${NC}"
}
fix_hostname() {
info "Memeriksa entri hostname di /etc/hosts..."
local host
host=$(hostname)
if ! awk -v h="${host}" '$1 == "127.0.0.1" { for (i = 2; i <= NF; i++) if ($i == h) found = 1 } END { exit found ? 0 : 1 }' /etc/hosts 2>/dev/null; then
info "Menambahkan hostname '${host}' ke /etc/hosts..."
printf '127.0.0.1 %s\n' "${host}" >> /etc/hosts || error_exit "Gagal memperbarui /etc/hosts."
success "Hostname '${host}' berhasil ditambahkan."
else
success "Hostname '${host}' sudah ada di /etc/hosts."
fi
}
update_system() {
info "Memperbarui daftar repositori..."
apt-get update -qq || error_exit "Gagal memperbarui repositori apt."
info "Memperbarui paket yang terinstal..."
apt-get "${APT_OPTS[@]}" upgrade || error_exit "Gagal melakukan upgrade."
info "Distribusi upgrade (jika diperlukan)..."
apt-get "${APT_OPTS[@]}" dist-upgrade || error_exit "Gagal melakukan dist-upgrade."
info "Membersihkan paket tidak terpakai..."
apt-get "${APT_OPTS[@]}" --purge autoremove
apt-get clean -qq
apt-get autoclean -qq
info "Memeriksa dan memperbaiki dependensi..."
apt-get "${APT_OPTS[@]}" install -f || error_exit "Gagal memperbaiki dependensi."
success "Sistem berhasil diperbarui."
}
install_bind9() {
info "Menginstal paket BIND9, alat bantu, dan utilitas jaringan..."
apt-get "${APT_OPTS[@]}" install \
bind9 bind9-dnsutils bind9-utils \
bc git htop iftop telnet traceroute rsync screen whois fping ipcalc subnetcalc idn2 libidn2-0 \
|| error_exit "Gagal menginstal paket-paket yang diperlukan."
success "Semua paket (BIND9, dnsutils, dan utilitas) terinstal."
}
setup_zones_dir() {
info "Menyiapkan direktori zone: ${ZONES_DIR}"
mkdir -p "${ZONES_DIR}" || error_exit "Gagal membuat direktori: ${ZONES_DIR}"
set_permissions "${ZONES_DIR}" "root:bind" "755"
success "Direktori zone siap."
}
download_bind_configs() {
info "Mengambil file konfigurasi BIND9 dari repositori..."
for file in "${CONFIG_FILES[@]}"; do
local destination="${BIND_DIR}/${file}"
local url="${REPO_URL}/${file}"
if [[ "${file}" == "named.conf.local" || "${file}" == "named.conf.options" ]]; then
backup_file "${destination}"
rm -f "${destination}"
fi
check_url "${url}"
download_file "${url}" "${destination}"
set_permissions "${destination}" "root:bind" "644"
success "File '${file}' berhasil dikonfigurasi."
done
}
validate_bind_config() {
info "Memvalidasi konfigurasi BIND..."
if ! named-checkconf; then
error_exit "Konfigurasi BIND9 tidak valid. Silakan periksa file di ${BIND_DIR}."
fi
success "Konfigurasi BIND9 valid."
}
validate_bind_config_with_zones() {
info "Memvalidasi konfigurasi BIND dan test-load zone primary..."
if ! named-checkconf -z; then
error_exit "Konfigurasi BIND9 atau zone tidak valid. Periksa konfigurasi dan file zone di ${BIND_DIR}."
fi
success "Konfigurasi BIND9 dan zone valid."
}
port53_in_use() {
if ss -tuln 2>/dev/null | grep -qE '(^|[[:space:]])(tcp|udp).*:53[[:space:]]'; then
return 0
fi
if netstat -tuln 2>/dev/null | grep -qE '(^|[[:space:]])(tcp|udp).*:53[[:space:]]'; then
return 0
fi
return 1
}
show_port53_users() {
warn "Daftar proses/listener port 53 saat ini:"
ss -tulpen 2>/dev/null | grep -E '(^|[[:space:]])(tcp|udp).*:53[[:space:]]' || true
netstat -tulpen 2>/dev/null | grep -E '(^|[[:space:]])(tcp|udp).*:53[[:space:]]' || true
}
handle_port53() {
info "Memeriksa port 53..."
if ! port53_in_use; then
success "Port 53 tersedia."
return 0
fi
warn "Port 53 sedang dipakai. Mencoba menghentikan layanan DNS lokal yang umum..."
show_port53_users
local svc
for svc in systemd-resolved dnsmasq unbound; do
if systemctl list-unit-files "${svc}.service" > /dev/null 2>&1 && systemctl is-active --quiet "${svc}.service"; then
systemctl stop "${svc}.service" || warn "Gagal menghentikan ${svc}.service"
systemctl disable "${svc}.service" --quiet || warn "Gagal menonaktifkan ${svc}.service"
warn "${svc}.service dihentikan dan dinonaktifkan."
fi
done
sleep 2
if port53_in_use; then
show_port53_users
error_exit "Port 53 masih dipakai oleh proses lain. Hentikan proses tersebut secara manual agar BIND9 dapat bind ke port 53."
fi
success "Port 53 berhasil dibersihkan."
}
get_bind_service() {
if systemctl list-unit-files named.service > /dev/null 2>&1; then
printf 'named'
return 0
fi
if systemctl list-unit-files bind9.service > /dev/null 2>&1; then
printf 'bind9'
return 0
fi
printf 'named'
}
restart_bind9() {
local bind_service
bind_service=$(get_bind_service)
info "Menyalakan ulang BIND9 (${bind_service})..."
systemctl restart "${bind_service}" || error_exit "Gagal menjalankan BIND9 melalui service ${bind_service}."
systemctl enable "${bind_service}" --quiet || error_exit "Gagal mengaktifkan ${bind_service} saat boot."
if ! systemctl is-active --quiet "${bind_service}"; then
error_exit "Service ${bind_service} tidak aktif setelah restart."
fi
success "BIND9 aktif dan dijadwalkan menyala saat boot."
}
setup_rpz_binary() {
info "Mengunduh binary RPZ..."
check_url "${RPZ_URL}"
download_file "${RPZ_URL}" "${RPZ_BINARY}"
set_permissions "${RPZ_BINARY}" "root:root" "755"
success "Binary RPZ siap di ${RPZ_BINARY}"
}
setup_cron() {
info "Menyiapkan cron job untuk RPZ (tiap 12 jam)..."
local rndc_cmd
local cron_entry
local tmp_cron
rndc_cmd=$(command -v rndc 2>/dev/null || printf '/usr/sbin/rndc')
cron_entry="0 */12 * * * ${RPZ_BINARY} >> ${LOG_FILE} 2>&1 && ${rndc_cmd} reload >> ${LOG_FILE} 2>&1"
tmp_cron=$(mktemp) || error_exit "Gagal membuat file sementara cron."
{ crontab -l 2>/dev/null || true; } | grep -vF "${RPZ_BINARY}" > "${tmp_cron}" || true
printf '%s\n' "${cron_entry}" >> "${tmp_cron}"
crontab "${tmp_cron}" || {
rm -f "${tmp_cron}"
error_exit "Gagal menambahkan cron job."
}
rm -f "${tmp_cron}"
success "Cron job berhasil diset: ${cron_entry}"
}
configure_resolv_conf() {
info "Mengonfigurasi /etc/resolv.conf untuk menggunakan 127.0.0.1 di urutan pertama..."
backup_file "/etc/resolv.conf"
if [ -L /etc/resolv.conf ]; then
warn "/etc/resolv.conf adalah symlink, menggantinya dengan file reguler..."
local real_file
real_file=$(readlink -f /etc/resolv.conf || true)
rm -f /etc/resolv.conf
if [ -n "${real_file}" ] && [ -f "${real_file}" ]; then
cp "${real_file}" /etc/resolv.conf
else
touch /etc/resolv.conf
fi
fi
sed -i '/^[[:space:]]*nameserver[[:space:]]*127\.0\.0\.1[[:space:]]*$/d' /etc/resolv.conf 2>/dev/null || true
local tmp_resolv
tmp_resolv=$(mktemp) || error_exit "Gagal membuat file sementara resolv.conf."
printf 'nameserver 127.0.0.1\n' > "${tmp_resolv}"
cat /etc/resolv.conf >> "${tmp_resolv}" 2>/dev/null || true
cat "${tmp_resolv}" > /etc/resolv.conf
rm -f "${tmp_resolv}"
success "nameserver 127.0.0.1 berhasil ditambahkan di awal baris /etc/resolv.conf."
}
run_rpz() {
info "Menjalankan RPZ untuk sinkronisasi awal..."
"${RPZ_BINARY}" || error_exit "Gagal menjalankan binary RPZ: ${RPZ_BINARY}"
validate_bind_config_with_zones
info "Menjalankan rndc reload setelah RPZ berjalan..."
rndc reload || error_exit "Gagal menjalankan rndc reload setelah RPZ."
success "RPZ berhasil dijalankan dan BIND berhasil di-reload."
}
# ============================================================
# Jalur utama skrip
# ============================================================
main() {
check_root "$@"
mkdir -p "$(dirname "${LOG_FILE}")"
touch "${LOG_FILE}"
show_banner
choose_rpz_source
if ! command -v apt-get > /dev/null 2>&1; then
error_exit "apt-get tidak ditemukan. Skrip hanya bekerja pada distribusi Debian/Ubuntu."
fi
check_os_version
fix_hostname
update_system
install_dependencies
detect_virtualization
handle_port53
install_bind9
setup_zones_dir
download_bind_configs
validate_bind_config
restart_bind9
setup_rpz_binary
setup_cron
configure_resolv_conf
echo ""
success "============================================================"
success " Instalasi BIND9 + RPZ selesai dengan sukses!"
success " Log kegiatan tersimpan di: ${LOG_FILE}"
success "============================================================"
# Konfirmasi menjalankan RPZ.
echo ""
info "Proses instalasi selesai. Apakah Anda ingin langsung menjalankan binary RPZ sekarang?"
local answer
read -rp " Jalankan RPZ? [Y/n] " answer </dev/tty || answer="y"
answer="${answer:-y}"
case "${answer:0:1}" in
y|Y|"")
run_rpz
;;
*)
info "RPZ tidak dijalankan. Anda dapat menjalankannya nanti dengan perintah:"
info " ${RPZ_BINARY} && rndc reload"
;;
esac
echo ""
info "Tips pengujian DNS dengan nslookup:"
info " - Uji dari server ini: nslookup google.com 127.0.0.1"
info " - Uji dari klien : nslookup google.com <alamat IP server ini>"
info " - Uji dari server ini: nslookup pornhub.com 127.0.0.1"
info " - Uji dari klien : nslookup pornhub.com <alamat IP server ini>"
info " Jika RPZ memblokir domain tertentu, respon akan berbeda."
info " Pastikan klien menggunakan DNS server ini agar RPZ aktif."
}
main "$@"
Untuk mendapatkan performa yang optimal, peningkatan stabilitas, dan keamanan tingkat lanjut (security) baik pada lingkungan baremetal maupun virtualisasi, sangat disarankan untuk menggunakan Kernel Zabbly terbaru.
Anda dapat menggunakan curl atau wget untuk menyimpan kunci otentikasi Zabbly:
Menggunakan curl (Rekomendasi): 📥
mkdir -p /etc/apt/keyrings/
curl -fsSL https://pkgs.zabbly.com/key.asc -o /etc/apt/keyrings/zabbly.asc
Menggunakan wget (Alternative): 📥
mkdir -p /etc/apt/keyrings/
wget -q https://pkgs.zabbly.com/key.asc -O /etc/apt/keyrings/zabbly.asc
Jalankan perintah berikut untuk menambahkan repositori Zabbly ke sistem Anda:
sh -c 'cat <<EOF > /etc/apt/sources.list.d/zabbly-kernel-stable.sources
Enabled: yes
Types: deb
URIs: https://pkgs.zabbly.com/kernel/stable
Suites: $(. /etc/os-release && echo ${VERSION_CODENAME})
Components: main
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/zabbly.asc
EOF'
Setelah repositori ditambahkan, perbarui daftar paket dan instal kernel Zabbly:
apt-get update
apt-get install linux-zabbly -y
💡 Catatan: Setelah instalasi selesai, pastikan untuk melakukan reboot pada server Anda agar sistem memuat dan menggunakan kernel baru.
Untuk memperoleh BIND versi lebih baru (9.20 atau 9.21) yang tidak tersedia di repositori bawaan distribusi, Anda dapat menggunakan sumber paket tambahan berikut.
ISC menyediakan PPA (Personal Package Archive) resmi untuk Ubuntu yang berisi BIND versi terbaru:
ppa:isc/bindppa:isc/bind-dev# Tambahkan PPA (pilih salah satu)
sudo add-apt-repository ppa:isc/bind # Versi stabil 9.20
# sudo add-apt-repository ppa:isc/bind-dev # Versi pengembangan 9.21
# Perbarui daftar paket
sudo apt update
# Install BIND beserta utilitas pendukung
sudo apt install bind9 bind9-dnsutils bind9-utils
Untuk Debian, ISC merekomendasikan repositori yang dikelola oleh Ondrej Surý di packages.sury.org. Repositori ini menyediakan paket BIND yang lebih baru dibandingkan repositori bawaan Debian:
# Install dependensi
sudo apt update
sudo apt install -y lsb-release ca-certificates curl
# Unduh dan pasang kunci GPG repositori
sudo curl -sSLo /tmp/debsuryorg-archive-keyring.deb \
https://packages.sury.org/debsuryorg-archive-keyring.deb
sudo dpkg -i /tmp/debsuryorg-archive-keyring.deb
# Tambahkan repositori BIND (pilih salah satu)
# Versi stabil 9.20:
sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/debsuryorg-archive-keyring.gpg] https://packages.sury.org/bind/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/bind.list'
# Versi pengembangan 9.21:
# sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/debsuryorg-archive-keyring.gpg] https://packages.sury.org/bind-dev/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/bind-dev.list'
# Perbarui daftar paket dan install
sudo apt update
sudo apt install bind9 bind9-dnsutils bind9-utils
crontab -e
* */12 * * * /usr/local/bin/rpz > /dev/null 2>&1
// Definisi ACL (Access Control List) untuk jaringan yang diizinkan
acl localnet {
// Jaringan private IPv4 (RFC 1918)
10.0.0.0/8; // Blok IP privat kelas A
172.16.0.0/12; // Blok IP privat kelas B
192.168.0.0/16; // Blok IP privat kelas C
// Loopback (localhost)
127.0.0.0/8; // Loopback IPv4
::1/128; // Loopback IPv6
localhost; // Alias untuk loopback
// Contoh alamat IPv4 dan IPv6 publik (dikomentari)
// 202.88.254.0/22; // Contoh blok IPv4 publik
// 2001:6f83::/32; // Contoh blok IPv6 publik
};
// Pengaturan global untuk server BIND
options {
// Direktori untuk menyimpan file cache dan zona
directory "/var/cache/bind";
// Mendengarkan permintaan DNS pada port 53 untuk semua IPv4 dan IPv6
listen-on port 53 { any; }; // Mendengarkan pada port 53 untuk semua IPv4
listen-on-v6 port 53 { any; }; // Mendengarkan pada port 53 untuk semua IPv6
// Contoh mendengarkan pada alamat IPv4 dan IPv6 tertentu (dikomentari)
// listen-on port 53 { 127.0.0.1; 192.168.254.254; 202.88.254.254; }; // IPv4 (loopback, privat, dan publik)
// listen-on-v6 port 53 { ::1; 2001:6f83:88:99:202:88:254:254; }; // IPv6 (loopback dan publik)
// Membatasi akses query dan rekursi hanya untuk jaringan yang didefinisikan di `localnet`
allow-query { localnet; }; // Hanya izinkan query dari `localnet`
allow-recursion { localnet; }; // Hanya izinkan rekursi untuk `localnet`
allow-query-cache { localnet; }; // Hanya izinkan query cache untuk `localnet`
#BASIC PERINTAH DASAR NSLOOKUP DOMAIN DAN IP (WAJIB DIKETAHUI UNTUK TROBLESHOTING DNS!)
nslookup domain/ip ipmesindns
nslookup domain.tld
nslookup domain.tld 127.0.0.1
nslookup domain.tld 192.168.254.254
nslookup 192.168.254.254
nslookup 192.168.254.254 127.0.0.1
nslookup 192.168.254.254 192.168.254.254
#Perintah NSLOOKUP Dengan Menanyakan Query Ke DNS PUBLIK
nslookup domain.tld 8.8.8.8
nslookup domain.tld 1.1.1.1
nslookup domain.tld 9.9.9.9
#Contoh Beberapa Perintah NSLOOKUP
nslookup -query=any example.com
nslookup -query=ns example.com
nslookup -query=a example.com
nslookup -query=aaaa example.com
nslookup -query=mx example.com
nslookup -query=soa example.com
#Perintah NSLOOKUP apabila DNS Server Menggunakan Port Lain Misal Port 5353
nslookup -port=5353 example.com
Jika Anda merasa terbantu dan ingin mendukung proyek ini, pertimbangkan untuk berdonasi melalui https://www.paypal.me/alsyundawy. Terima kasih atas dukungannya! ☕
Jika Anda merasa terbantu dan ingin mendukung proyek ini, pertimbangkan untuk berdonasi melalui QRIS. Terima kasih atas dukungannya! ☕
Anda bebas untuk mengubah, mendistribusikan script ini untuk keperluan anda 📝
Jangan semangat tetap putus asa, tetaplah mengeluh meski gak ada yang pedulikan. Ketika yang lain bisa kenapa harus saya, ketika yang lain tidak bisa apalagi saya. Tetaplah hidup meski tidak berguna, maju tak gentar membela yang bayar !!!! Yoi, ya begitulah ….. 🤣