1 poin oleh GN⁺ 2024-03-31 | 1 komentar | Bagikan ke WhatsApp
  • TablePlus terus memantau kondisi server meski ada upaya DDoS yang berlangsung selama beberapa minggu, tanpa memblokir IP atau mengaktifkan mode “Under Attack” Cloudflare
  • Upaya pengunduhan file instalasi dalam 30 hari terakhir mencapai sekitar 6 juta kali, dan 800.126 kali hanya dalam 5 hari terakhir; ukuran file sekitar 200MB per unduhan
  • Bahkan saat serangan berlangsung, penggunaan CPU server sebagian besar tetap di 0–1%, dan sekitar 8 layanan API beserta database dikonfigurasi untuk menangani puluhan miliar request per bulan tanpa cache
  • Backend dikelompokkan sebagai layanan monolitik per aplikasi, dan satu binary dideploy ke VPS baru tanpa Docker, Kubernetes, atau lingkungan runtime
  • Konfigurasi sederhana seperti framework Go/Rust, indexing database, pemisahan database log, reverse proxy Nginx, Cloudflare CDN/R2, dan throttling pengiriman email menurunkan biaya serangan serta kompleksitas operasional

Upaya DDoS yang Berlangsung Selama Beberapa Minggu

  • Seseorang mengirim ratusan juta request ke server TablePlus selama beberapa minggu dan mencoba mengunduh file instalasi jutaan kali
  • Upaya pengunduhan file instalasi mencapai 800.126 kali dalam 5 hari terakhir, dan sekitar 6 juta kali dalam 30 hari terakhir
    • Ukuran file instalasi sekitar 200MB per unduhan
  • Berdasarkan panggilan API dalam 30 hari terakhir, sebagian besar traffic berasal dari EU, terutama Germany dan United Kingdom
    • Angka ini tidak mencakup request unduhan dan traffic CDN
  • Pada saat tulisan ini dibuat, serangan masih berlangsung

Respons Nyata: Struktur yang Bertahan, Bukan Memblokir

  • Tidak memblokir alamat IP penyerang
  • Menggunakan Cloudflare, tetapi tidak mengaktifkan mode “Under Attack”
  • Bahkan saat serangan berlangsung, CPU server sebagian besar hampir idle di kisaran 0–1%
  • Karena layanan dapat menangani puluhan miliar request per bulan tanpa masalah dan beban biaya juga tidak besar, hampir tidak ada tindakan khusus yang dilakukan

Desain Backend yang Sederhana

  • Desain aplikasi TablePlus berorientasi pada kesederhanaan, dan layanan backend juga dijaga agar tetap dalam konfigurasi seminimal mungkin
  • Layanan rendering pihak ketiga seperti Vercel atau Netlify tidak digunakan karena dapat menimbulkan bottleneck atau tagihan tak terduga saat terjadi serangan
  • Dengan memakai web server sendiri, batasan seperti itu dianggap dapat dihindari
  • Di masa lalu, monolith bisa menjadi bottleneck karena VPS dan prosesor yang lemah, tetapi VPS saat ini menyediakan CPU multicore, RAM besar, dan SSD cepat
    • SSD dan RAM yang cepat sangat meningkatkan performa database
    • Jika diimplementasikan dengan benar, layanan monolith pada satu instance pun dapat menangani puluhan miliar request per bulan

Cara Operasi Monolith per Aplikasi

  • API, website, email, pembayaran, dan kebutuhan lain untuk tiap aplikasi digabungkan ke dalam satu layanan
  • Deployment selesai hanya dengan satu file konfigurasi, build, dan deploy
  • Saat memindahkan layanan ke vendor cloud lain atau melakukan deployment baru, prosesnya dapat dilakukan dengan cepat
  • Dengan dependensi yang sedikit, debugging dan identifikasi bottleneck menjadi mudah
    • Meski terjadi error, layanan yang perlu diperiksa hanya satu atau segelintir
  • Contoh framework monolith yang dapat dipilih adalah sebagai berikut
    • Golang: Echo, Gin
    • PHP: Laravel
    • Ruby: Rails
    • Rust: Actix, Rocket, Warp

Prinsip Konfigurasi untuk Puluhan Miliar Request per Bulan

  • Memilih web framework berperforma tinggi; TablePlus lebih memilih Golang dan Rust
  • Seiring dataset membesar, index disetel pada database untuk mengurangi waktu query
  • Untuk melindungi performa bisnis inti, database utama dipisahkan dari database log dan penggunaan
    • Database utama digunakan untuk data yang tidak berubah atau ukurannya tidak bertambah seiring waktu
    • Database log dan penggunaan digunakan untuk data yang terus bertambah seiring waktu
  • Reverse proxy ditempatkan di depan API inti untuk menangani dan mendistribusikan request
    • Ini membantu jika diperlukan beberapa server
    • TablePlus menggunakan Nginx
  • Semua ditempatkan di belakang Cloudflare, dengan cache, Argo, dan full SSL antara Cloudflare dan server dikonfigurasi secara tepat
  • Menggunakan CDN yang memiliki perlindungan DDoS
    • TablePlus lebih memilih Cloudflare R2 dan CDN dibanding Amazon CloudFront + S3 demi penghematan biaya dan perlindungan
  • Jika file unduhan besar ditempatkan di VPS tanpa CDN atau caching, bandwidth akan cepat habis
    • TablePlus menggunakan Cloudflare CDN dengan bandwidth tak terbatas
    • Jika Argo diaktifkan pada domain yang sama, traffic Cloudflare CDN dapat melewati Argo, dan bandwidth Argo tidak gratis sehingga biaya bisa membesar
  • Request yang mengharuskan server mengirim email, seperti pemulihan kata sandi, melindungi mailer dengan throttling

Cara Deployment: Menjalankan Binary tanpa Container

  • TablePlus menjaga proses deployment sesederhana mungkin tanpa Docker, Kubernetes, container, atau pengaturan lingkungan runtime terpisah
  • Unit deployment adalah binary
    • Disalin ke server Linux lalu dijalankan sebagai proses
    • Dipandang mirip dengan cara menjalankan aplikasi TablePlus di macOS
  • Linux Systemctl dapat diberi tanggung jawab untuk memantau proses dan melakukan restart jika terjadi error fatal
  • Dijalankan secara native agar CPU/RAM tidak terbuang pada lapisan perantara seperti VM, virtualisasi, atau pengelola infrastruktur pihak ketiga
  • Go dan Rust dipilih karena merupakan bahasa berperforma tinggi dan dapat menghasilkan file binary untuk deployment

Fitur Perlindungan yang Perlu Diaktifkan saat Menggunakan Vercel

  • Dalam situasi seperti ini, Vercel menyediakan fitur untuk melindungi situs, yaitu Spend Management dan Attack Challenge Mode
    • Spend Management: dapat menetapkan batas pengeluaran soft atau hard
    • Attack Challenge Mode: mirip dengan mode “Under Attack” Cloudflare
  • Jika menggunakan Vercel, fitur-fitur tersebut perlu diaktifkan

1 komentar

 
GN⁺ 2024-03-31
Opini Hacker News
  • Tulisan ini terasa terlalu berlebihan dalam memuji diri sendiri. “1 miliar request per bulan” hanya beberapa ratus request per detik, jadi skalanya sepele, dan sulit juga menyebutnya DDoS
    Selain itu, situsnya berada di belakang Cloudflare, sebuah CDN, jadi makin sulit dipahami mengapa ini dianggap melakukan sesuatu yang hebat dari sudut pandang performa
    Misalnya, tidak ada situasi yang masuk akal di mana file 200MB tidak di-cache dan disajikan oleh CDN. Tidak perlu bangga karena server aplikasi tidak membaca 200MB dari disk dan menyalinnya ke klien setiap kali ada unduhan; kalau begitu, itu desain yang terlalu jelas buruk

    • Jika file 200MB yang dimaksud adalah unduhan aplikasi klien TablePlus di https://tableplus.com/download, versi Windows berukuran 183MB dan memang di-cache oleh Cloudflare

      # curl -v https://files.tableplus.com/windows/5.9.2/TablePlusSetup.exec > /dev/null

      < cache-control: max-age=691200

      < cf-cache-status: HIT

      < age: 2980

    • Bukankah ini biasanya jenis pekerjaan yang, kalau di perusahaan FAANG, dianggap membutuhkan 1.000+ developer? Saya tidak tahu bagaimana sesuatu yang bahkan perusahaan besar pun sering gagal melakukannya secara rutin bisa hanya disebut memuji diri sendiri

    • Sulit melihatnya hanya sebagai beberapa ratus request per detik. Kepadatan request tidak merata dari waktu ke waktu, dan sering bisa naik sampai 20 kali rata-ratanya

  • 4TB per bulan sebenarnya sulit disebut serangan DDoS, bukan? Kalau 4TB per jam, itu bisa disebut DDoS, tetapi 4TB per bulan hanya 1,5MB per detik
    6 juta request per bulan juga hanya 2 request per detik. Pada skala ini, fakta bahwa layanan berjalan sebagai monolit tampaknya tidak terlalu penting, apalagi jika Cloudflare menangani sebagian besar request lewat cache CDN

    • Mayoritas besar web adalah situs WordPress di hosting multi-tenant seharga 5–20 dolar per bulan, dan untuk organisasi yang lebih besar sering kali Drupal. Tanpa cache terpasang dan langsung terhubung ke database, sebagian besar situs di internet bisa tumbang hanya dengan 4 request per detik

      Ini terdengar gila, tapi itulah kenyataannya. Dulu saya mengelola pertahanan DDoS, WAF, firewall, dan proyek keamanan pelanggan di Cloudflare, dan saya sering melihat situs pelanggan tumbang hanya karena web scraping atau tingkat request HTTP yang sangat kecil dan rendah

      Angka besar memang jadi headline, tetapi yang benar-benar dirasakan kebanyakan orang adalah angka kecil

    • Serangan denial-of-service bisa dilakukan hanya dengan beberapa KB per jam. Jika menyentuh endpoint API yang berat pada layanan target, itu saja sudah bisa menjatuhkan layanan, dan Distributed hanya berarti beberapa mesin menyerang secara bersamaan

      DDoS tidak harus selalu membutuhkan throughput raksasa. Hanya saja yang biasanya muncul di berita adalah serangan besar

      Tujuan serangan seperti ini bisa jadi membakar kuota bandwidth server asal, atau membuat biaya bandwidth tidak tertanggung. Ini bisa dilakukan dengan sangat murah bahkan memakai satu atau segelintir mesin penyerang. Sebagian besar data center dan penyedia hosting punya batas bandwidth atau mengenakan biaya setelah jumlah tertentu, dan terlalu sering perusahaan yang diserang baru sadar setelah menerima tagihan yang tidak mampu mereka bayar

    • Saya punya situs unduhan game dengan total pemain sekitar 50 orang. Hampir tidak ada yang memakainya, dan orang sungguhan mungkin mengunduh gamenya hanya beberapa kali per bulan
      Namun dari satu file zip 2GB, bulan lalu muncul trafik 5TB, dan ini sudah berlangsung bertahun-tahun. Ini bukan DDoS, hanya bot/crawler yang salah konfigurasi, mengikuti semua tautan dan tidak bisa membatalkan unduhan

    • Sepertinya sekitar 1TB per hari, tetapi tetap saja itu sangat kecil

    • Sepertinya tergantung seberapa tidak teraturnya trafiknya

  • Ini hanya situs marketing statis untuk aplikasi desktop. Tidak ada forum diskusi, dan feedback ditangani lewat issue GitHub
    Cukup aneh membanggakan betapa sederhananya deployment situs marketing statis dan bahwa file statis tetap bertahan meski diunduh jutaan kali per hari. Dan yang melakukan mitigasi di sini adalah Cloudflare, bukan mereka. Itu pun kalau trafik sekecil ini memang butuh mitigasi

    Kalau saya menerima “serangan” seperti ini, mungkin saya bahkan tidak akan menyadarinya sampai menerima email bulanan dari Cloudflare yang berbunyi “X TB ditransfer, hampir 100% bandwidth dihemat”

    Aplikasinya sendiri saya suka dan layak direkomendasikan

    • Saya juga suka aplikasinya, tetapi tulisan ini terdengar seperti meminta ChatGPT membuat tulisan marketing yang tidak biasa. Secara keseluruhan kurang masuk akal, apalagi bagi orang yang pernah mengalami serangan DDoS sungguhan
    • Poin “membanggakan betapa sederhananya deployment” justru saya ingin lebih sering muncul. Semakin banyak orang menyadari bahwa infrastruktur mereka yang terlalu rumit bukanlah pilihan optimal, semakin baik
  • Ini lebih terlihat seperti “penyalahgunaan layanan yang menyebalkan dan tidak bermakna” dengan tambahan trafik sekitar 8TB per bulan, menurut penjelasannya, daripada serangan DDoS
    Selama penyalahgunaan seperti itu tidak menimbulkan masalah biaya atau kehabisan resource, tidak apa-apa diabaikan, tetapi cerita seperti “ternyata 80% kapasitas fleet auto-scaling tidak melakukan hal berguna apa pun” cukup sering terjadi sampai terasa menyedihkan, jadi setidaknya perlu dipantau

    Bagian paling menyebalkan dari penyalahgunaan seperti ini biasanya adalah log. Sebagian besar log dipenuhi host yang sama mengulangi tindakan tidak bermakna yang sama. Jika penyimpanan log murah dan lapang, itu bukan masalah besar, tetapi punya cara untuk otomatis mengklasifikasikan trafik tertentu sebagai penyalahgunaan dan menekan pemrosesan rutin jelas merupakan ide bagus

    Namun itu tidak semudah kedengarannya. Saya tidak bisa menghitung berapa kali saya menambahkan logika klasifikasi untuk menangkap penyalahgunaan yang terang-terangan dan bodoh pada server SMTP inbound, dan setiap kali selalu ada skenario yang berada di batas tetapi sebenarnya valid ikut terkena

    Kalau terlalu banyak waktu dihabiskan menyusuri rabbit hole beruntun, pekerjaan nyata mudah terbengkalai. Jadi kadang lebih baik mengalihdayakannya, atau jika itu pun terlalu merepotkan atau mahal, lebih baik mengabaikan penyalahgunaan meski menyebalkan

    • Di AWS, trafik keluar 8TB biayanya 595 dolar bahkan setelah memperhitungkan 1TB gratis per bulan, sedangkan di Hetzner mulai dari di bawah 10 dolar
      DigitalOcean, misalnya, mengenakan 30 dolar untuk kelebihan 3TB di atas 5TB yang termasuk pada s-4vcpu-8gb-intel, dan Linode mengenakan 15 dolar untuk kelebihan 3TB. Jadi menurut saya inti tulisannya ada benarnya
    • Kalau terus diabaikan, itu sama saja mendorong mereka melakukan hal yang lebih mencurigakan. Sikap seperti itu telah membuat internet saat ini nyaris menjadi rawa
  • Ini bukan “serangan” yang patut diperhatikan. Ini bisa saja dilakukan hanya dengan satu skrip bash yang mengamuk di mesin seseorang
    “50 juta permintaan per bulan dari Inggris” rata-ratanya bahkan tidak sampai 20 permintaan per detik. Saya akan berharap satu server Go saja bisa menangani 250 kali lipat jumlah permintaan itu tanpa optimasi besar

    Sarannya sendiri tidak selalu buruk, tetapi angka-angka itu bukan bukti untuk saran tersebut. Untuk layanan Go HTTP API, di VPS kecil hingga menengah, meski ada sedikit operasi database dan pemformatan JSON, saya akan berharap bisa menangani 5 ribu permintaan per detik tanpa optimasi. Angka ini berdasarkan pengalaman menerapkan puluhan layanan serupa di tempat yang menerima miliaran permintaan per hari dan saat puncak melampaui 500 ribu permintaan per detik

    • Jika trafik seperti itu membanjiri API sebagai permintaan berulang dan semuanya berasal dari lokasi yang tidak mencurigakan, hal pertama yang perlu dipikirkan bukan DDoS, melainkan apakah loop retry tak terbatas tanpa sengaja dimasukkan ke kode klien
  • Bagus kalau ini tidak menimbulkan kerusakan, tetapi untuk menjadikannya sebagai saran, ada terlalu banyak bagian yang hilang sehingga agak mengkhawatirkan
    Memilih distribusi biner dibanding Docker itu boleh saja, tetapi bagaimana dengan host tempat biner itu berjalan? Salah satu alasan memakai container adalah agar pengaturan hardening keamanan ikut dipaketkan dalam deployment, sehingga ketika nanti perlu melakukan scaling, kita yakin konfigurasi keamanan antar-node tetap sama

    Monolith yang dibicarakan di sini bisa ditempatkan di satu VPS, dan itu bagus sekaligus murah. Namun jika crash atau hardware gagal karena alasan apa pun, downtime-nya bisa cukup besar

    Kekhawatiran lain adalah jika semuanya digabung dalam monolith, kita kehilangan defense in depth pada stack aplikasi. Jika seseorang menembus aplikasi lewat frontend, ia bisa langsung mencapai penyimpanan data backend. Karena itu banyak orang menaruh penyimpanan data di balik layanan web internal dan memblokirnya dengan security group di jaringan privat yang terpisah dari frontend, sehingga attack surface dibatasi pada tindakan yang bisa dilakukan lewat browser

    • Tidak ada dunia di mana memperbesar attack surface membuat keamanan menjadi lebih baik

    • Kalau mengira memasang Docker berarti host otomatis diamankan, itu keliru. Saat scaling, bagaimana host tambahan akan dikonfigurasi?

      Kalau memakai Docker, bukan hanya container yang harus aman, tetapi juga host, yaitu layanan yang menjalankan container. Saat melakukan scaling dan menambahkan host, semuanya juga harus sama amannya

      Jika memakai infrastructure as code dan configuration as code, pada dasarnya tidak ada perbedaan berarti antara mendistribusikan biner setelah konfigurasi sistem atau mendistribusikan Docker

    • Ada alat yang membuat konfigurasi “bare metal” bisa direproduksi sampai tingkat tertentu. Contohnya NixOS, Ansible, dan build image Amazon AMI

    • Saya selalu tidak paham dengan ungkapan “menembus aplikasi lewat frontend”. SQL injection menyentuh penyimpanan data secara langsung tanpa remote code execution, dan XSS berdampak secara horizontal ke pengguna lain
      Lalu bagaimana caranya dari frontend bisa bebas mencapai seluruh backend? Apakah orang-orang menjalankan interpreter JavaScript yang punya akses shell di dalam layanan Go API lalu memanggil eval pada input pengguna? Secara teknis rasanya terlalu dipaksakan

    • Pada akhirnya bukankah ini security through obscurity? Seolah-olah kalau dibuat begitu rumit sampai kita sendiri tidak mengerti, orang lain juga tidak akan mengerti?

      Yang penting bukan membuat lebih banyak tembok, melainkan membuat tembok tidak bisa dijebol. Antarmuka menurunkan performa dan menaikkan kompleksitas

  • Secara pribadi, ungkapan ini mengganggu. “1 miliar permintaan per bulan” kira-kira 370 permintaan per detik. Itu tingkat yang bisa ditangani satu server yang dikonfigurasi dengan baik, dan jelas kurang dari 10 server sudah cukup
    Satu skrip bash jahat pun bisa menghasilkan trafik sebesar itu

    • Berkat microservices, kami butuh 45 node Kubernetes untuk menangani 1000 permintaan per detik
    • Itu benar jika permintaan tersebar merata sepanjang waktu. Namun dalam situasi serangan, permintaan bisa melonjak tiba-tiba lalu mendatar, dan tetap saja jika dihitung selama 30 hari menjadi 1 miliar permintaan per bulan
    • Bukan hanya satu server yang dikonfigurasi dengan baik; setelah JVM JIT bekerja, satu core pun bisa melakukannya
  • Mungkin saya yang kehilangan rasa realistis, tetapi puluhan miliar permintaan per bulan terdengar bukan apa-apa. Apakah ini dianggap serangan DDoS besar?

    • Tergantung siapa yang membayar biayanya. Kalau hosting sendiri, itu bukan masalah, tetapi di serverless, level seperti itu biasanya cukup mahal, apalagi jika trafiknya tidak bernilai
    • Untuk API yang dirancang secara wajar, 300–400 permintaan API per detik bukan beban berat. 300–400 permintaan file statis per detik bahkan lebih kecil dari kacang
    • Benar. 1 miliar permintaan per bulan rata-ratanya 380 permintaan per detik, jadi tidak setinggi itu
    • Tergantung banyak faktor. Biasanya infrastruktur diprovisioning sesuai penggunaan yang diperkirakan, dan kapasitas cadangan berlebihan itu pemborosan
  • Saya suka bagian “membuat layanan monolith untuk tiap aplikasi yang mudah dideploy dan dirawat. Tanpa Docker, tanpa Kubernetes, tanpa dependensi, tanpa lingkungan runtime; hanya satu file biner yang bisa dideploy ke VPS baru mana pun”

    • Saya tidak memakai TablePlus secara langsung. Kalau ini soal situs web marketing, jelas tidak perlu Kubernetes
      Kalau ini soal aplikasinya, klaim tanpa dependensi terasa aneh. Bukankah ia menyimpan data dan juga mencatat log?

    • Ini salah satu keunggulan Golang yang benar-benar bagus. Tinggal menyalakan VPS, menerapkan default yang masuk akal, lalu cross-compile dan menjalankan binernya

      Dibanding deployment Python, Node, atau PHP, kompleksitas yang tidak perlu jauh lebih sedikit

      Andai menjalankan dan menjaga server database tetap hidup bisa sesederhana ini

  • Dari judulnya, saya mengharapkan sesuatu yang lebih cocok dengan swole doge. Saya setuju dengan banyak sarannya, tetapi berada di balik Cloudflare sama sekali bukan berarti tidak melakukan apa-apa
    Tergantung distribusi trafiknya, mungkin saja VPS sendiri tanpa Cloudflare juga bisa bertahan, dan skalanya juga tidak tampak sebesar itu. Akan menarik jika melihat statistik yang lebih rinci seperti jumlah permintaan per detik dan seberapa banyak yang diblokir Cloudflare sebelum mencapai origin

    DDoS layer 7 dari Rusia terhadap perusahaan Swedia yang saya ketahui skalanya begitu besar sampai penyedia-penyedia utama tumbang karena masalah kapasitas. Termasuk Verizon, Azure Frontdoor, Cloudflare, hingga load balancer GCP. Menghadapi skala seperti itu, strategi ini jelas tidak akan berhasil