Varnish İle Rate Limiting Nasıl Uygulanır?

Web uygulamaları geliştiren hemen hemen tüm geliştiricilerin bir şekilde yolunun düştüğü Varnish, en kaba tabiriyle backend çıktısını önbellekleyen ve sunan, aynı zamanda HTTP reverse proxy yeteneğine de sahip, açık kaynak kodlu güçlü — ve hızlı — bir ürün.

Hızlı ve stabil olmasının yanı sıra, ürünü güçlü kılan en önemli özelliklerinden bir tanesi genişletilebilir olması. VMOD adını verdikleri eklenti özelliği sayesinde; komünite tarafından (bireysel geliştiricilerin yanısıra NY Times gibi şirketler de bu ürün üzerinde çalışıyor ve eklentiler geliştiriyor) eklenen yeni özelliklerle birlikte, ürünün kullanım alanı gün geçtikte genişliyor.

Geliştirilmesi durmuş ama hala çalışan, hala geliştirilme aşamasında olan ve stabil olduğu kabul edilen tüm eklentilerin listesi, bu adresten erişebilir durumda.

Bu yazının konusu da beğeniyle kullandığım iki eklentiyi harmanlayarak, basit ama etkili bir rate limiting (istek sınırlama) uygulamasını hayata geçirmek. Hadi kolları sıvayalım o halde!

Fotoğraf, Asael Peña tarafından çekilmiş, Unsplash üzerinden indirilmiştir.

tbf ve dict

Şu bahsi geçen iki eklentinin kısaltma isimleri.

tbf

Rate limit uygulaması için geliştirilen eklenti. Bu adresten eklentinin kaynak kodlarına ve nasıl kurulup, kullanılabileceğine erişebilirsiniz.

dict

Anahtar-değer ikilisi olarak tutulan verilerin okunup sorgulanması için geliştirilen eklenti. Onun da kaynak kodlarına ve dokümantasyonuna yine bu adresten erişmeniz mümkün.

Harmanı ise şöyle yapacağız:

Bir anahtar-değer ikilisi tutan dosya içerisinde, izinli IP adreslerini ve bu izinlere karşılık gelen rate limitleri dict eklentisi sayesinde tutacağız. Varnish’e bir istek geldiğinde, isteğin geldiği IP adresinin liste içerisinde olup olmadığını kontrol edecek; eğer izinli ise onun limitlerini alıp tbf eklentisi ile sorgulayacağız.

Yukarıdaki senaryonun canlandırıldığı örneğe aşağıdaki repository üzerinden ulaşabilirsiniz.

Örnek, Vagrant üzerinde çalışıyor ve IP adresi 172.81.81.2 . Varnish ise 6081 portundan hizmet ediyor. Client makinemizin adresi ise 172.81.81.1 . Bu client üzerinden gelen isteklere koymak istediğim sınır ise 5 saniyede 1 istek. Dolayısıyla, repository içerisindeki /configurations/ip-list.dict dosyası içerisine 172.81.81.1 1req/5s ifadesini ekliyorum. 5s olarak girilen yerdeki s parametresi yerine m (dakika), h (saat) ya da d (gün) ifadeleri de girilebilir. 24 saatte 10000 istek için 10000req/24h ifadesi örnek olarak verilebilir.

Bundan sonraki fırtına ise Varnish konfigürasyon dosyasında (/configurations/default.vcl ) kopuyor:

vcl_init subroutine’inde IP listemi ve karşılık gelen limitleri yüklüyorum. vcl_recv subroutine’inde — gelen her isteğin uğradığı alt fonksiyon — ise isteği yapan IP adresinin listede olup olmadığını kontrol ediyorum. Eğer listede böyle bir IP adresi yoksa — 13.satır — direkt olarak 405 dönüyorum. Listede varsa tbf.check fonksiyonu ile rate limit sınırlarını sorguluyor ve limit aşılmadığı takdirde cevap olarak bir metin dönüyorum (tabii ki gerçek hayatta olması gereken, backend’den gelen cevabı dönmek). Aksi durumda ise 429 kodu ile limitlerin aşıldığını kullanıcıya iletiyorum.

Sonuç

Bu senaryo, Rate Limiting için uygulanabilecek en basit senaryo. Header üzerinden, kullanıcıya kaç adet limiti kaldığını, ne kadar süre içerisinde ne kadar istek yapabileceğini de belirtebiliriz.

Dict eklentisinin ise kullanım alanı oldukça geniş. Küçük — ve gerçek hayattan — bir örnek vermek gerekirse, statik yönlendirmelerimizi bu eklenti ile çok hızlı bir şekilde yönetebiliyoruz. Böylece uygulamanız içerisinde bir yönlendirme akışı yazmadan ve sadece yönlendirme işlemi için uygulamalarınızı yormadan bu işlemi halledebilirsiniz.

Bir sonraki yazıya dek, 429 ile hiç karşılaşmamanız dileğiyle (geliştirme aşamasında çok can sıkıyor da :)