# Shield Guard — paket pembaruan untuk Zenith

Isi folder ini siap dipasang ke `ahyat786/Zenith-App`. Semuanya sudah
diuji, bukan sekadar disalin.

| Berkas | Tujuan | Ukuran |
| --- | --- | --- |
| `default_blocklist.txt` | ganti `rust/zenith-core/src/default_blocklist.txt` | 4,3 MB · 215.448 host |
| `urlpattern-rules.txt` | lapisan baru, pemblokiran berbasis jalur URL | 35 baris |
| `cosmetic-rules.txt` | lapisan baru, penyembunyian elemen lewat CSS | 45 baris |
| `shield-dns.yaml` | blok DNS untuk Clash / Mihomo | 5,6 kB |
| `build-blocklist.py` | membangun ulang daftar dari sumbernya | — |
| `verifikasi.py` | menguji daftar memakai tiruan mesin Rust | — |

---

## 1. Daftar blokir

Digabung dari enam sumber publik, semuanya berhasil diambil:

| Sumber | Host baru |
| --- | --- |
| Turtlecute Host List | 129 |
| AdGuard DNS filter | 182.374 |
| StevenBlack unified hosts | 70.951 |
| AdAway | 16 |
| someonewhocares.org | 32 |
| Peter Lowe (bawaan Pi-hole) | 13 |

Gabungan mentah 253.515 host, lalu **diruntuhkan menjadi 215.448 domain
induk**. Peruntuhan ini memanfaatkan perilaku `should_block_host()` di
`adblock.rs` yang mencocokkan sufiks: satu baris `doubleclick.net` sudah
memblokir seluruh subdomainnya, jadi `ad.doubleclick.net` tidak perlu
ikut ditulis.

Penguraiannya meniru persis `parse_hosts_line()` dan `is_domain()` milik
Anda, termasuk penolakan alamat IP serta string bermuatan `/` dan `:`.
Aturan AdBlock bermodifier bersyarat sengaja dilewati karena mesin
berbasis hosts tidak bisa mewakilinya.

### Pengecualian dibagi dua

Ini bagian yang sempat salah dan sudah diperbaiki. Melindungi
`google.com` ternyata ikut melindungi `adservice.google.com`, sehingga
empat host iklan lolos pada pengujian pertama.

- **AMAN_POHON** — domain beserta seluruh subdomainnya tidak pernah
  diblokir. Hanya untuk infrastruktur murni: `googleapis.com`,
  `gstatic.com`, CDN, bank Indonesia, WhatsApp, Telegram, dan domain
  Anda sendiri.
- **AMAN_PERSIS** — hanya host itu sendiri yang dilindungi.
  `google.com` bisa dibuka, tetapi `adservice.google.com` tetap
  diblokir.

### Hasil pengujian

```
Host termuat : 215448
Harus diblokir      : 49/49 terblokir
Tidak boleh diblokir : 24/24 aman
SEMUA LOLOS
```

Jalankan ulang kapan saja:

```bash
python3 build-blocklist.py   # ambil ulang dari sumber, bangun daftar
python3 verifikasi.py        # uji dengan tiruan mesin Rust
```

### Catatan ukuran

Daftar ini tertanam di biner lewat `include_str!`. Teks 4,3 MB akan
menambah sekitar 600 kB pada APK setelah dikompresi, dan memakai kira
kira 10 MB memori saat `HashSet` dibangun. Masih wajar untuk peramban,
tetapi bila ingin APK lebih ramping, kecilkan daftar bawaan lalu biarkan
pengguna mengimpor daftar besar lewat `load_user_list()` yang sudah ada.

---

## 2. Dua uji yang tidak mungkin lolos dengan hosts saja

Pada tangkapan layar Anda, dua uji gagal: **Cosmetic Filter** dan **Ad
Script**. Keduanya **tidak akan pernah lolos** hanya dengan daftar hosts,
sebanyak apa pun isinya. Situs ujinya sendiri menyatakan hal itu:

> a hosts file cannot pass the cosmetic filter or ad script checks

Alasannya sederhana. Permintaan yang diuji adalah
`adblock.turtlecute.org/pagead.js` — host-nya sama dengan situs yang
sedang dibuka. Kalau host itu diblokir, seluruh situs ikut mati. Yang
harus dicocokkan adalah **jalur** URL-nya, bukan host.

Karena itu disertakan dua lapisan baru:

**`urlpattern-rules.txt`** — dicocokkan di dalam
`shouldInterceptRequest` sebelum pemeriksaan host. Sudah memuat dua
aturan yang persis diminta situs uji: `/pagead.js` dan `/widget/ads.`

**`cosmetic-rules.txt`** — disuntikkan sebagai CSS. Zenith sudah punya
jalurnya di `extension.rs` lewat field `css` pada `content_scripts`;
muat berkas ini dengan `matches: ["<all_urls>"]` dan
`run_at: "document_start"`. Sudah memuat keempat selektor uji:
`.adbox`, `.banner_ads`, `.adsbox`, `.textads`

Dengan ketiga lapisan aktif, keempat uji di adblock.turtlecute.org
seharusnya hijau.

---

## 3. Konfigurasi DNS

`shield-dns.yaml` memuat `fallback-filter` **persis** seperti yang Anda
kirim: `geoip: true`, `geoip-code: ID`, 16 baris `ipcidr`, dan 10 baris
`domain`. Diverifikasi jumlahnya cocok.

Server ditambah menjadi dua pasang seperti diminta, plus AdGuard:

| Grup | Alamat | Port | Jenis |
| --- | --- | --- | --- |
| NameServer | dns.quad9.net/dns-query | 443 | HTTPS |
| NameServer | 9.9.9.9 | 853 | TLS |
| NameServer | dns.adguard-dns.com/dns-query | 443 | HTTPS |
| NameServer | 94.140.14.14 | 853 | TLS |
| FallBack | dns.quad9.net/dns-query | 443 | HTTPS |
| FallBack | 149.112.112.112 | 853 | TLS |
| FallBack | dns.adguard-dns.com/dns-query | 443 | HTTPS |
| FallBack | 94.140.14.15 | 853 | TLS |

Keempat DoT saya uji soketnya terbuka. Kedua DoH saya uji dengan query
DNS wire-format dan keduanya menjawab 200 berisi jawaban yang sah.
AdGuard terbukti memblokir: `doubleclick.net` dan
`pagead2.googlesyndication.com` hanya mengembalikan satu jawaban
(0.0.0.0), sedangkan `example.com` mengembalikan dua.

### Soal hostname di Connection log

Permintaan Anda adalah agar Connection log menampilkan hostname, bukan
IP. `fallback-filter` sendiri tidak melakukan itu. Yang menentukan
adalah dua setelan berikut, dan keduanya sudah diaktifkan:

- `enhanced-mode: fake-ip` — klien menerima IP semu sehingga nama domain
  tetap tercatat pada koneksi.
- `sniffer` dengan `force-dns-mapping` dan `parse-pure-ip` — membaca SNI
  dari TLS dan header Host dari HTTP, sehingga aplikasi yang menghubungi
  IP langsung pun tetap terbaca nama domainnya.

### GEOIP dan GEOSite

Dipakai `geodata-mode: true` dengan sumber `meta-rules-dat`, yang memuat
kategori global maupun kode negara `ID`. Pembaruan otomatis tiap 24 jam.
Aturan bawaannya: `GEOSITE,category-ads-all,REJECT` untuk memblokir
iklan, lalu `GEOIP,ID,DIRECT` supaya trafik Indonesia tetap langsung.

Daftar Turtlecute dipasang sebagai `rule-provider` yang memperbarui
dirinya tiap hari, bukan disalin manual.

---

## Cara memasang

```bash
git clone https://github.com/ahyat786/Zenith-App
cd Zenith-App
cp /path/ke/default_blocklist.txt rust/zenith-core/src/default_blocklist.txt
cargo test -p zenith-core      # uji parser bawaan Anda tetap hijau
./gradlew assembleRelease
```

`urlpattern-rules.txt` dan `cosmetic-rules.txt` perlu sedikit kode baru
karena lapisannya memang belum ada. Beri tahu saya bila ingin saya
tuliskan modul Rust dan pemanggilnya di Kotlin.
