Mengeraskan RoadRunner untuk produksi: membatasi ukuran request dan jumlah worker, menetapkan request timeout, menerapkan rate limiting, memproteksi endpoint API, serta mengamankan RPC dan file config dari akses tidak sah.

Setelah di episode 15-16 kita mengamankan jalur komunikasi dan membuka gRPC, pada episode kali ini kita mengeraskan aplikasi dan server itu sendiri. Keamanan RoadRunner bukan hanya soal TLS — melainkan membatasi resource yang bisa dikonsumsi satu request, menahan lonjakan request, dan memastikan jalur administrasi (RPC, config) tidak mudah diserang.
Mengapa episode ini penting? Karena app server yang selalu-hidup adalah target yang lebih besar daripada PHP-FPM: ia mendengarkan banyak port, menjalankan proses yang kalian kontrol, dan menyimpan semua konfigurasi infrastruktur. Satu celah bisa memberi attacker akses ke worker PHP itu sendiri.
Batas dasar yang harus selalu ada:
http:
address: 0.0.0.0:8080
max_request_size: 1024
uploads:
dir: /tmp/uploads
forbid: [".php", ".exe", ".bat", ".sh"]
pool:
max_worker_memory: 128
max_jobs: 1000| Proteksi | Fungsi |
|---|---|
max_request_size | Tolak request dengan body melebihi limit (KB) — lawan upload raksasa |
uploads.forbid | Blokir ekstensi berbahaya dari file upload |
max_worker_memory | Batasi memori worker; worker yang bocor direstart |
max_jobs | Restart berkala worker untuk memutus leak |
Worker PHP bisa hang — koneksi DB yang membeku, loop tanpa henti. Tanpa timeout, worker macet selamanya dan pool kehabisan worker. supervisor.exec_ttl membatasi durasi satu task:
pool:
num_workers: 8
supervisor:
exec_ttl: 30
exec_ttl_jobs: 100
idle_ttl: 60
ttl: 0| Key | Arti |
|---|---|
exec_ttl | Batas waktu satu task (detik) — lewat batas, worker di-recycle |
exec_ttl_jobs | Batas waktu khusus jobs (detik) |
idle_ttl | Worker idle di-recycle setelah N detik |
ttl | Umur maksimum worker (detik); 0 = tanpa batas |
Dengan exec_ttl, request yang menggantung tidak akan menghabiskan worker selamanya — supervisor memotongnya dan mengganti worker.
Plugin http.rate_limit (berbasis Redis) membatasi request per detik:
http:
middleware: ["rate_limit"]
rate_limit:
per_second: 100
burst: 200per_second: jumlah request rata-rata yang diizinkan per detik.burst: lonjakan sesaat yang diizinkan sebelum pembatasan.Untuk kontrol per-endpoint, lakukan di level aplikasi (middleware PSR-15 yang memakai counter KV Redis, episode 8 & 10). Rate limit di level Go melindungi server; di level aplikasi melindungi resource spesifik (misal endpoint login).
Tip
Rate limit API yang sensitif (login, OTP, upload) lebih ketat dari endpoint publik. Kombinasikan: rate limit global di Go untuk dasar, lalu limit per-user/per-IP di middleware PHP dengan KV Redis.
Pola proteksi API yang umum — autentikasi bearer token via middleware PSR-15:
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$header = $request->getHeaderLine('Authorization');
if (!preg_match('/^Bearer (.+)$/', $header, $m)) {
return new Response(401, [], '{"error":"missing token"}');
}
$token = $m[1];
if (!hash_equals($this->apiKeys[$token] ?? '', $token)) {
return new Response(401, [], '{"error":"invalid token"}');
}
return $handler->handle($request->withAttribute('api_key', $token));
}Catatan keamanan: pakai hash_equals() untuk perbandingan token (constant-time), jangan === yang rentan timing attack.
Port RPC adalah permukaan serang terbesar yang sering dilupakan:
rpc:
listen: tcp://127.0.0.1:6001Aturan hardening RPC:
| Langkah | Alasan |
|---|---|
Listen hanya 127.0.0.1 | Blokir akses dari jaringan lain |
| Atau pakai Unix socket | unix://rr.sock — hanya proses lokal dengan izin filesystem |
| Jangan expose di proxy | Reverse proxy tidak perlu meneruskan port RPC |
| Batasi user yang bisa menulis config | Config mengontrol server.command — siapa pun yang bisa mengubahnya bisa mengeksekusi kode |
File config juga sensitif: .rr.yaml boleh berisi secret (password Redis, key SQS). Pastikan:
chmod 600 .rr.yamldan jangan pernah me-commit secret ke git (gunakan environment variable / secret manager, tema episode 18).
| Item | Status aman |
|---|---|
max_request_size dibatasi | Ya |
exec_ttl aktif di supervisor | Ya |
| Rate limit aktif | Ya |
| Endpoint API memakai auth | Ya |
| RPC hanya localhost / unix socket | Ya |
.rr.yaml izin 600 dan tanpa secret di git | Ya |
| Port gRPC/HTTP tidak terbuka ke publik tanpa proteksi | Ya |
Pada episode 17 ini, kalian telah mengeraskan RoadRunner.
Inti yang harus dibawa pulang:
max_request_size dan ekstensi upload.supervisor.exec_ttl memutus request yang menggantung.hash_equals.Di episode 18 selanjutnya, kita belajar CVE & dependency management — memahami rilis patch keamanan RoadRunner v2025.1.x (CVE-2026-32280, CVE-2026-42504, dan lainnya), pola upgrade rutin, dan pengelolaan dependensi yang aman. Sampai jumpa di episode 18!