Belajar Swoole - Keamanan Server & Hardening
Episode 17 of 26

Belajar Swoole - Keamanan Server & Hardening

Mengamankan server Swoole: input validation di layer server, pembatasan koneksi dengan max_conn dan timeout, heartbeat untuk membunuh koneksi basi, serta strategi proteksi terhadap Slowloris dan connection flooding.

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

Pendahuluan

Setelah di episode 16 kita membangun microservices — pada episode kali ini kita berhenti sejenak dari membangun fitur dan mengamankan apa yang sudah kita bangun. Server Swoole adalah server jaringan publik: ia terhubung langsung ke internet, dan karena itu menjadi sasaran serangan yang jauh lebih beragam daripada PHP-FPM yang bersembunyi di balik Nginx.

Mengapa episode ini penting? Dua alasan. Pertama, Swoole biasanya dipakai tanpa web server di depan (bukan di balik Nginx), jadi semua pertahanan menjadi tanggung jawab kalian. Kedua, serangan yang menargetkan koneksi (Slowloris, flooding) persis menyerang titik yang menjadi keunggulan Swoole — dan menutupnya adalah skill wajib.

Prinsip Pertahanan Berlapis

Jangan harap satu konfigurasi menyelesaikan semuanya. Lapisi tiga layer:

100%
LayerFungsiContoh
1. InfrastrukturFiltering di depanFirewall, Cloudflare, rate limit LB
2. SwooleBatasan koneksi & waktumax_conn, heartbeat, timeout
3. AplikasiValidasi logikaInput validation, auth, business rules

Episode ini fokus pada layer 2 dan 3.

Input Validation di Layer Server

Setiap input dari client adalah tidak tepercaya. Validasi sebelum menyentuh logika bisnis:

Validasi input di handler
$server->on('Request', function (Request $req, Response $res) {
    $id = $req->get['id'] ?? null;
 
    if ($id === null || !ctype_digit($id) || (int)$id > PHP_INT_MAX) {
        $res->status(400);
        $res->end('Invalid id');
        return;
    }
 
    $name = $req->post['name'] ?? '';
    if (mb_strlen($name) > 255 || mb_strlen($name) < 2) {
        $res->status(422);
        $res->end('Nama harus 2-255 karakter');
        return;
    }
 
    // ... lanjut proses
});

Aturan praktis:

  • Whitelist, bukan blacklist — terima pola yang valid, tolak sisanya.
  • Batasi panjang input (package_max_length, dan cek strlen di kode).
  • JSON: json_decode selalu cek json_last_error().
  • Jangan pernah meng-echo input mentah ke response (XSS) atau ke query SQL (injection).

Batasan Koneksi: max_conn dan Timeout

Swoole menyediakan pembatas yang menghentikan serangan di gerbang:

Hardening konfigurasi server
$server = new Server('0.0.0.0', 9501);
$server->set([
    'max_conn'              => 10000,   // batas koneksi total
    'heartbeat_check_interval' => 30,   // cek tiap 30 detik
    'heartbeat_idle_time'      => 120,  // tutup koneksi idle > 120 detik
    'package_max_length'       => 2 * 1024 * 1024, // batas paket 2MB
    'buffer_output_size'       => 4 * 1024 * 1024, // batas output 4MB
    'open_tcp_keepalive'       => true,
    'dispatch_mode'            => 3,
]);
SetelanMelindungi dari
max_connConnection flooding — menolak koneksi melebihi batas
heartbeat_idle_timeKoneksi basi & Slowloris — koneksi yang "setengah hidup" dibunuh
package_max_lengthRequest raksasa / buffer overflow
buffer_output_sizeResponse membengkak (memory exhaustion)
open_tcp_keepaliveDead peer di sisi TCP

Warning

heartbeat_idle_time membunuh koneksi yang tidak mengirim apa pun. Hati-hati: WebSocket idle (user yang tidak mengetik) juga akan diputus. Solusinya heartbeat ping/pong dari episode 6 — kirim ping berkala sehingga koneksi tidak pernah tampak idle. Jangan aktifkan heartbeat buta pada server WebSocket.

Proteksi Slowloris

Slowloris adalah serangan yang membuka banyak koneksi lalu mengirim data sangat pelan (misal 1 byte per menit) untuk menahan resource server selama mungkin. Pertahanan utamanya:

  1. max_conn — membatasi total koneksi yang bisa ditahan attacker.
  2. heartbeat_check_interval + heartbeat_idle_time — koneksi yang menahan request sebagian (header belum lengkap) tidak akan mengirim data dalam interval waktu tertentu → diputus.
  3. Timeout operasi — atur batas waktu baca/tulis socket:
Timeout socket untuk Slowloris
$server->set([
    'socket_buffer_size'  => 2 * 1024 * 1024,
    'socket_read_timeout' => 10,   // 10 detik untuk membaca
    'socket_write_timeout' => 10,  // 10 detik untuk menulis
]);

Dengan timeout ini, koneksi yang mengirim setengah request lebih dari 10 detik akan diputus oleh kernel/swoole — persis serangan yang coba ditahan Slowloris.

Proteksi Connection Flooding

Connection flooding (SYN flood / banyak koneksi cepat) ditangani berlapis:

Deteksi dan tolak flooding
$server->on('Connect', function ($server, $fd, $reactorId) {
    $ip = $server->getClientInfo($fd)['remote_ip'] ?? 'unknown';
    if (isFlooding($ip)) {
        $server->close($fd); // tolak cepat
    }
});

Kombinasi terbaik untuk flooding:

  • Firewall/infra: iptables rate limit, Cloudflare, atau LB — layer 1 paling efektif.
  • max_conn: batas keras total koneksi.
  • backlog: ukuran antrian koneksi pending.
  • Aplikasi: rate limit per IP (kita bangun dengan Table di episode 12) untuk request-level.

Praktik: Konfigurasi Hardening Lengkap

server-hardened.php
<?php
use Swoole\Http\Server;
use Swoole\Http\Request;
use Swoole\Http\Response;
 
$server = new Server('0.0.0.0', 9501);
$server->set([
    'worker_num'            => swoole_cpu_num(),
    'max_conn'              => 10000,
    'dispatch_mode'         => 3,
    'package_max_length'    => 2 * 1024 * 1024,
    'buffer_output_size'    => 4 * 1024 * 1024,
    'heartbeat_check_interval' => 30,
    'heartbeat_idle_time'      => 120,
    'socket_read_timeout'   => 10,
    'socket_write_timeout'  => 10,
    'open_tcp_keepalive'    => true,
    'backlog'               => 512,
]);
 
$server->on('Request', function (Request $req, Response $res) {
    $path = $req->server['request_uri'] ?? '/';
    $allowed = ['/health', '/api/users'];
 
    if (!in_array($path, $allowed, true)) {
        $res->status(404);
        $res->end('Not Found');
        return;
    }
 
    $res->end('OK');
});
 
$server->start();

Setelan ini bisa kalian jadikan template dasar produksi — kita akan mengevaluasi ulang trade-off-nya di episode 20 (performance tuning).

Common Pitfalls

MasalahPenyebabSolusi
WebSocket user terputusHeartbeat salah konfigurasiAktifkan ping/pong aplikasi agar koneksi aktif
Request valid ditolakmax_conn terlalu kecilUkur beban puncak, naikkan batas
Timeout pemrosesan lamasocket_read/write_timeout terlalu ketatSesuaikan dengan latensi upstream (bukan request ringan)
Rate limit bypassLimit per IP dihapus karena worker bedaPakai Swoole\Table (episode 12) — shared lintas worker

Penutup

Pada episode 17 ini, kalian telah mengamankan server Swoole.

Inti yang harus dibawa pulang:

  • Pertahanan berlapis: firewall/LB → config Swoole → kode aplikasi.
  • Input validation di layer server: whitelist, batasi panjang, cek JSON.
  • max_conn, heartbeat, dan socket timeout melawan Slowloris & flooding.
  • Heartbeat + ping/pong WebSocket harus seimbang agar user valid tidak terputus.
  • Rate limit per IP dengan Table adalah pertahanan layer aplikasi.

Di episode 18 selanjutnya, kita mengunci jalur data: TLS/SSL, HTTPS & WSS — konfigurasi sertifikat di HTTP/WebSocket server dan redirect HTTP ke HTTPS. Sampai jumpa di episode 18!

Belajar Swoole - Keamanan Server & Hardening | Belajar Swoole