#!/bin/bash ################################################################################################################ # NAMA SCRIPT : TRUSTPOSITIF-RPZ-DNS-ZONE-UPDATER.SH # FUNGSI : MEMPERBARUI ZONA DNS DENGAN DATA TRUSTPOSITIF, WHITELIST, DAN SAFESEARCH # DESKRIPSI : SCRIPT INI MENGUNDUH DATA DARI BERBAGAI SUMBER DAN MENGONVERSINYA KE FORMAT RPZ UNTUK BIND. # DITAMBAHKAN FUNGSI UNTUK MENGHAPUS DOMAIN WHITELIST & DOH DARI BLACKLIST # AUTHOR : HARRY DERTIN SUTISNA (ORIGINAL) # MODIFIED BY : CLAUDE ASSISTANT (PENAMBAHAN FUNGSI WHITELIST CLEANER) # WAKTU & TANGGAL : JAKARTA, 02 JANUARY 2025 (ORIGINAL) # MODIFIED: 12 JANUARY 2026 ################################################################################################################ # Warna ANSI MERAH="\033[1;31m" HIJAU="\033[1;32m" KUNING="\033[1;33m" CYAN="\033[1;36m" MAGENTA="\033[1;35m" BIRU="\033[1;34m" PUTIH="\033[1;37m" HITAM="\033[1;30m" ABUABU="\033[1;90m" MERAH_TUA="\033[1;91m" HIJAU_TUA="\033[1;92m" KUNING_TUA="\033[1;93m" CYAN_TUA="\033[1;96m" MAGENTA_TUA="\033[1;95m" BIRU_TUA="\033[1;94m" PUTIH_TUA="\033[1;97m" RESET="\033[0m" # Variabel URL # URL_TRUSTPOSITIF="https://raw.githubusercontent.com/alsyundawy/TrustPositif/refs/heads/main/alsyundawy_blacklist_complete_v2.txt" URL_TRUSTPOSITIF="https://gitea.ismayadjati.id/syamsulhadiae/trustpositif/raw/branch/main/blacklist_cleaned_v2.txt" # URL_TRUSTPOSITIF="https://trustpositif.komdigi.go.id/assets/db/domains_isp" URL_WHITELIST="https://raw.githubusercontent.com/alsyundawy/hds-pihole-blacklist/main/dnssehat/whitelist.txt" URL_SAFESEARCH="https://www.google.com/supported_domains" # URL Whitelist tambahan untuk dibersihkan dari blacklist (DoH/DoT domains) # URL_DOH_WHITELIST="https://raw.githubusercontent.com/hagezi/dns-blocklists/main/domains/doh-only-domains.txt" URL_DOH_WHITELIST="https://raw.githubusercontent.com/alsyundawy/TrustPositif/refs/heads/main/doh-onlydomains.txt" # File output zona FILE_TRUSTPOSITIF="/etc/bind/zones/trustpositif.zones" FILE_WHITELIST="/etc/bind/zones/whitelist.zones" FILE_SAFESEARCH="/etc/bind/zones/safesearch.zones" # CNAME targets CNAME_TRUSTPOSITIF="lamanlabuh.resolver.id." CNAME_SAFESEARCH="forcesafesearch.google.com." # Temporary files TMP_DIR="/tmp/rpz_updater_$$" TMP_TRUSTPOSITIF="$TMP_DIR/trustpositif_domains.txt" TMP_TRUSTPOSITIF_CLEAN="$TMP_DIR/trustpositif_cleaned.txt" TMP_WHITELIST="$TMP_DIR/whitelist_domains.txt" TMP_SAFESEARCH="$TMP_DIR/safesearch_domains.txt" TMP_DOH_WHITELIST="$TMP_DIR/doh_whitelist.txt" TMP_COMBINED_WHITELIST="$TMP_DIR/combined_whitelist.txt" # Konfigurasi ENABLE_DOH_WHITELIST=true # Set false untuk menonaktifkan pembersihan DoH ENABLE_CUSTOM_WHITELIST=true # Set false untuk menonaktifkan whitelist kustom CUSTOM_WHITELIST_FILE="" # Path ke file whitelist kustom lokal (opsional) # Fungsi untuk menampilkan pesan berwarna function cetak_pesan() { echo -e "$1$2${RESET}" } # Fungsi cleanup saat exit cleanup() { if [[ -d "$TMP_DIR" ]]; then rm -rf "$TMP_DIR" fi } trap cleanup EXIT # Buat direktori temporary mkdir -p "$TMP_DIR" cetak_pesan "$CYAN" "PEMBAHARUAN DATABASE INTERNET SEHAT TRUSTPOSITIF DIPROSES" # Banner dengan warna echo -e "${MAGENTA} _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ ( H | A | R | R | Y ) ( D | S ) ( A | L | S | Y | U | N | D | A | W | Y ) \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ ${RESET}" echo -e "${CYAN}############################################################################${RESET}" echo -e "${CYAN}## ##${RESET}" echo -e "${CYAN}##${MERAH} PEMBAHARUAN DATABASE INTERNET SEHAT TRUSTPOSITIF ${CYAN}##${RESET}" echo -e "${CYAN}##${KUNING} SUPPORT JUGA GOOGLE SAFESEARCH & WHITELIST ${CYAN}##${RESET}" echo -e "${CYAN}##${MAGENTA} UNTUK DNS FILTER ISP ${CYAN}##${RESET}" echo -e "${CYAN}##${HIJAU_TUA} + WHITELIST CLEANER (DOH/DOT DOMAINS REMOVAL) ${CYAN}##${RESET}" echo -e "${CYAN}## ##${RESET}" echo -e "${CYAN}##${HIJAU} SCRIPT INI DIBUAT & DIMODIFIKASI OLEH HARRY DS ALSYUNDAWY ${CYAN}##${RESET}" echo -e "${CYAN}##${BIRU} ALSYUNDAWY@GMAIL.COM | 08568515212 | ALSYUNDAWY.COM ${CYAN}##${RESET}" echo -e "${CYAN}##${KUNING} PADA TANGGAL 02 JANUARY 2025 ${CYAN}##${RESET}" echo -e "${CYAN}## ##${RESET}" echo -e "${CYAN}############################################################################${RESET}" # Fungsi untuk membuat header RPZ generate_rpz_header() { cat << EOF ; ; RPZ File Generated by TRUSTPOSITIF-RPZ-DNS-ZONE-UPDATER.SH ; Dibuat pada $(date '+%Y-%m-%d %H:%M:%S') ; Author: HARRY DERTIN SUTISNA ALSYUNDAWY ; Email: alsyundawy@gmail.com ; WhatsApp/Telegram/Call: +628568515212 & +6281298986464 (WHATSAPP/TELEGRAM/CALL) ; HOMEPAGE: https://github.com/alsyundawy ; ; \$TTL 300 @ IN SOA dns.domain.net.id. hostmaster.domain.net.id. ( $(date '+%Y%m%d%H') ; Serial 10800 ; Refresh 120 ; Retry 604800 ; Expire 3600 ) ; Minimum TTL @ IN NS lamanlabuh.resolver.id. EOF } #=============================================================================== # FUNGSI WHITELIST CLEANER - Menghapus domain whitelist dari blacklist # Dioptimasi untuk file besar dengan penggunaan memory dan CPU yang efisien #=============================================================================== # Fungsi untuk membersihkan dan normalisasi file domain clean_domain_file() { local input_file="$1" local output_file="$2" local file_type="$3" cetak_pesan "$ABUABU" " ├─ Membersihkan $file_type..." # Handle berbagai format: # - Hapus baris komentar (dimulai dengan #, !, //) # - Hapus baris kosong # - Lowercase semua domain # - Trim whitespace # - Hapus karakter CR (Windows line endings) # - Sort dan unique sed 's/\r$//' "$input_file" | \ awk ' { # Trim leading/trailing whitespace gsub(/^[[:space:]]+|[[:space:]]+$/, "") # Skip empty lines if (length($0) == 0) next # Skip comment lines if (/^[#!]/ || /^\/\//) next # Convert to lowercase and print print tolower($0) } ' | LC_ALL=C sort -u > "$output_file" local count=$(wc -l < "$output_file") cetak_pesan "$ABUABU" " │ └─ $file_type: $count domain unik" } # Fungsi untuk mengunduh whitelist DoH/DoT download_doh_whitelist() { if [[ "$ENABLE_DOH_WHITELIST" != "true" ]]; then cetak_pesan "$KUNING" " ├─ [SKIP] DoH whitelist dinonaktifkan" return 0 fi cetak_pesan "$HIJAU" " ├─ Mengunduh DoH/DoT whitelist..." if curl -k -s --connect-timeout 30 --max-time 120 "$URL_DOH_WHITELIST" -o "$TMP_DOH_WHITELIST.raw"; then # Validasi file bukan HTML if head -20 "$TMP_DOH_WHITELIST.raw" | grep -qi " "$TMP_COMBINED_WHITELIST" local total=$(wc -l < "$TMP_COMBINED_WHITELIST") cetak_pesan "$ABUABU" " │ └─ Total whitelist gabungan: $total domain" else touch "$TMP_COMBINED_WHITELIST" cetak_pesan "$KUNING" " │ └─ [WARN] Tidak ada whitelist untuk digabungkan" fi } # Fungsi utama untuk membersihkan blacklist dari whitelist # Menggunakan metode yang optimal berdasarkan ukuran file remove_whitelist_from_blacklist() { local blacklist_file="$1" local output_file="$2" if [[ ! -f "$TMP_COMBINED_WHITELIST" ]] || [[ ! -s "$TMP_COMBINED_WHITELIST" ]]; then cetak_pesan "$KUNING" " ├─ [SKIP] Tidak ada whitelist, blacklist tidak dimodifikasi" cp "$blacklist_file" "$output_file" return 0 fi local wl_count=$(wc -l < "$TMP_COMBINED_WHITELIST") local bl_count=$(wc -l < "$blacklist_file") cetak_pesan "$HIJAU" " ├─ Menghapus $wl_count domain whitelist dari $bl_count domain blacklist..." # Pilih metode berdasarkan ukuran file if [[ $wl_count -lt 100000 ]]; then # Metode AWK - optimal untuk whitelist kecil-medium cetak_pesan "$ABUABU" " │ ├─ Metode: AWK hash lookup" awk ' NR==FNR { whitelist[$0] = 1 next } { if (!($0 in whitelist)) { print $0 } } ' "$TMP_COMBINED_WHITELIST" "$blacklist_file" > "$output_file" elif [[ $wl_count -lt 500000 ]]; then # Metode GREP - optimal untuk whitelist medium-besar cetak_pesan "$ABUABU" " │ ├─ Metode: grep -vFxf" LC_ALL=C grep -vFxf "$TMP_COMBINED_WHITELIST" "$blacklist_file" > "$output_file" || true else # Metode COMM - optimal untuk file sangat besar (hemat memory) cetak_pesan "$ABUABU" " │ ├─ Metode: comm (memory efficient)" # Pastikan kedua file sudah sorted LC_ALL=C sort -u "$blacklist_file" -o "$blacklist_file.sorted" LC_ALL=C comm -23 "$blacklist_file.sorted" "$TMP_COMBINED_WHITELIST" > "$output_file" rm -f "$blacklist_file.sorted" fi local new_count=$(wc -l < "$output_file") local removed=$((bl_count - new_count)) cetak_pesan "$HIJAU_TUA" " │ └─ Hasil: $removed domain dihapus, tersisa $new_count domain" } #=============================================================================== # FUNGSI GENERATOR RPZ #=============================================================================== # Fungsi untuk mengunduh dan memproses TrustPositif generate_trustpositif_rpz() { cetak_pesan "$HIJAU" "[1/3] Memproses TrustPositif Blacklist..." # Unduh data TrustPositif cetak_pesan "$HIJAU" " ├─ Mengunduh data TrustPositif..." if ! curl -k -s --connect-timeout 30 --max-time 300 "$URL_TRUSTPOSITIF" -o "$TMP_TRUSTPOSITIF.raw"; then cetak_pesan "$MERAH" "[ERROR] Gagal mengunduh data TrustPositif." exit 1 fi # Validasi file if head -20 "$TMP_TRUSTPOSITIF.raw" | grep -qi "> "$TMP_DOH_WHITELIST" 2>/dev/null || true fi # Buat combined whitelist if [[ -f "$TMP_DOH_WHITELIST" ]]; then LC_ALL=C sort -u "$TMP_DOH_WHITELIST" -o "$TMP_COMBINED_WHITELIST" else touch "$TMP_COMBINED_WHITELIST" fi # Hapus domain whitelist dari blacklist remove_whitelist_from_blacklist "$TMP_TRUSTPOSITIF" "$TMP_TRUSTPOSITIF_CLEAN" # Konversi ke format RPZ cetak_pesan "$HIJAU" " ├─ Mengonversi ke format RPZ..." { generate_rpz_header awk -v cname="$CNAME_TRUSTPOSITIF" ' { print $1 " 3600 IN CNAME " cname print "*." $1 " 3600 IN CNAME " cname }' "$TMP_TRUSTPOSITIF_CLEAN" } > "$FILE_TRUSTPOSITIF" local final_count=$(wc -l < "$TMP_TRUSTPOSITIF_CLEAN") cetak_pesan "$HIJAU" " └─ [OK] TrustPositif RPZ: $final_count domain aktif" } # Fungsi untuk mengunduh dan memproses Whitelist (untuk RPZ passthru) generate_whitelist_rpz() { cetak_pesan "$HIJAU" "[2/3] Memproses Whitelist RPZ..." cetak_pesan "$HIJAU" " ├─ Mengunduh data Whitelist..." if ! curl -k -s --connect-timeout 30 --max-time 120 "$URL_WHITELIST" -o "$TMP_WHITELIST.raw"; then cetak_pesan "$MERAH" "[ERROR] Gagal mengunduh data Whitelist." exit 1 fi # Bersihkan whitelist clean_domain_file "$TMP_WHITELIST.raw" "$TMP_WHITELIST" "whitelist RPZ" cetak_pesan "$HIJAU" " ├─ Mengonversi ke format RPZ passthru..." { generate_rpz_header awk '/^[a-zA-Z0-9.-]+$/ { print $1 " 3600 IN CNAME rpz-passthru." print "*." $1 " 3600 IN CNAME rpz-passthru." }' "$TMP_WHITELIST" } > "$FILE_WHITELIST" local wl_count=$(wc -l < "$TMP_WHITELIST") cetak_pesan "$HIJAU" " └─ [OK] Whitelist RPZ: $wl_count domain passthru" } # Fungsi untuk mengunduh dan memproses SafeSearch generate_safesearch_rpz() { cetak_pesan "$HIJAU" "[3/3] Memproses Google SafeSearch..." cetak_pesan "$HIJAU" " ├─ Mengunduh Google SafeSearch domains..." if ! curl -k -s --connect-timeout 30 --max-time 60 "$URL_SAFESEARCH" | grep -oE '([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}' > "$TMP_SAFESEARCH"; then cetak_pesan "$MERAH" "[ERROR] Gagal mengunduh Google SafeSearch domains." exit 1 fi cetak_pesan "$HIJAU" " ├─ Mengonversi ke format RPZ..." { generate_rpz_header awk -v cname="$CNAME_SAFESEARCH" '/^[^#]/ {print $1 " 3600 IN CNAME " cname}' "$TMP_SAFESEARCH" } > "$FILE_SAFESEARCH" local ss_count=$(wc -l < "$TMP_SAFESEARCH") cetak_pesan "$HIJAU" " └─ [OK] SafeSearch RPZ: $ss_count domain" } # Fungsi untuk memeriksa file zona check_zone_files() { cetak_pesan "$CYAN" "Memeriksa validitas file zona..." for file in "$FILE_TRUSTPOSITIF" "$FILE_WHITELIST" "$FILE_SAFESEARCH"; do zone_name=$(basename "$file" .zones).zone if ! named-checkzone "$zone_name" "$file" > /dev/null 2>&1; then cetak_pesan "$MERAH" "[ERROR] Kesalahan dalam file zona $zone_name." exit 1 fi cetak_pesan "$ABUABU" " ├─ $zone_name: OK" done cetak_pesan "$HIJAU" " └─ Semua file zona valid" } # Fungsi untuk me-reload BIND9 reload_bind9() { cetak_pesan "$CYAN" "Me-reload BIND9 untuk menerapkan perubahan..." # Gunakan rndc jika tersedia, karena lebih cepat daripada systemctl if command -v rndc > /dev/null 2>&1; then if rndc reload > /dev/null 2>&1; then cetak_pesan "$HIJAU" "[BERHASIL] BIND9 berhasil di-reload menggunakan rndc." else cetak_pesan "$MERAH" "[ERROR] Gagal me-reload BIND9 menggunakan rndc." exit 1 fi elif command -v systemctl > /dev/null 2>&1; then if systemctl reload bind9 > /dev/null 2>&1; then cetak_pesan "$HIJAU" "[BERHASIL] BIND9 berhasil di-reload menggunakan systemctl." else cetak_pesan "$MERAH" "[ERROR] Gagal me-reload BIND9 menggunakan systemctl." exit 1 fi else cetak_pesan "$MERAH" "[ERROR] Tidak dapat menemukan perintah 'rndc' atau 'systemctl'." exit 1 fi } # Fungsi untuk menampilkan ringkasan show_summary() { echo "" echo -e "${CYAN}============================================================================${RESET}" echo -e "${CYAN} RINGKASAN UPDATE ${RESET}" echo -e "${CYAN}============================================================================${RESET}" if [[ -f "$TMP_TRUSTPOSITIF_CLEAN" ]]; then local tp_count=$(wc -l < "$TMP_TRUSTPOSITIF_CLEAN") echo -e " ${PUTIH}TrustPositif Blacklist : ${HIJAU}$tp_count${PUTIH} domain${RESET}" fi if [[ -f "$TMP_WHITELIST" ]]; then local wl_count=$(wc -l < "$TMP_WHITELIST") echo -e " ${PUTIH}Whitelist Passthru : ${HIJAU}$wl_count${PUTIH} domain${RESET}" fi if [[ -f "$TMP_SAFESEARCH" ]]; then local ss_count=$(wc -l < "$TMP_SAFESEARCH") echo -e " ${PUTIH}Google SafeSearch : ${HIJAU}$ss_count${PUTIH} domain${RESET}" fi if [[ -f "$TMP_COMBINED_WHITELIST" ]]; then local combined=$(wc -l < "$TMP_COMBINED_WHITELIST") echo -e " ${PUTIH}Domain Whitelist Total : ${KUNING}$combined${PUTIH} (dihapus dari blacklist)${RESET}" fi echo -e "${CYAN}============================================================================${RESET}" echo -e " ${PUTIH}Waktu selesai: ${HIJAU}$(date '+%Y-%m-%d %H:%M:%S')${RESET}" echo -e "${CYAN}============================================================================${RESET}" } # Fungsi utama main() { local start_time=$(date +%s) cetak_pesan "$CYAN" "MEMULAI PEMBARUAN DATABASE DNS..." echo "" generate_trustpositif_rpz || exit 1 echo "" generate_whitelist_rpz || exit 1 echo "" generate_safesearch_rpz || exit 1 echo "" check_zone_files || exit 1 echo "" cetak_pesan "$HIJAU" "[BERHASIL] Semua file zona berhasil diperbarui dan diverifikasi." # Me-reload BIND9 reload_bind9 # Tampilkan ringkasan show_summary local end_time=$(date +%s) local elapsed=$((end_time - start_time)) cetak_pesan "$HIJAU" "Total waktu eksekusi: ${elapsed} detik" } # Jalankan fungsi utama main