Nginx güvenlik ayarları: oran sınırlama, başlıklar, erişim kısıtları
Nginx, sitenize gelen her isteğin ilk karşılandığı yerdir. Bu yüzden birçok koruma, uygulamanın koduna dokunmadan burada kurulabilir: aşırı istek gönderen adresleri yavaşlatmak, açıkta kalmaması gereken dosyaları kapatmak, yönetim sayfasını yalnızca belirli adreslere açmak, çok büyük ya da çok yavaş istekleri kesmek.
Bu ayarlar uygulamadaki açıkları kapatmaz; hatanın etkisini küçülten ve otomatik taramaların büyük bölümünü uygulamaya ulaşmadan durduran bir ön katmandır. Rehber, her ayarın ne işe yaradığını ve Nginx yapılandırmasında nasıl yazıldığını anlatır. HTTPS kurulumu ayrı bir rehberdedir: Nginx'te HTTPS.
Kısaca
- Bilinmeyen alan adıyla gelen istekler varsayılan sunucu bloğunda reddedilir.
- limit_req ve limit_conn, tek adresten gelen istek ve bağlantı sayısını sınırlar.
- Alt blokta add_header varsa üstteki başlıklar devralınmaz; ortak başlıklar yinelenmelidir.
- Gizli dosyalar, yönetim yolu ve yükleme klasörü ayrı location bloklarıyla korunur.
Dikkat
Ayarları tek tek ekleyin, her değişiklikten sonra "nginx -t" ile sınayın. Yanlış bir IP kısıtı ya da çok sıkı bir oran sınırı sizi ve gerçek ziyaretçileri de dışarıda bırakabilir; değerleri kendi trafiğinize göre belirleyin.
Bu sayfada
Yedi adımda sıkılaştırma
-
Bilinmeyen alan adlarını reddedin, sürümü gizleyin
Nginx, gelen isteğin
Hostbaşlığınıserver_namesatırlarıyla eşleştirir. Hiçbiri uymazsa isteği o bağlantı noktasının varsayılan sunucusuna verir; ayrıca belirtilmediyse bu, yapılandırmada ilk tanımlananserverbloğudur. Sonuç: sunucuya IP adresiyle ya da size ait olmayan bir alan adıyla gelen otomatik taramalar gerçek sitenize ulaşır.Bunu önlemek için hiçbir siteye ait olmayan bir varsayılan (catch-all) blok tanımlayın.
return 444;Nginx'e özgü bir koddur: yanıt göndermeden bağlantıyı kapatır.Nginx# Hata sayfalarında ve Server başlığında sürüm numarasını gösterme server_tokens off; # Varsayılan blok: hiçbir siteyle eşleşmeyen Host istekleri server { listen 80 default_server; listen [::]:80 default_server; listen 443 ssl default_server; listen [::]:443 ssl default_server; server_name _; # Bilinmeyen adla gelen TLS el sıkışmasını reddet ssl_reject_handshake on; # Yanıt göndermeden bağlantıyı kapat return 444; }ssl_reject_handshake on;bilinmeyen adla gelen HTTPS bağlantılarını sertifika sunmadan reddeder ve güncel Nginx sürümlerinde bulunur; eski sürümlerde bu blok için kendinden imzalı bir sertifika tanımlamak gerekir.server_tokens off;ise hata sayfalarından veServerbaşlığından sürüm numarasını kaldırır. Bu tek başına koruma sağlamaz; yalnızca sürüme göre hedef seçen taramalara daha az bilgi verir. Asıl önlem Nginx'i güncel tutmaktır.
: Büyüt -
Oran sınırlama: limit_req ve limit_conn
Oran sınırlama (rate limiting), tek bir adresin belirli sürede gönderebileceği istek sayısını sınırlar. İki ayrı araç vardır:
limit_req_zone+limit_req: istek hızını sınırlar (ör. saniyede 10 istek).limit_conn_zone+limit_conn: aynı anda açık bağlantı sayısını sınırlar.
…_zoneyönergelerihttpbloğunda bir kez tanımlanır: anahtarı (genellikle istemci adresi,$binary_remote_addr), paylaşılan bellek alanının adını ve boyutunu,limit_req_zoneiçin ayrıca hızı belirtir. Sınır,serverya dalocationiçinde uygulanır.Nginx# http bloğunda: alanlar bir kez tanımlanır limit_req_zone $binary_remote_addr zone=genel:10m rate=10r/s; limit_req_zone $binary_remote_addr zone=giris:10m rate=5r/m; limit_conn_zone $binary_remote_addr zone=baglanti:10m; # Reddedilenlere 503 yerine 429 dön limit_req_status 429; limit_conn_status 429; server { listen 443 ssl; server_name ornek.com; ssl_certificate /etc/letsencrypt/live/ornek.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ornek.com/privkey.pem; # Tüm site: saniyede 10 istek, 20 isteklik sıra limit_req zone=genel burst=20 nodelay; # Aynı adresten en çok 20 eş zamanlı bağlantı limit_conn baglanti 20; location / { proxy_pass http://127.0.0.1:8080; } # Giriş formu: dakikada 5 istek location = /giris { limit_req zone=giris burst=5 nodelay; proxy_pass http://127.0.0.1:8080; } }İki parametre davranışı belirler:
burst: hızın üzerindeki isteklerden kaçının hemen reddedilmeyip sıraya alınacağını belirtir. Yazılmazsa hızı aşan her istek reddedilir; bir sayfa açılışında art arda gelen görsel ve betik istekleri için bu çok serttir.nodelay: sıraya alınan istekler bekletilmeden hemen işlenir; sıradaki yerler ise belirlenen hızla boşalır. Yazılmazsa sıradaki istekler hıza uyacak şekilde geciktirilir.
Reddedilen isteklere varsayılan olarak 503 döner.
limit_req_status 429;velimit_conn_status 429;ile bunu "çok fazla istek" anlamına gelen 429 yapın; böylece günlüklerde gerçek sunucu hatalarından ayırt edilir. Giriş formu gibi hassas adreslere ayrı ve daha düşük bir sınır verin. Birlocationiçindelimit_reqtanımlanırsa üst düzeydekilimit_reqo blokta geçerli olmaz.Dikkat: Nginx bir CDN'in ya da başka bir vekil sunucunun arkasındaysa
$binary_remote_addrziyaretçinin değil, öndeki sunucunun adresidir; sınır tüm ziyaretçilere birlikte uygulanır. Bu durumda önce gerçek istemci adresiniset_real_ip_fromvereal_ip_headeryönergeleriyle (yalnızca güvendiğiniz vekil adresleri için) tanımlayın. Oran sınırlama büyük hacimli saldırıları tek başına durdurmaz; katmanlar için DDoS ve bot saldırıları rehberine, giriş denemeleri için Giriş ve oturum güvenliği rehberine bakın.
: Büyüt -
Güvenlik başlıkları ve add_header kalıtım tuzağı
Güvenlik başlıkları tarayıcının yerleşik korumalarını açar. Nginx'te
add_headerile eklenir; sondakialways, başlığın 404 ve 500 gibi hata yanıtlarında da gönderilmesini sağlar. Başlıkların anlamı için Güvenlik başlıkları ve HTTPS rehberine bakın.Nginx'e özgü önemli bir tuzak vardır:
add_headeryönergeleri üst düzeyden yalnızca geçerli blokta hiçadd_headeryoksa devralınır. Birlocationiçine tek biradd_header(ör. önbellek başlığı) yazdığınız anda,serverdüzeyindeki tüm güvenlik başlıkları o blokta kaybolur.Nginx# server düzeyi: tüm yanıtlara add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "geolocation=(), camera=(), microphone=()" always; location /assets/ { # Bu blokta add_header var: yukarıdaki dört başlık burada DEVRALINMAZ add_header Cache-Control "public, max-age=2592000"; # Çözüm: ortak başlıkları bu blokta da tanımla # (dosyanın içeriği yukarıdaki dört add_header satırıdır) include /etc/nginx/snippets/guvenlik-basliklari.conf; }Güvenilir çözüm, ortak başlıkları ayrı bir dosyada tutup
add_headerkullanan her bloğaincludeile eklemektir. Değişiklikten sonra yalnızca ana sayfayı değil, statik dosyaları ve hata sayfalarını dacurl -sIile kontrol edin.
: Büyüt -
Gizli dosyalara erişimi kapatın
Adı nokta ile başlayan dosya ve klasörler (
.env,.git,.htpasswd) parola, anahtar ve kaynak kod içerebilir; otomatik taramaların ilk baktığı yerlerdir. Tek istisna.well-knownklasörüdür: sertifika doğrulaması gibi standart işler için açık kalmalıdır.Nginx# İstisna: .well-known açık kalır (sertifika doğrulaması vb.) location ^~ /.well-known/ { allow all; } # Adı nokta ile başlayan her dosya ve klasör: .env, .git, .htpasswd ... location ~ /\. { deny all; } # Web kökünde unutulan yedek ve döküm dosyaları location ~* \.(?:sql|bak|old|orig|log|ini)$ { deny all; }^~işareti, bu ön ek eşleştiğinde düzenli ifadelilocationbloklarına bakılmamasını sağlar; böylece.well-knownaltındaki istekler genel yasağa takılmaz. Üçüncü blok, web kökünde unutulan yedek ve döküm dosyalarını kapatır. Yine de en doğrusu bu dosyaları web kökünde hiç bulundurmamaktır: Sunucu ve barındırma güvenliği. -
Yönetim yolunu ve yükleme klasörünü koruyun
Yönetim paneli yalnızca belirli yerlerden kullanılıyorsa IP kısıtı, parola tahmini denemelerini giriş formuna ulaşmadan keser.
allowvedenykuralları yazıldıkları sırayla denenir; ilk uyan kural geçerlidir, bu yüzdendeny all;en sonda durur.Nginx# ^~ : bu ön ek eşleşince dıştaki düzenli ifadeli bloklara bakılmaz location ^~ /yonetim/ { allow 203.0.113.10; # ofis allow 198.51.100.0/24; # VPN deny all; # Kısıt, bloğun içindeki PHP işleyicisi için de geçerlidir location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/run/php/php-fpm.sock; # yol dağıtıma göre değişir } }Burada sık yapılan bir hata vardır. PHP sitelerinde genellikle
location ~ \.php$biçiminde düzenli ifadeli bir blok bulunur. Kısıtı sıradan birlocation /yonetim/bloğuna yazarsanız/yonetim/index.phpisteği düzenli ifadeli bloğa düşer ve kısıt uygulanmaz. Örnekteki gibi^~kullanıp PHP işleyicisini bloğun içine yerleştirmek bunu önler. PHP-FPM soket yolu dağıtıma göre değişir.Aynı mantık yükleme klasörü için tersine çalışır: ziyaretçilerin dosya yükleyebildiği klasörde hiçbir betik çalıştırılmamalıdır. Aşağıdaki blok, klasördeki dosyaları yalnızca durağan dosya olarak sunar ve betik uzantılı isteklere 403 döndürür.
Nginx# Yükleme klasörü: yalnız durağan dosya sunulur location ^~ /upload/ { # Betik uzantılı istekler çalıştırılmaz, sunulmaz location ~* \.(?:php|phtml|phar|pl|py|cgi|sh)$ { return 403; } }Bu, yüklenen bir dosyanın sunucuda çalıştırılmasını engelleyen ikinci katmandır; ilk katman yükleme sırasındaki denetimdir: Dosya yükleme güvenliği.
: Büyüt -
Büyük ve yavaş isteklere sınır koyun
Çok büyük gövdeli istekler disk ve bellek tüketir; bilerek çok yavaş gönderilen istekler ise bağlantıları uzun süre meşgul eder. Üç yönerge bu ikisini sınırlar:
Yönerge Ne sınırlar? Varsayılan Aşılınca client_max_body_sizeİstek gövdesinin (ör. yüklenen dosyanın) en büyük boyutu 1m 413 client_body_timeoutGövde okunurken art arda iki okuma arasındaki süre 60s 408 client_header_timeoutİstek başlıklarının tamamının okunma süresi 60s 408 Nginx# Genel sınırlar client_max_body_size 2m; client_body_timeout 15s; client_header_timeout 15s; # Yalnız dosya yüklenen adres için daha yüksek gövde sınırı location /dosya-yukle { client_max_body_size 20m; proxy_pass http://127.0.0.1:8080; }Genel sınırı düşük tutun, dosya yüklenen adrese ayrı ve daha yüksek bir değer verin. PHP kullanıyorsanız
upload_max_filesizevepost_max_sizeayarları da bu değerle uyumlu olmalıdır. Zaman aşımlarını (timeout) çok kısaltmak, yavaş mobil bağlantıdaki gerçek kullanıcıları da keser; değerleri kademeli düşürün ve günlüklerdeki 408 yanıtlarını izleyin. -
Sınayın, yükleyin ve dışarıdan doğrulayın
Her değişiklikten sonra sözdizimini sınayın ve Nginx'i yeniden yükleyin. Ardından ayarların gerçekten çalıştığını kendi sitenize dışarıdan istek göndererek doğrulayın: gizli dosya adresleri 403 ya da 404 dönmeli, başlıklar statik dosyalarda da görünmeli, sunucunun IP adresine yapılan istek yanıtsız kapanmalıdır.
Bash# Sözdizimini sına, sonra yeniden yükle sudo nginx -t sudo systemctl reload nginx # Başlıklar: ana sayfa ve bir statik dosya curl -sI https://ornek.com/ curl -sI https://ornek.com/assets/site.css # Gizli dosyalar kapalı mı? (403 ya da 404 beklenir) curl -s -o /dev/null -w "%{http_code}\n" https://ornek.com/.env curl -s -o /dev/null -w "%{http_code}\n" https://ornek.com/.git/config # Sunucunun IP adresine istek: yanıtsız kapanmalı curl -sI http://203.0.113.20/IP kısıtını denerken ikinci bir oturumu açık tutun; yanlış bir kural sizi panelin dışında bırakırsa yapılandırmayı o oturumdan geri alabilirsiniz.
: Büyüt
Bu ayarlar neyi çözmez?
- Uygulama açıkları: SQL enjeksiyonu, XSS ya da yetki kontrolü hataları kodda düzeltilir; Nginx ayarı bunların yerini tutmaz.
- Büyük hacimli saldırılar: sunucunun bant genişliğini dolduran trafik, sunucuya ulaşmadan önce (barındırma firması ya da CDN düzeyinde) karşılanmalıdır.
- Dağıtık yavaş denemeler: çok sayıda farklı adresten gelen az sayıda istek, adres başına sınıra takılmaz; giriş güvenliği uygulamada da kurulmalıdır.
- Ele geçirilmiş hesaplar: IP kısıtı ve oran sınırı, geçerli parolayla izinli adresten gelen birini durdurmaz; iki adımlı doğrulama gerekir.
Değerleri nasıl seçmeli?
Örneklerdeki sayılar başlangıç noktasıdır, öneri değildir. Doğru değer sitenizin trafiğine bağlıdır:
- Bir sayfanın açılışında tarayıcının kaç istek gönderdiğine bakın;
burstbu sayıyı karşılamalıdır. - Aynı kurum ağından çıkan çok sayıda kullanıcı tek IP adresiyle görünebilir; sınırı buna göre gevşetin ya da bilinen adresleri ayrı tutun.
- Sınırı açtıktan sonra hata günlüğünde reddedilen istek kayıtlarını ve erişim günlüğündeki 429 yanıtlarını izleyin; gerçek kullanıcılar takılıyorsa değeri yükseltin.
- HTTP/2 ve HTTP/3'te eş zamanlı her istek
limit_conniçin ayrı bir bağlantı sayılır; değeri çok düşük seçmeyin. - Arama motoru botlarını ve kendi izleme araçlarınızı sınırın dışında bırakmanız gerekip gerekmediğini değerlendirin.
Kontrol listesi
- 80 ve 443 için varsayılan blok tanımlı; bilinmeyen
Hostile gelen istek siteye ulaşmıyor. server_tokens off;tanımlı ve Nginx güncel.- Genel ve giriş adresine özel oran sınırı var; reddedilenlere 429 dönüyor.
- Vekil arkasında gerçek istemci adresi doğru tanımlı.
- Güvenlik başlıkları
alwaysile tanımlı;add_headerkullanan alt bloklarda yinelenmiş. - Nokta ile başlayan dosyalar ve yedek uzantıları kapalı;
.well-knownaçık. - Yönetim yolu IP ile kısıtlı ve kısıt
.phpisteklerinde de geçerli. - Yükleme klasöründe betik çalışmıyor.
- Gövde boyutu ve zaman aşımı sınırları tanımlı; yükleme adresi için ayrı değer var.
- Her değişiklik
nginx -tile sınandı ve dışarıdan doğrulandı.
Sık sorulan sorular
Oran sınırlama arama motoru botlarını etkiler mi?
Çok düşük bir sınır botları da yavaşlatır ve 429 yanıtı taramayı geciktirir. Sınırı gerçek trafiğinize göre belirleyin ve günlüklerde hangi isteklerin reddedildiğini izleyin.
server_tokens off yazınca Server başlığı tümüyle kalkar mı?
Hayır. Yalnızca sürüm numarası kalkar; başlıkta "nginx" yazmaya devam eder. Bu ayar bilgi sızıntısını azaltır, güncellemenin yerini tutmaz.
444 yerine 403 ya da 404 dönsem olur mu?
Olur. 444 yanıt göndermeden bağlantıyı kapattığı için otomatik taramalara en az bilgiyi verir. Bir izleme aracı ya da yük dengeleyici o adresten yanıt bekliyorsa standart bir kod kullanın.
Başlıklarım ana sayfada var ama görsellerde yok; neden?
Büyük olasılıkla statik dosyalara ait location bloğunda ayrı bir add_header var. Nginx bu durumda üst düzeydeki başlıkları o bloğa devralmaz; ortak başlıkları o blokta da tanımlayın.
Paylaşımlı barındırmada bu ayarları yapabilir miyim?
Genellikle hayır; Nginx yapılandırması sunucu yöneticisinin elindedir. Barındırma firmanızdan destek isteyebilir ya da benzer korumaları panelden ve CDN üzerinden açabilirsiniz.
BYK Yazılım Destek Ekibi
Bu rehber BYK Yazılım destek ekibi tarafından hazırlanır ve düzenli olarak gözden geçirilir. Son güncelleme: 04.10.2026.
İlgili rehberler
- DDoS ve bot saldırılarıBelirtiler, CDN ve WAF, oran sınırlama, önbellek ve barındırma sağlayıcıyla birlikte hareket etme.
- Giriş ve oturum güvenliğiParola karması, deneme sınırı, oturum sabitleme, çerez bayrakları ve her istekte yetki kontrolü.
- Nginx'te HTTPS: SSL sertifikası kurulumuNginx'te sertifika alma, HTTPS'e yönlendirme, HSTS, SSL sonlandırma ve otomatik yenileme adımları.
- Güvenlik başlıkları ve HTTPSHSTS, CSP, X-Content-Type-Options, Referrer-Policy ve Permissions-Policy; .htaccess örneğiyle.
Web sitenizin altyapısını birlikte konuşalım
BYK Yazılım kurumsal web siteleri geliştirir. Sitenizle ilgili sorularınız için bize yazabilirsiniz.
Bize ulaşın Kurumsal web sitesi hizmetimiz