Pengerasan Keamanan & Anti-Spoofing
Rate limiter yang dideploy di edge atau di belakang reverse proxy menghadapi ancaman keamanan umum seperti Pemalsuan Header (IP Spoofing) dan Tabrakan Routing Redis Cluster. distlimit membangun mekanisme pertahanan bawaan terhadap kedua vektor ancaman tersebut.
🛡️ Pelindung Anti-IP Spoofing (WithTrustedProxies)
Section titled “🛡️ Pelindung Anti-IP Spoofing (WithTrustedProxies)”Ancaman Pemalsuan
Section titled “Ancaman Pemalsuan”Saat aplikasi Go Anda berjalan di belakang CDN atau Load Balancer (Cloudflare, Nginx, AWS ALB), RemoteAddr socket yang masuk adalah IP milik proxy, bukan pengguna akhir. Rate limiter yang naif akan mempercayai header HTTP seperti X-Forwarded-For atau X-Real-IP secara mentah.
Penyerang dapat memotong rate limit berbasis IP dengan menyisipkan header palsu:
GET /api/v1/resource HTTP/1.1Host: api.example.comX-Forwarded-For: 1.2.3.4, 5.6.7.8Jika server Anda mempercayai header unverified ini, penyerang cukup memutar nilai X-Forwarded-For pada setiap request untuk melewati pembatasan kuota secara total.
Solusi: Verifikasi Proxy CIDR
Section titled “Solusi: Verifikasi Proxy CIDR”Adapter middleware distlimit menginspeksi X-Forwarded-For atau X-Real-IP hanya jika peer jaringan langsung (RemoteAddr) cocok dengan subnet CIDR terpercaya.
Contoh Konfigurasi
Section titled “Contoh Konfigurasi”package main
import ( "time"
"github.com/balramadan/distlimit" "github.com/balramadan/distlimit/algorithm/tokenbucket" "github.com/balramadan/distlimit/driver/memory" distlimitnethttp "github.com/balramadan/distlimit/middleware/nethttp")
func main() { memDriver := memory.New(5 * time.Minute) limiter, _ := distlimit.New( memDriver, distlimit.WithLimit(100), distlimit.WithWindow(1*time.Minute), distlimit.WithAlgorithm(tokenbucket.New()), )
// Konfigurasi Subnet Proxy Terpercaya (misal CIDR Cloudflare, VPC Internal) middleware := distlimitnethttp.New( limiter, distlimitnethttp.WithTrustedProxies([]string{ "10.0.0.0/8", // Subnet VPC Privat "172.16.0.0/12", // Jaringan Docker Internal "103.21.244.0/22", // Blok CIDR Cloudflare IPv4 }), )}Flowchart Resolusi IP
Section titled “Flowchart Resolusi IP”flowchart TD
Req[Incoming Request] --> CheckProxy{Apakah RemoteAddr di Trusted Proxies?}
CheckProxy -->|Ya| ParseHeader[Parse X-Forwarded-For / X-Real-IP]
CheckProxy -->|Tidak| Fallback[Gunakan IP Mentah RemoteAddr]
ParseHeader --> Extract[Ekstrak IP Client Pertama yang Untrusted]
Extract --> Limiter[Kirim IP Asli ke Limiter]
Fallback --> Limiter
🔐 Keamanan Redis Cluster via Hash Tags {}
Section titled “🔐 Keamanan Redis Cluster via Hash Tags {}”Kerentanan CROSSSLOT
Section titled “Kerentanan CROSSSLOT”Dalam topologi Redis Cluster, data dibagi ke dalam 16.384 hash slot yang didistribusikan ke beberapa node master. Saat mengeksekusi operasi atomik multi-key atau skrip Lua di Redis Cluster, Redis mengharuskan semua key yang dirujuk berada dalam hash slot yang persis sama.
Mengeksekusi operasi multi-key tanpa hash tag menyebabkan Redis mengembalikan error fatal:
(error) CROSSSLOT Keys in request don't hash to the same slotSolusi: Format Hash Tag Otomatis
Section titled “Solusi: Format Hash Tag Otomatis”distlimit menerapkan pemformatan Redis Hash Tags {} pada setiap key yang dievaluasi oleh driver Redis: distlimit:{key}.
Cara Kerja Hash Tags
Section titled “Cara Kerja Hash Tags”Saat Redis menemukan kurung kurawal {} pada nama key, Redis menghitung checksum CRC16 hanya dari substring yang ada di dalam {}:
- Key 1:
distlimit:{user_123}:tokens$\rightarrow$ Slot dihitung dariuser_123 - Key 2:
distlimit:{user_123}:timestamp$\rightarrow$ Slot dihitung dariuser_123
Karena kedua key memiliki hash tag {user_123} yang sama, Redis menjamin kedua key berada pada slot node cluster yang sama. Ini mencegah error CROSSSLOT secara total sambil menjaga eksekusi Lua atomik di seluruh cluster Redis.