CodeIgniter 4 Shieldv1.2.x
Instalasi
Panduan ini mengantar Anda dari aplikasi CodeIgniter 4 yang masih polos sampai CodeIgniter 4 Shield aktif sebelum router dan mencatat kejadian, dalam sekitar 15 menit.
Yang Anda butuhkan
Section titled “Yang Anda butuhkan”- PHP
^8.2atau lebih baru - Composer
- CodeIgniter 4 4.7.5 (baseline yang didokumentasikan)
- Database yang sudah terhubung ke aplikasi Anda
Langkah 1 — Pasang paketnya
Section titled “Langkah 1 — Pasang paketnya”composer require ganadev/codeigniter4-shieldcodeigniter4-shield menarik ganadev/shield-core secara otomatis, jadi Anda tidak perlu memasang core sendiri.
Langkah 2 — Daftarkan service provider
Section titled “Langkah 2 — Daftarkan service provider”CodeIgniter 4 tidak menemukan service provider secara otomatis seperti Laravel, jadi satu baris kecil perlu ditambahkan. Buka app/Config/Events.php dan tambahkan:
Events::on('pre_system', static function (): void { \Ganadev\Shield\Codeigniter\ShieldServiceProvider::register();});Satu baris ini mendaftarkan tiga hal:
- Service Shield — engine, resolver, cache, dan driver challenge.
- Alias filter
shield.firewall. - Filter firewall — ditempatkan di
globals['before']secara default.
Penting: globals['before'] berjalan setelah router. Artinya request ke path
yang tidak punya route (mis. /.env, /wp-login.php, atau path acak) tidak
diperiksa oleh filter default. Langkah 3 dan 4 memindahkan Shield ke
required['before'] agar request 404/scanner tetap diperiksa sebelum router —
itu setup default yang dipakai dokumentasi ini. Detail urutan filternya ada di
Registrasi & Urutan Filter.
Kalau Anda sengaja ingin memakai filter global saja, Langkah 4 boleh dilewati. Konsekuensinya: path tanpa route tidak akan diperiksa Shield.
Panggilan berulang aman — provider membangun ulang service dari konfigurasi terkini setiap kali.
Perintah php spark shield:* tidak perlu didaftarkan manual. Kalau aplikasi
punya app/Config/Commands.php, provider mendaftarkan command ke sana. Kalau
tidak (appstarter CI4 umumnya tidak punya file itu), CodeIgniter menemukannya
otomatis dengan memindai namespace PSR-4 package.
Langkah 3 — Siapkan konfigurasi dan path publik
Section titled “Langkah 3 — Siapkan konfigurasi dan path publik”Shield sudah punya nilai default yang aman. Namun gateSkipPaths adalah array
dan tidak bisa diatur lewat .env, jadi buat app/Config/Shield.php minimal
seperti ini:
<?php
namespace Config;
class Shield extends \Ganadev\Shield\Codeigniter\Config\Shield{ public string $appId = 'my-app';
/** * Path publik yang tetap diperiksa Shield, tetapi tidak menambah behavior * counter saat diakses normal dengan GET/HEAD. * * Ini bukan daftar bypass. Ban, challenge, dan rule enforcement tetap * berlaku. * * @var list<string> */ public array $gateSkipPaths = [ '/', '/health', '/robots.txt', '/sitemap.xml', '/favicon.ico', ];}Sesuaikan daftar path dengan halaman publik aplikasi Anda. Jangan masukkan endpoint yang menangani data sensitif atau submit form.
Untuk nilai scalar, cukup tambahkan ke .env dengan prefix huruf kecil.
CodeIgniter 4 memetakannya otomatis lewat BaseConfig:
shield_mode = observeshield_appId = my-appshield_challengeDriver = nullJangan memakai SHIELD_MODE atau SHIELD_CHALLENGE; nama uppercase itu tidak
dibaca otomatis untuk properti config. Penjelasan lengkap ada di
Environment & .env.
Langkah 4 — Jalankan Shield sebelum router
Section titled “Langkah 4 — Jalankan Shield sebelum router”Langkah ini membuat Shield berjalan sebelum router, termasuk untuk request yang tidak punya route. Lakukan ketiga bagian berikut sebelum menyalakan ulang aplikasi.
4.1 Buat ShieldGateFilter
Section titled “4.1 Buat ShieldGateFilter”Buat app/Filters/ShieldGateFilter.php. Kode lengkapnya ada di
Registrasi & Urutan Filter — Buat ShieldGateFilter.
Salin seluruh kelas, bukan hanya method before().
Filter ini bertugas:
- menjalankan
SecurityFirewallFiltersebelum router, - mengembalikan behavior counter untuk halaman publik yang diizinkan,
- tetap menegakkan ban/challenge yang sudah ada,
- menghitung 404 sebelum router lewat
after().
4.2 Daftarkan alias dan posisi filter
Section titled “4.2 Daftarkan alias dan posisi filter”Di app/Config/Filters.php, tambahkan alias dan tempatkan shield.gate di
required:
use App\Filters\ShieldGateFilter;
public array $aliases = [ // ... 'shield.gate' => ShieldGateFilter::class,];
public array $required = [ 'before' => [ 'forcehttps', // hapus kalau aplikasi tidak memakai ForceHTTPS 'shield.gate', // Shield sebelum router 'pagecache', // hapus kalau aplikasi tidak memakai PageCache ], 'after' => [ 'pagecache', 'performance', 'toolbar', 'shield.gate', // hitung 404 sebelum router ],];Pertahankan filter lain yang sudah ada di aplikasi Anda. Urutan
forcehttps → shield.gate → pagecache penting: PageCache tidak boleh berjalan
sebelum Shield.
4.3 Hapus shield.firewall dari global filter
Section titled “4.3 Hapus shield.firewall dari global filter”Provider menambahkan shield.firewall ke globals['before']. Karena sekarang
Shield dipanggil lewat shield.gate, hapus penempatan global itu agar request
tidak diperiksa dua kali. Edit app/Config/Events.php:
Events::on('pre_system', static function (): void { \Ganadev\Shield\Codeigniter\ShieldServiceProvider::register();
/* * Provider memasang Shield sebagai filter global, yang berjalan setelah * routing. Kita memakai App\Filters\ShieldGateFilter di required filter * agar path tanpa route juga diperiksa. Hapus yang global supaya request * tidak diperiksa dua kali. */ $filters = config('Filters');
$filters->globals['before'] = array_values(array_filter( $filters->globals['before'] ?? [], static fn ($alias): bool => $alias !== 'shield.firewall', ));});Kalau app/Config/Events.php Anda sudah berisi kode lain, gabungkan potongan di
atas dengan isi yang sudah ada; jangan menimpa seluruh file.
Langkah 5 — Jalankan migrasi
Section titled “Langkah 5 — Jalankan migrasi”php spark migrate --allPerintah ini membuat dua tabel:
| Tabel | Isi |
|---|---|
security_ip_bans |
Ban aktif dan riwayat durasi. |
security_events |
Catatan setiap peristiwa keamanan. |
Langkah 6 — Atur proxyIPs
Section titled “Langkah 6 — Atur proxyIPs”Ini bagian penting: semua penghitung dan ban berbasis IP klien. Kalau aplikasi di belakang proxy/load balancer (termasuk Cloudflare), isi proxyIPs di app/Config/App.php dengan format asosiatif (IP/Subnet → Header).
Format yang benar sejak CI4 4.3 adalah array asosiatif
(CIDR => header):
public array $proxyIPs = [ // Cloudflare IPv4 '173.245.48.0/20' => 'CF-Connecting-IP', '103.21.244.0/22' => 'CF-Connecting-IP', '103.22.200.0/22' => 'CF-Connecting-IP', '103.31.4.0/22' => 'CF-Connecting-IP', '141.101.64.0/18' => 'CF-Connecting-IP', '108.162.192.0/18' => 'CF-Connecting-IP', '190.93.240.0/20' => 'CF-Connecting-IP', '188.114.96.0/20' => 'CF-Connecting-IP', '197.234.240.0/22' => 'CF-Connecting-IP', '198.41.128.0/17' => 'CF-Connecting-IP', '162.158.0.0/15' => 'CF-Connecting-IP', '104.16.0.0/13' => 'CF-Connecting-IP', '104.24.0/14' => 'CF-Connecting-IP', '172.64.0.0/13' => 'CF-Connecting-IP', '131.0.72.0/22' => 'CF-Connecting-IP',
// Cloudflare IPv6 '2400:cb00::/32' => 'CF-Connecting-IP', '2606:4700::/32' => 'CF-Connecting-IP', '2803:f800::/32' => 'CF-Connecting-IP', '2405:b500::/32' => 'CF-Connecting-IP', '2405:8100::/32' => 'CF-Connecting-IP', '2a06:98c0::/29' => 'CF-Connecting-IP', '2c0f:f248::/32' => 'CF-Connecting-IP',];Kalau Anda tidak memakai Cloudflare, ganti dengan CIDR proxy Anda sendiri. Daftar resmi Cloudflare ada di https://www.cloudflare.com/ips/.
Langkah 7 — Penyesuaian opsional
Section titled “Langkah 7 — Penyesuaian opsional”Nonaktifkan cache konfigurasi
Section titled “Nonaktifkan cache konfigurasi”Saat mengembangkan config, nonaktifkan cache di app/Config/Optimize.php agar
perubahan tidak tertahan cache:
public bool $configCacheEnabled = false;public bool $locatorCacheEnabled = false;Ini tidak menghapus kebutuhan restart php spark serve; server built-in adalah
satu proses panjang dan .env sudah dimuat saat proses mulai.
Route challenge sudah otomatis
Section titled “Route challenge sudah otomatis”Route shield/challenge dan shield/challenge/verify dimuat dari
Config/Routes.php paket. Jangan menambahkan route manual dengan nama controller
yang berbeda; route bawaan memakai method GET dan POST serta nama controller
yang benar.
Challenge membutuhkan HTTPS
Section titled “Challenge membutuhkan HTTPS”Cookie trusted pada ChallengeController selalu memakai secure: true. Di HTTP
murni, CodeIgniter dapat melempar SecurityException saat response dikirim.
Gunakan HTTPS untuk challenge, atau driver null selama development lokal.
Langkah 8 — Jalankan dan periksa
Section titled “Langkah 8 — Jalankan dan periksa”php spark servePeriksa urutan filter terlebih dahulu:
php spark filter:check GET /Yang diharapkan: forcehttps → shield.gate → pagecache (sesuaikan dengan filter
yang benar-benar dipakai aplikasi Anda). Kalau shield.gate tidak muncul,
periksa kembali Langkah 4.
Lalu periksa apakah semua komponen sehat:
php spark shield:healthPerintah ini memeriksa koneksi database, cache, mesin Shield, konfigurasi trusted proxy, dan resolusi DNS untuk verifikasi crawler.
Langkah 9 — Jadwalkan pembersihan
Section titled “Langkah 9 — Jadwalkan pembersihan”shield:prune menghapus event lama, ban berstatus released yang sudah lewat
expiry, dan semua baris berstatus expired. Ban active yang sudah melewati
expires_at tidak diubah oleh perintah ini. Tidak ada scheduler bawaan di
CodeIgniter, jadi host Anda yang menjalankan. Tambahkan cron berikut:
* * * * * cd /path/ke/aplikasi && php spark shield:prune >> /dev/null 2>&1Tanpa cron itu, tabel security_events akan tumbuh tanpa batas.
Langkah 10 — Aktivasi bertahap
Section titled “Langkah 10 — Aktivasi bertahap”Jangan langsung masuk ke mode enforce. Urutan yang aman:
- Mode
observeselama 1–3 hari. Shield mencatat, tidak memblokir. - Baca
shield:report. Cari rule yang sering memicu tanpa alasan, atau IP asli yang ikut tercatat. - Naikkan
modekechallenge. Pantau apakah pengunjung bisa lolos. - Naikkan
modekeenforce. Lakukan setelah false positive terkendali. - Atur durasi ban.
banDurationsdibaca sesuai urutan offense;escalationStepmenambah skor risiko, bukan memperpanjang durasi ban.
Setiap tahap, periksa event blokir/ban dan lakukan manual release bila ada
pengunjung asli yang ikut kena. Tidak ada metrik “challenge pass rate” di
shield:report; gunakan laporan event dan log aplikasi.
Kalau saya memakai auth resmi CI4?
Section titled “Kalau saya memakai auth resmi CI4?”Filter Shield bekerja apa adanya, tanpa bergantung pada paket auth apa pun. Paket auth resmi (codeigniter4/shield) hanya diperlukan kalau Anda ingin memakai panel admin dengan pembatasan izin.
Langkah berikutnya
Section titled “Langkah berikutnya”- Registrasi & Urutan Filter — penjelasan mendalam soal urutan filter, counter publik, dan PageCache.
- Environment & .env — panduan env-driven dan config siap-tempel.
- Konfigurasi — semua opsi yang bisa Anda ubah.
- Masalah Umum — kalau ada yang tidak beres.
- Perintah Spark — cara melihat apa yang terjadi.
Powered by PT Ganadev Multi Solusi