Lewati ke konten

Shield Corev1.2.x

Verifikasi Crawler

Setiap request bisa mengaku apa saja. User-Agent: Googlebot/2.1 bisa dikirim oleh script mana pun dalam satu baris kode.

Jadi Shield tidak percaya User-Agent. Ia mencari bukti.

Klaim: User-Agent mengandung "googlebot"
IP: 66.249.66.1
1. Apakah IP ini ada di CIDR yang terdaftar untuk googlebot?
Tidak → 2.
2. Reverse DNS: 66.249.66.1 → crawler.googlebot.com
Tidak berakhiran .googlebot.com atau .google.com? → gagal
3. Forward-confirm: crawler.googlebot.com → 66.249.66.1
Tidak balik ke IP yang sama? → gagal
Lolos.

Langkah 3 itu yang disebut forward-confirm, dan itulah yang membuat verifikasi inilirata. Reverse DNS saja bisa dipalsukan: penyerang tinggal memesan hostname_ptr untuk IP-nya sendiri.

Dengan forward-confirm, penyerang harus mengontrol DNS dan A record-nya. Untuk IP di datacenter, itu bukan sesuatu yang bisa dilakukan diam-diam.

namespace Ganadev\Shield\Core\Trust;
interface CrawlerVerifierInterface
{
public function verify(string $claimedAgent, string $ip): ?string;
}

Return value-nya sederhana:

Nilai Arti
Nama agent Bot terverifikasi.
null Tidak terverifikasi.

BehaviorDetector membandingkan hasilnya dengan nama yang diklaim:

return $this->crawlerVerifier->verify($claimedAgent, $ip) === $claimedAgent;

Perbandingan itu disengaja. Kalau adapter mengembalikan nama berbeda, hasilnya dianggap gagal.

Sembilan bot punya hostname yang diverifikasi:

Agent Hostname yang diterima
googlebot .googlebot.com, .google.com
bingbot .search.msn.com
yandexbot .yandex.ru, .yandex.net
baiduspider .baidu.com, .baidu.jp
duckduckbot .duckduckgo.com
ahrefsbot .ahrefs.com
semrushbot .semrush.com
dotbot .moz.com
ccbot .cc

Tujuh belas nama agent lain ada di bots.known_agents untuk deteksi, termasuk gptbot, claudebot, chatgpt-user, bytespider, dan perplexitybot — tapi kebanyakan tidak punya hostname yang diverifikasi.

Ini bukan kekurangan. Bot AI tidak mengiklankan infrastruktur seperti itu, jadi tidak ada yang bisa dibuktikan. Lihat bagian bot AI di bawah.

'bots' => [
'mode' => 'observe',
],
Mode Yang terjadi pada klaim yang gagal diverifikasi
off Diabaikan sepenuhnya.
observe Dicatat, tapi tidak pernah menaikkan keputusan menjadi terminal.
challenge Dinaikkan jadi CHALLENGE, kalau keputusan sebelumnya bukan terminal.

Ini detail yang sering terlewat, dan ini alasan utama mode observe ada.

Tanpa pengecualian, crawler sah yang reverse-DNS-nya bermasalah akan mendapat skor tinggi hanya karena jumlah request. Di mode observe Shield menurunkannya kembali:

} elseif ($config->botMode === BOT_OBSERVE
&& $activeBan === null
&& $breakdown->matchedRuleIds === []
&& $behaviorReport->has(SIGNAL_UNVERIFIED_CRAWLER_CLAIM)
&& $verdict->decision->isTerminal()) {
// turunkan ke OBSERVE
}

Tiga syarat harus terpenuhi: tidak ada ban aktif, tidak ada rule yang cocok, dan skornya naik murni dari perilaku.

Kalau ada rule sensitive.env yang cocok, crawler tetap diblokir. Pengecualian ini hanya berlaku untuk lonjakan traffic.

Mengapa ini penting: hilangnya Googlebot dari indeks Anda jauh lebih sulit dideteksi daripada beberapa request yang lolos. Banyak orang tidak sadar situsnya tidak terindeks selama berbulan-bulan.

Kalau DNS tidak tersedia sama sekali — kontainer tanpa resolver, lingkungan pengujian, DNS server sedang mati — tidak ada yang bisa diverifikasi. Dalam keadaan itu, hanya CIDR yang bisa mengonfirmasi bot.

Untuk itu ada bots.verification.ip_ranges:

'bots' => [
'verification' => [
'ip_ranges' => [
'googlebot' => ['66.249.64.0/19', '66.249.128.0/17'],
],
],
],

CIDR dicek lebih dulu, sebelum reverse-DNS. Jadi kalau IP bot Anda memang diastikan stabil, ini cara paling murah dan paling handal.

CIDR selalu per-IP, jadi jangan pakai /0 atau blok yang terlalu luas. Salah satu entri yang terlalu longgar sama saja dengan tidak memakai verifikasi.

Hasil verifikasi disimpan per IP selama bots.verification.ttl_hours, yang bawaannya 24 jam. Artinya satu crawler hanya memicu satu kali lookup DNS per hari.

Nilai negatif juga di-cache. Kalau IP tidak bisa diverifikasi, hasilnya none dan tidak perlu lookup lagi selama 24 jam ke depan.

Reverse-DNS bisa lambat atau tidak menjawab sama sekali. Setiap adapter perlu menetapkan batas waktu sendiri, karena Core tidak tahu apa itu timeout di sistem Anda.

Di Laravel, ini diatur lewat SHIELD_BOTS_VERIFY_TIMEOUT (default 2 detik). Kalau DNS server Anda lambat, naikkan sedikit. Kalau tidak, satu lookup yang menggantung akan menahan request.

Bot AI tidak punya infrastruktur yang bisa dibuktikan. gptbot dikirim dari AWS, tapi tidak ada hostname reverse yang stabil dan tidak ada dokumen resmi yang bisa dijadikan dasar verifikasi.

Verifikasi otomatis akan selalu gagal untuk mereka, dan konsekuensinya:

  • bots.mode = challenge → diblokir dengan challenge, berulang kali.
  • bots.mode = observe → aman, hanya tercatat.

Bot AI ini tidak menghiraukan robots.txt. Kalau Anda tidak ingin mereka mengindeks situs, blokir di CDN atau reverse proxy — bukan di Shield.

Contoh untuk Nginx:

# Bot AI yang tidak Anda kehendaki
if ($http_user_agent ~* "(gptbot|claudebot|CCBot|bytespider|perplexitybot)") {
return 403;
}

Daftar lengkap agen AI ada di bots.known_agents.

Kalau Anda punya layanan yang memang perlu mengindeks situs Anda:

'bots' => [
'known_agents' => ['googlebot', 'bidabot', 'tokenbot'],
'verification' => [
'hostnames' => [
// nama bot => suffix hostname yang sah
'bidabot' => ['.bidswitch.net'],
'tokenbot' => ['.tokenbot.com'],
],
'ip_ranges' => [
'bidabot' => ['198.2.0.0/16'],
],
],
],

Tambahkan juga ke bots.known_agents, kalau tidak classifyCrawler() tidak pernah memanggil verifier untuk nama itu.

  1. Cek log. Cari unverified_crawler_claim_ followed by nama bot.
  2. Kalau muncul unverified_crawler_claim_unknown, User-Agent-nya tidak ada di known_agents.
  3. Kalau nama bot muncul tapi verifikasi gagal, masalahnya DNS: PTR salah, forward-confirm tidak cocok, atau resolver tidak bisa menjawab.
  4. Sementara, tambahkan CIDR ke bots.verification.ip_ranges. Itu lebih baik daripada mematikan bots.mode.

Powered by PT Ganadev Multi Solusi