TABALONG SENTINEL
Dokumen Teknis · Cara Kerja

Arsitektur &
cara kerja di balik layar.

Bagaimana sistem menemukan, memindai, menilai, dan memberi peringatan — secara otomatis, asinkron, dan modular.

Python 3.12 FastAPI · Celery · Redis PostgreSQL React SPA Docker · Dokploy
Fondasi Teknologi

Komponen yang menyusun sistem.

FastAPI

REST API async + auth Cloudflare Access (JWT) di tiap route.

api

Celery + Redis

Antrian job & penjadwal (beat). Worker memproses scan paralel.

worker · beat

PostgreSQL

SQLAlchemy async + Alembic. Scan, verdict, incident, audit.

db

httpx + render

Fetch HTTP async (dual-UA) + screenshot via headless render.

scan

React SPA

Dashboard operator: status, riwayat, insiden, tuning bobot.

web

Docker · Dokploy

5 container, deploy via registry + Traefik (TLS Let's Encrypt).

deploy

Loki + Grafana

structlog → Loki → dashboard. Metrik antrian tiap 30 detik.

observability

Kualitas kode

mypy strict, ruff, pytest + testcontainers (Postgres asli).

CI
Arsitektur Tingkat Tinggi

Aliran data dari penjadwal sampai peringatan.

01 · ORKESTRASIPenjadwalan & antrian
Beat · penjadwal Redis · 4 antrian per-tier Celery Workers ×4
02 · PIPELINEPemindaian satu situs
Probe + Fetch dual-UA Detektor (paralel) Scoring Verdict
03 · PENYIMPANANPersistensi
PostgreSQL · scan · verdict · incident + Blob store · HTML & screenshot
04 · KELUARANInsiden & antarmuka
Incident engine Alert · Telegram · WhatsApp · Email · Grafana | FastAPI ⇄ Dashboard

Sumber target: Cloudflare DNS API + Certificate Transparency logs (discovery tiap 30 menit).

Topologi Layanan

Lima container, satu image.

API, worker, dan beat berbagi image yang sama — hanya beda perintah start. Postgres & Redis sebagai infrastruktur stateful.

api

FastAPI/uvicorn (2 worker). Jalankan alembic upgrade head saat boot. Di-route Traefik (HTTPS).

worker

Celery, concurrency 4. Berlangganan semua antrian tier + default. Menjalankan pipeline scan.

beat

Penjadwal Celery. Memicu scan per-tier, discovery, escalation, digest, metrik.

postgres

PostgreSQL 16. Volume persisten. Healthcheck pg_isready.

redis

Redis 7 (AOF). Broker antrian Celery + backend hasil + metrik.

healthcheck per-service restart: unless-stopped migrasi otomatis saat boot
Mesin Penjadwalan

Beat memicu scan per-tier ke antrian terpisah.

KritisLayanan vital (pajak, kependudukan, perizinan) — interval terpendeksetiap 5 menit → scan_critical
TinggiLayanan publik utamasetiap 15 menit → scan_high
NormalSitus informasi umumsetiap 1 jam → scan_normal
RendahSitus internal / jarang berubahsetiap 6 jam → scan_low
discovery · 30 mnt onboard · 30 mnt escalation sweep · 1 mnt queue metrics · 30 dtk email digest · 15 mnt / harian
Anatomi Satu Scan

Yang terjadi saat satu situs dipindai.

1
Buat record scan
Status RUNNING + idempotency key (anti-duplikat per menit).
2
Kumpulkan data (paralel)
Probe jaringan (DNS/TLS/ASN) bersamaan dengan fetch HTTP dual-UA.
3
Triage keterjangkauan
Gerbang #1: jika tak terjangkau → lewati detektor, tetap tetapkan severity.
4
Jalankan detektor
Muat baseline, lalu semua detektor jalan paralel (asyncio.gather).
5
Hitung verdict
Rata-rata berbobot dari confidence → skor → tingkat keparahan.
6
Enrichment (bersyarat)
Gerbang #2: detektor eksternal hanya bila skor ≥ mencurigakan.
7
Simpan & perbarui
Verdict, bukti, snapshot HTML/PNG, baseline, status subdomain.
8
Proses insiden
IncidentDispatcher menentukan: buka / gabung / tutup → antre alert.
Pengumpulan Data

Dua permintaan, satu trik anti-cloaking.

Setiap halaman diambil dengan dua identitas sekaligus, dan jaringan diperiksa paralel — semua tanpa memberatkan situs target.

UA "Pengunjung"

Fetch sebagai browser biasa (Chrome). Inilah yang dilihat publik.

User-Agent: Chrome

UA "Googlebot"

Fetch sebagai bot Google. Perbedaan = indikasi cloaking.

User-Agent: Googlebot

Network probe

Resolusi DNS, sertifikat TLS, dan ASN — dijalankan paralel dengan fetch.

DNS · TLS · ASN

Batas aman: timeout 15 dtk, maks 5 redirect, body dipotong di 5 MB — agar scan ringan & tidak mengganggu.

Efisiensi: Two-Stage Gating

Dua gerbang yang menghemat sumber daya.

Tidak semua langkah dijalankan untuk semua situs. Dua gerbang memastikan kerja mahal hanya dilakukan saat perlu.

GERBANG #1 · REACHABILITY TRIAGE

Situs hidup atau mati?

Jika situs tak terjangkau (down / error jaringan), detektor konten dilewati — percuma menganalisis halaman kosong. Severity dasar tetap ditetapkan.

skip_detectors → hemat CPU & waktu
GERBANG #2 · ENRICHMENT GATE

Perlu cek pihak ketiga?

Layanan eksternal (Safe Browsing, urlscan, VirusTotal) ber-kuota terbatas. Hanya dipanggil bila verdict dasar sudah ≥ mencurigakan.

severity ≥ SUSPICIOUS → baru jalan
Battery Detektor

Antarmuka seragam, banyak detektor.

class Detector(ABC): name: str default_weight: int = 10 async def analyse(fetch, context): # → DetectorSignal( # confidence: 0–100, # evidence: {...} )

Pluggable: tambah detektor = tambah satu class. Pipeline menjalankan semuanya paralel.

judol_keyword — leksikon judi outbound_link — link + blocklist cloaking_diff — UA normal vs bot dom_hash_diff — defacement visual_hash_diff — hash gambar js_pattern — skrip berbahaya form_heuristics — phishing tls_cert_drift — sertifikat safe_browsing — Google urlscan — urlscan.io virustotal — VirusTotal + mudah ditambah

8 detektor konten (tiap scan)  ·  3 detektor enrichment (bersyarat)

Scoring → Verdict

Banyak sinyal jadi satu keputusan.

Tiap detektor memberi confidence 0–100. Sistem menghitung rata-rata berbobot → satu skor → dipetakan ke tingkat keparahan. Bobot dapat ditala operator.

AMAN
WASPADA
TINGGI
KRITIS
0255080100
< 25 — clean ≥ 25 — suspicious ≥ 50 — high ≥ 80 — critical
Baseline & Deteksi Perubahan

Mengenali "normal", lalu mendeteksi penyimpangan.

Saat sebuah situs pertama kali bersih, sistem merekam "sidik jari" kondisi normalnya. Scan berikutnya membandingkan terhadap baseline ini.

Yang direkam sebagai baseline

DOM hash (struktur halaman), visual phash (rupa screenshot), daftar link keluar, dan profil jaringan (DNS/TLS/ASN).

Yang memicu sinyal

Struktur DOM berubah drastis (defacement), tampilan berbeda, link baru mencurigakan, atau sertifikat/server berpindah tak wajar.

Cerdas terhadap perubahan sah. Saat sertifikat TLS diperbarui wajar (penerbit sama) dan hasil scan bersih, baseline jaringan dirotasi otomatis — mengurangi alarm palsu.

Lifecycle Insiden

Verdict → keputusan insiden.

Setiap hasil scan diproses oleh IncidentDispatcher menjadi salah satu aksi berikut — dengan dedup agar tidak banjir insiden.

CLEANAuto-resolve. Insiden terbuka ditutup otomatis setelah beberapa scan bersih berturut-turut.
SUSPICIOUSNo-op. Dicatat untuk analitik, tetapi belum dijadikan insiden (mengurangi noise).
HIGH / CRITICALOpen / Append. Buka insiden baru atau gabung ke yang terbuka; deteksi kenaikan severity → antre alert.
dedup per-subdomain deteksi upgrade severity mute notifikasi per-situs
Routing Peringatan

Severity menentukan saluran.

SeverityTelegramWhatsAppEmailGrafana / Loki
CRITICAL
HIGH
SUSPICIOUS
escalation sweep tiap 1 menit email digest 15 mnt + harian 06:00 saluran bisa di-on/off operator
Discovery & Auto-Onboard

Subdomain baru terdaftar & terklasifikasi sendiri.

1
Temukan
Cloudflare DNS API + Certificate Transparency logs, tiap 30 menit.
2
Klasifikasi tier
classify_tier(nama) berbasis pola nama → kritis/tinggi/normal/rendah.
3
Onboard
Liveness probe → situs hidup dipromosikan NEW → ACTIVE otomatis.

Hormati keputusan manusia. Klasifikasi otomatis ditandai tier_source = auto. Begitu operator mengubah tier manual, otomatisasi tidak akan menimpanya lagi.

Observability & Operasi

Sistem yang bisa diawasi dirinya sendiri.

Log terstruktur

structlog (JSON) dikirim ke Loki, divisualkan di dashboard Grafana.

Metrik antrian

Kedalaman tiap antrian Celery dipush tiap 30 detik untuk pantau beban.

Healthcheck

API (HTTP), worker (celery ping), beat (mtime jadwal) — dicek berkala.

FP suggestion

Mesin usulan false-positive membantu operator menekan alarm palsu.

Regression fixture

Kasus nyata otomatis jadi PR fixture uji — mencegah regresi deteksi.

Weight tuning + backtest

Operator menala bobot detektor, lalu uji dampaknya pada data lampau.

Deploy & CI/CD

Dari merge ke produksi, otomatis.

1
GitHub Actions
Setiap merge ke main: build image Docker (tag :latest + :sha).
2
Push ke registry
Ke registry.tabalongkab.go.id via Tailscale (subnet router internal).
3
Dokploy deploy
Webhook memicu pull image baru + restart container.
4
Traefik + TLS
Reverse-proxy + sertifikat Let's Encrypt → sentinel.tabalongkab.go.id.
auth: Cloudflare Access (JWT) migrasi DB otomatis saat boot zero-downtime restart
Prinsip Desain

Asinkron, modular,
dapat diamati.

Asinkron menyeluruh

asyncio + Celery: ratusan situs dipindai paralel tanpa saling menunggu.

Modular & pluggable

Detektor sebagai class terpisah — mudah menambah deteksi baru.

Efisien

Two-stage gating: kerja mahal hanya saat benar-benar perlu.

Otomatis ujung-ke-ujung

Discovery → scan → insiden → alert, tanpa intervensi manual.

Tabalong Sentinel · dokumen teknis

01 / 17
atau scroll untuk berpindah