Bloga dön
27 Ekim 2025Sergei Solod4 dk okuma

Statik Next.js sitem günde binlerce güvenlik açığı taraması alıyor. Nginx bunu neredeyse hiç hissetmiyor

Loglarım WordPress, PHP backdoor, .env ve .git/config arayan probe’larla dolu. Statik Next.js + Nginx yapımda bunların çoğu ucuz miss ve 404 olarak bitiyor; gözlem sırasında CPU yükü değişmedi. Bu deneyimin statik site güvenliği hakkında gerçekten ne söylediğini ve neyi kanıtlamadığını ayırmak önemli.

GüvenlikNext.jsNginxDevOpsStatik hostingAttack Surface

Her gün sunucu loglarımda binlerce otomatik güvenlik açığı taraması görüyorum. İsteklerin kendisi oldukça ürkütücü görünüyor:

  • /wp-admin/wp.php
  • /111.php
  • /code.php
  • /.git/config
  • /i.php
  • /admin
  • /api/.env
  • /kal.php

Beni şaşırtan sayı değil, sunucunun tepkisiydi. Bu trafiği izlerken CPU yükünde görünür bir değişiklik olmadı.

Bu gözlem gerçek, fakat ilk açıklamam gereğinden fazla kesindi. Statik sunum sihirli bir kalkan değil ve 404 de bedava değil. Mimari avantajım daha dar ama daha kullanışlı: opportunistic probe’ların çoğu ucuz, çünkü public request path üzerinde erişebilecekleri server-side application logic neredeyse yok.

Bunlar probe; compromise kanıtı değil

/wp-admin/wp.php veya /111.php görünce her isteğe “exploit” demek kolay. Teknik olarak bu doğru değil. Gördüğüm şey çoğunlukla otomatik probing: botlar yaygın dosya adlarını ve endpoint’leri deneyip neyin cevap verdiğini kontrol ediyor.

Bazı path’ler açıkça WordPress veya PHP hedefliyor. /.git/config ve /api/.env gibi diğerleri yanlışlıkla yayımlanmış configuration veya secret arıyor. /admin daha da genel; meşru bir route olabilir. Şüpheli bir request, scanner’ın ne aradığını gösterir; vulnerability’nin gerçekten var olduğunu kanıtlamaz.

Benim durumumda belirleyici şey mimari: public site, Next.js ile önceden render edilmiş statik HTML ve doğrudan Nginx tarafından sunuluyor.

Bu trafik stack’imde neden ucuz

Bahsettiğim sayfalarda her request’in arkasında PHP runtime veya database yok. Nginx zaten var olan dosyaları sunuyor. Scanner /111.php ister ve dosya yoksa PHP application başlamıyor, WordPress code çalışmıyor, database query oluşmuyor. Request sadece miss oluyor ve 404 ile bitiyor.

Bu, maliyet modelini değiştiriyor. Dinamik bir application’da request routing, framework, authentication, rendering, database veya başka service’lere kadar ilerleyebilir. Benim statik path’imde moving parts çok daha az. Nginx yine connection kabul etmek, HTTP işlemek, resource aramak, log yazmak ve response göndermek zorunda; ancak application work küçük.

Site için aggressive caching de kullanıyorum ve bu normal statik delivery’ye yardımcı oluyor. Yine de her rastgele 404’ü cache’e bağlamam. Daha önce görülmemiş anlamsız bir URI, 404 dönmeden önce normal Nginx processing ve filesystem lookup’tan geçebilir.

Önemli düzeltme: statik, “tanım gereği güvenli” demek değil

Bugün en çok bu kısmı daha dikkatli yazardım. Statik architecture public request path’ten birçok server-side component’i çıkarır, fakat security işini ortadan kaldırmaz.

  • Exposed file hâlâ exposed’dur. .git, .env, backup veya secret public directory’ye yanlışlıkla girerse ve configuration engellemiyorsa Nginx bunu HTML kadar verimli sunabilir.
  • Nginx, TLS, işletim sistemi ve network attack surface’in parçası olmaya devam eder. Patch ve doğru configuration gerekir.
  • Client-side code’da vulnerability olabilir. Statik HTML, JavaScript’i, browser-side auth logic’i veya third-party script’leri otomatik olarak güvenli yapmaz.
  • Resource exhaustion hâlâ mümkündür. Connection, bandwidth, TLS handshake, worker capacity, log I/O ve disk space sınırlıdır. Yeterli trafik statik siteyi de zorlayabilir.

Bu yüzden doğru sonuç “bu request’lerin önemi yok” değil; bu mimaride application-specific probe’ların çoğunun çalıştırabileceği bir şey bulamamasıdır.

“Günde binlerce scan” gerçek yükten daha korkutucu duyulabilir

Loglar Internet background noise’u çok yoğun gösterir; çünkü her başarısız probe ayrı satırdır. Fakat günlük toplam tek başına operational impact’i anlatmaz. 24 saate yayılmış birkaç bin request ile aynı miktarın kısa bir burst halinde gelmesi tamamen farklıdır.

CPU da yalnızca bir signal. Benim durumumda sabit kaldı; bu, gözlem anında trafiğin görünür compute pressure yaratmadığına dair faydalı evidence. Ama başka resource’ların maliyetinin sıfır olduğunu kanıtlamaz. Sağlıklı değerlendirmede request rate, bandwidth, active connections, Nginx worker utilization, response latency, log volume ve disk usage da bakarım.

Bu gürültüyü izlerken öğrendiğim şey

Benim için en büyük ders, mimarinin her scanner signature için ayrı rule yazmadan otomatik saldırıların tüm kategorilerini anlamsız hale getirebilmesi. Bir bot bütün gün WordPress ve PHP backdoor arayabilir; public request path’te WordPress veya PHP yoksa o probe’ların kullanabileceği çok az şey vardır.

Ama artık “benim stack’im için irrelevant” ile “harmless traffic”i aynı şey saymıyorum. Güncel checklist’im:

  • Public request path’ten gerçekten hangi runtime ve service’lerin reachable olduğunu bilmek.
  • Secret, repository metadata, backup ve build artifact’leri web root dışında tutmak veya açıkça block etmek.
  • Başka targeting veya impact evidence yoksa tekrarlanan 404 probe’ları normal Internet background noise saymak.
  • Sadece CPU’ya bakıp abusive traffic’in bedava olduğuna karar vermemek.
  • Application statik olsa bile Nginx, OS, TLS library ve dependency’leri patch tutmak.

Bu deneyimin kanıtlamadığı şeyler

Controlled benchmark çalıştırmadım ve DDoS simüle etmedim. Her gün binlerce scanner request gelirken production log ve server load’u gözlemledim. Bu kendi setup’ım için pratik sonuç çıkarmaya yeter, ama “statik her zaman kazanır” şeklinde evrensel bir kuralı kanıtlamaz.

Daha net doğrulayabildiğim şey şu: Nginx’in sunduğu Next.js static export’umda gördüğüm scanner traffic’in çoğu PHP runtime veya database-backed application’a ulaşmak yerine ucuz file miss ve 404 olarak bitti. Gözlem sırasında CPU yükü değişmedi.

Benim önemsediğim resilience avantajı bu. Daha az moving part sistemi invulnerable yapmaz; yalnızca random Internet noise’un gerçek application work’e dönüşebileceği yerleri azaltır.