Belajar RoadRunner - Keamanan & Hardening
Episode 17 of 26

Belajar RoadRunner - Keamanan & Hardening

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.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

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.

Membatasi Request

Batas dasar yang harus selalu ada:

Batas request dan upload
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
ProteksiFungsi
max_request_sizeTolak request dengan body melebihi limit (KB) — lawan upload raksasa
uploads.forbidBlokir ekstensi berbahaya dari file upload
max_worker_memoryBatasi memori worker; worker yang bocor direstart
max_jobsRestart berkala worker untuk memutus leak

Request Timeout

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:

Batasi durasi task
pool:
  num_workers: 8
  supervisor:
    exec_ttl: 30
    exec_ttl_jobs: 100
    idle_ttl: 60
    ttl: 0
KeyArti
exec_ttlBatas waktu satu task (detik) — lewat batas, worker di-recycle
exec_ttl_jobsBatas waktu khusus jobs (detik)
idle_ttlWorker idle di-recycle setelah N detik
ttlUmur maksimum worker (detik); 0 = tanpa batas

Dengan exec_ttl, request yang menggantung tidak akan menghabiskan worker selamanya — supervisor memotongnya dan mengganti worker.

Rate Limiting

Plugin http.rate_limit (berbasis Redis) membatasi request per detik:

Rate limit HTTP
http:
  middleware: ["rate_limit"]
  rate_limit:
    per_second: 100
    burst: 200
  • per_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.

Memproteksi Endpoint API

Pola proteksi API yang umum — autentikasi bearer token via middleware PSR-15:

Bearer token auth
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.

Mengamankan RPC dan File Sensitif

Port RPC adalah permukaan serang terbesar yang sering dilupakan:

RPC hanya untuk localhost
rpc:
  listen: tcp://127.0.0.1:6001

Aturan hardening RPC:

LangkahAlasan
Listen hanya 127.0.0.1Blokir akses dari jaringan lain
Atau pakai Unix socketunix://rr.sock — hanya proses lokal dengan izin filesystem
Jangan expose di proxyReverse proxy tidak perlu meneruskan port RPC
Batasi user yang bisa menulis configConfig 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:

Proteksi izin file
chmod 600 .rr.yaml

dan jangan pernah me-commit secret ke git (gunakan environment variable / secret manager, tema episode 18).

Checklist Hardening

ItemStatus aman
max_request_size dibatasiYa
exec_ttl aktif di supervisorYa
Rate limit aktifYa
Endpoint API memakai authYa
RPC hanya localhost / unix socketYa
.rr.yaml izin 600 dan tanpa secret di gitYa
Port gRPC/HTTP tidak terbuka ke publik tanpa proteksiYa

Penutup

Pada episode 17 ini, kalian telah mengeraskan RoadRunner.

Inti yang harus dibawa pulang:

  • Batasi max_request_size dan ekstensi upload.
  • supervisor.exec_ttl memutus request yang menggantung.
  • Rate limit di level Go untuk dasar, di PHP untuk per-endpoint.
  • Proteksi API dengan token + hash_equals.
  • RPC hanya localhost/Unix socket; config di-protect izin dan secret.

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!

Belajar RoadRunner - Keamanan & Hardening | Belajar RoadRunner