HTTP nedir ve sunucu tarafında nasıl çalışır?
HTTP protokolünün temel çalışma prensiplerini, sunucu loglarındaki durum kodlarını, başlık yapılarını ve HTTP/3 ile TLS süreçlerinin yönetimini bu rehberde bulabilirsiniz.
HTTP nedir?
HTTP (hypertext transfer protocol), bir istemci ile web sunucusunun veri talep etmek ve yanıt göndermek için kullandığı kurallar bütünüdür. İstemci bir istek gönderir: GET gibi bir metot, /pricing gibi bir yol, bir protokol sürümü, başlık listesi ve bazen bir gövde. Sunucu, 200 gibi bir durum koduyla ve ardından kendi başlıkları ve genellikle bir gövde ile yanıt verir. Sunucunuzdaki her sayfa görüntüleme ve her API (application programming interface) çağrısı, tekrarlanan bu tek bir alışveriştir.
HTTP kendi durumunu tutmaz. Sunucu, bir saniye önce ne istediğinizi hatırlamaz; bu nedenle oturum açma gibi bellek işlevi gören her şey, her bir istekteki başlık içerisinde taşınır. Bu tek özellik, aşağıdakilerin çoğunu açıklar: önbellekleme tamamen başlık odaklıdır ve bir yük dengeleyici, hiçbir şeyi bozmadan bir sonraki isteğinizi farklı bir arka uç sunucusuna gönderebilir.
Aşağıdaki her şey, bu modelin sunucu tarafında, access log dosyalarınızda ve nginx yapılandırmanızda nasıl göründüğüdür.
Ham bir istek ve yanıt, açıklamalı
Aşağıda eksiksiz bir HTTP/1.1 isteği yer almaktadır. Başlıkları boş bir satır sonlandırır ve bu satırdan sonra gelen her şey gövdedir. Bir GET genellikle gövde içermez.
GET /pricing HTTP/1.1
Host: example.com
User-Agent: curl/8.5.0
Accept: */*
Accept-Encoding: gzipGET, ne yapılmasını istediğinizi belirten metottur.GETokuma yapar,POSTveri gönderir,PUTdeğiştirir,DELETEkaldırır,HEADise gövde olmadan birGETbaşlıklarını ister./pricingyoldur. Ana makine adı istek satırının bir parçası değildir, sonraki başlığın var olma nedeni budur.HTTP/1.1, istemcinin kullandığı protokol sürümüdür.Host: example.com, istemcinin istediği sitenin adıdır. HTTP/1.1 bunu zorunlu tutar, bu yüzden nginx bu başlık olmadan gelen isteklere400 Bad Requestile yanıt verir.- Geri kalanlar tercihlerdir.
Accept-Encoding: gzip, istemcinin sıkıştırmayı açabileceğini belirtir, böylece sunucunun gövdeyi sıkıştırmasına izin verilir.
Yanıt, en üstte bir durum satırı ile aynı yapıya sahiptir.
HTTP/1.1 200 OK
Date: Thu, 06 Aug 2026 09:12:44 GMT
Server: nginx
Content-Type: text/html; charset=utf-8
Content-Length: 5310
Cache-Control: public, max-age=300
<!doctype html>...200 OK, neden ifadesiyle birlikte durum kodudur. Önemli olan koddur. İfade bir süslemedir ve istemciler bunu görmezden gelir.Content-Type, istemciye takip eden baytların nasıl işleneceğini söyler.Content-Length, bayt cinsinden gövde boyutudur; böylece istemci gövdenin nerede bittiğini bilir. Boyut önceden bilinmediğinde sunucu bunun yerineTransfer-Encoding: chunkedgönderir ve sonu sıfır uzunlukta bir parça ile işaretler.Cache-Control, tarayıcıya ve aradaki tüm önbelleklere bu yanıtı ne kadar süre tutabileceklerini söyler.- Başlıklardan sonra gelen boş satır, her iki yönde de başlıkları gövdeden ayırır.
Başlık isimleri büyük/küçük harfe duyarlı değildir ve her satır, yalın bir satır başı yerine satır başı ve satır besleme karakteriyle biter. Bunları elle yazmazsınız ancak paket yakalama işlemlerinde karşılaşırsınız.
Gerçek bir çifti izlemek için, sahip olduğunuz bir site üzerinde şu komutu çalıştırın:
curl -sS -o /dev/null -D - https://example.com/-D -, yanıt başlıklarını terminalinize yazar ve -o /dev/null gövdeyi atar. Bunu curl -I yerine tercih edin, çünkü -I bir HEAD isteği gönderir. HEAD ile GET arasında farklı işlem yapan bir uygulama sunucusu (ki çoğu öyledir), size hiçbir tarayıcının almayacağı başlıklar gösterecektir. curl -v, > ile işaretlenmiş istek satırları ve < ile işaretlenmiş yanıt satırları ile her iki tarafı da yazdırır.
Nginx erişim günlüğünüzdeki istek satırı nasıl görünür
Nginx, combined günlük biçimiyle gelir ve tanımı şu şekildedir:
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';Bu biçim tarafından üretilen bir satır:
203.0.113.45 - - [06/Aug/2026:09:12:44 +0000] "GET /pricing HTTP/1.1" 200 5310 "https://example.com/" "Mozilla/5.0 (X11; Linux x86_64) Chrome/127.0.0.0 Safari/537.36"203.0.113.45, TCP (iletim kontrol protokolü) bağlantısını açan adres olan$remote_addr'dir. Bir proxy arkasında bu adres ziyaretçi değil, proxy'dir.- İlk
-sabit bir yer tutucudur. İkincisi ise yalnızca HTTP temel kimlik doğrulaması kullanıldığında doldurulan$remote_user'tür. "GET /pricing HTTP/1.1", istek satırının tam olarak ulaştığı haliyle kopyalanmış hali olan$request'dır.200, ziyaretçinin algıladığı durum değil, sunucunuzun döndürdüğü durum kodudur.5310, yalnızca gövde boyutu olan$body_bytes_sent'dur. Yanıt başlıkları hesaba katılmadığı için bu sayı, gönderilen gerçek bayt miktarından her zaman daha küçüktür.- Tırnak içindeki son iki alan
RefererveUser-Agent'dir. Her ikisi de istemciden geldiği için her türlü veriyi içerebilirler.
$request olduğu gibi kopyalandığı için, hatalı veriler de olduğu gibi görünür. Düz metin 80 numaralı portunuza TLS (taşıma katmanı güvenliği) ile konuşan bir istemci, istek alanı "\x16\x03\x01\x02\x00\x01" gibi kaçış karakterli baytlarla başlayan bir 400 satırı bırakır. \x16, TLS el sıkışma kayıt türüdür; dolayısıyla bu baytlar bir istek satırı değil, bir ClientHello başlangıcıdır. Sunucunuz doğru şekilde davranmaktadır. Bir şey, HTTPS trafiğini bir HTTP portuna yönlendirmektedir.
Günlük biçiminize $server_protocol ifadesini de ekleyin. Bu ifade HTTP/1.1, HTTP/2.0 veya HTTP/3.0 değerlerini yazdırır ve bir protokol değişikliğinin gerçekten devreye girdiğini kanıtlamanın en hızlı yoludur.
Kendi sitenizden dönen yaygın durum kodlarının anlamları
İlk rakam sınıfı belirtir ve öncelikle bu sınıfa bakılmalıdır.
2xx başarılı işlem demektir. Normal bir okuma işlemi için 200 OK döner. Bir şey oluşturan POST isteğinin ardından 201 Created döner. Geri gönderilecek bir içerik olmadığında, genellikle bir DELETE isteğine yanıt olarak 204 No Content döner.
3xx başka bir yere bakılması gerektiğini belirtir. 301 kalıcıdır ve tarayıcılar tarafından yoğun biçimde önbelleğe alınır; bazen kullanıcı profilini temizleyene kadar bu durum devam eder. Bu nedenle yanlış bir ana makine adına yönlendiren bir 301 hatasını düzeltmek zordur. Test aşamasında yönlendirmeler için 302 kullanın. 304 Not Modified bir hata değil, başarıdır: istemci, hâlâ tanıdığınız bir ETag (entity tag) taşıyan bir If-None-Match gönderdiğinde, yanıt olarak gövdesiz başlıklar gönderilir. 304 kodlarıyla dolu bir günlük kaydı, önbelleklemenin çalıştığı anlamına gelir.
4xx isteğin hatalı olduğunu belirtir. 400 Bad Request hatalı biçimlendirilmiş girişi ifade eder. 401 Unauthorized aslında kimlik doğrulanmadığı anlamına gelir ve mutlaka şemayı belirten bir WWW-Authenticate başlığı taşımalıdır. 403 Forbidden, isteğin anlaşıldığı ancak yine de reddedildiği anlamına gelir. 404 Not Found mevcut olmayan bir yolu ifade eder. 405 Method Not Allowed, doğru yola yanlış yöntemle erişilmeye çalışıldığında döner; statik bir dosya konumuna yapılan POST isteği buna örnektir. 413, nginx'in varsayılan olarak 1 megabayt olan client_max_body_size değerinden daha büyük bir gövde gönderildiğinde oluşur ve hata günlüğünde client intended to send too large body ile doğrulanır.
Statik bir dosyada alınan 403 hatası, neredeyse her zaman bir HTTP kuralından ziyade dosya sistemiyle ilgilidir. Herhangi bir yapılandırmayı değiştirmeden önce /var/log/nginx/error.log dosyasını okuyun. open() "/srv/site/index.html" failed (13: Permission denied), nginx çalışan kullanıcısının dosyayı okuyamadığı anlamına gelir; bu durum genellikle üst dizinin diğer kullanıcılar için çalıştırma (execute) iznine sahip olmamasından kaynaklanır. directory index of "/srv/site/" is forbidden, yolun bir dizine işaret ettiğini ancak autoindex kapalı olduğu için dizin listeleme yapılamadığını belirtir.
5xx sizin tarafınızda bir hata olduğunu belirtir. 500, uygulamanızda işlenmemiş bir hatadır. 502 Bad Gateway, nginx'in yukarı akıştan (upstream) kullanılabilir bir yanıt alamadığı anlamına gelir ve hata günlüğü nedeni belirtir: connect() failed (111: Connection refused) while connecting to upstream, proxy_pass adresinde hiçbir servisin dinleme yapmadığını gösterir. 504 Gateway Timeout, yukarı akışın bağlantıyı kabul ettiği ancak varsayılan olarak 60 saniye olan proxy_read_timeout süresi içinde yanıt vermediği anlamına gelir; bu durum günlükte upstream timed out (110: Connection timed out) while reading response header from upstream olarak kaydedilir. 503 Service Unavailable kasıtlı bir reddetmedir. Nginx'in kendi hız sınırlayıcısının (rate limiter) 503 döndürdüğünü unutmayın; çünkü limit_req_status varsayılan olarak 503 değerindedir. Günlüklerinizde 429 Too Many Requests ararken 503 ile karşılaşıyorsanız nedeni budur. Doğru kodu almak için limit_req_status 429; ayarını yapın.
Sunucuyu çalıştırırken önemli olan başlıklar
Host, siteyi seçer. Tek bir IP adresi yüzlerce ana makine adını (hostname) sunabilir; nginx, hangi server bloğunun yanıt vereceğine karar vermek için Host ile server_name değerlerini eşleştirir. Hiçbir eşleşme olmazsa nginx, varsayılan sunucuyu kullanır. Bu, başka bir blok default_server olarak işaretlenmediği sürece, ilgili adres ve portu dinleyen ilk bloktur. Yeni bir sanal ana makineden yanlış sitenin dönmesi neredeyse her zaman şundan kaynaklanır: isim eşleşmediği için istek varsayılan bloğa düşmüştür. DNS ayarlarını değiştirmeden şu şekilde test edin:
curl -sS -o /dev/null -D - -H 'Host: app.example.com' http://127.0.0.1/User-Agent, istemci tarafından yazılan bir öz tanımlamadır ve serbest metindir. Günlük kayıtlarını okurken bunu bir ipucu olarak kullanın. Asla bir kontrol mekanizması olarak kullanmayın; çünkü bu konuda yalan söylemek isteyen bir istemci bunu kolayca yapar. Bu nedenle, bir kazıyıcıyı (scraper) User-Agent ile engellemek yalnızca nazik olanları filtreler.
Content-Type, baytların nasıl yorumlanacağına karar verir: API isteği için application/json, bir sayfa için text/html; charset=utf-8. nginx, dosya uzantılarını /etc/nginx/mime.types ile türlere eşler ve paketlenmiş nginx.conf dosyası default_type application/octet-stream; değerini ayarlar. Bu yüzden nginx'in tanımadığı bir uzantıya sahip dosya, tarayıcıda görüntülenmek yerine indirilmesi için sunulur. Bunun görünür belirtisi, tarayıcı konsolunda Refused to apply style from ... because its MIME type ('text/plain') is not a supported stylesheet MIME type hatası yazarken stil dosyaları yüklenmemiş bir sayfadır. MIME, bu tür dizelerinin geldiği adlandırma şeması olan "multipurpose internet mail extensions" ifadesinin kısaltmasıdır.
Cache-Control, sunucunuz ile okuyucu arasındaki her önbelleği nasıl kontrol edeceğinizi belirler. public, max-age=31536000, immutable, dosya adı içerik özeti (hash) içeren varlıklar için uygundur; çünkü içerik değiştiğinde dosya adı da değişir. no-store, kullanıcıya özel her şey için kullanılmalıdır; çünkü oturum açılmış bir sayfayı tutan paylaşımlı bir önbellek, aynı URL'yi isteyen bir sonraki kişiye bu sayfayı gösterebilir. private orta seviye bir ayardır: tarayıcı dosyayı tutabilir ancak paylaşımlı bir önbellek tutamaz.
X-Forwarded-For, bir proxy'nin ziyaretçiyi gizlemesi nedeniyle mevcuttur. Bir istek reverse proxy üzerinden geçtiğinde, $remote_addr proxy'nin adresi olur; bu nedenle günlükleriniz, coğrafi konum belirleme ve hız sınırlama (rate limiting) mekanizmalarınız tek bir istemci görür. Proxy'nin orijinal adresi iletmesi gerekir:
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;Ardından, alıcı sunucuya bu bilgiye güvenmesi gerektiği ve tam olarak kime güveneceği söylenmelidir:
set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;Yalnızca kontrolünüz altındaki aralıkları listeleyin. X-Forwarded-For, herhangi bir istemcinin gönderebileceği düz bir metindir; bu nedenle set_real_ip_from 0.0.0.0/0;, bir ziyaretçinin günlüklediğiniz ve hız sınırlayıcınızın saydığı adresi seçmesine olanak tanır.
X-Forwarded-Proto, belirli ve çok yaygın bir hatayı önler. Proxy'niz TLS termination işlemini yapar ve isteği uygulama sunucusuna düz HTTP üzerinden iletir. Uygulama, düz bir istek görür, ziyaretçinin HTTPS üzerinde olması gerektiğine karar verir ve 301 https://example.com/ yanıtını döner. Tarayıcı bunu takip eder, proxy tekrar TLS termination yapar ve tekrar düz HTTP iletir; bu döngü, tarayıcı ERR_TOO_MANY_REDIRECTS hatası verene kadar devam eder. X-Forwarded-Proto: https başlığını göndermek, uygulamaya ziyaretçinin zaten HTTPS üzerinde olduğunu bildirir ve uygulamanın yönlendirme yapmasını engeller.
HTTP/1.1, HTTP/2 ve HTTP/3: Sizin için neler değişiyor
HTTP/1.1 metin tabanlıdır ve bağlantı başına tek seferde bir istek işler. Connection: keep-alive, sonraki isteğin aynı TCP bağlantısını yeniden kullanmasına olanak tanır; bu da kurulum maliyetinden tasarruf sağlar ancak yanıtlar hala talep edildikleri sırayla döner. Yavaş bir yanıt, arkasında kuyruğa giren her şeyi engeller. Buna "head-of-line blocking" (sıra başı engelleme) denir ve tarayıcılar aynı ana bilgisayar adına aynı anda birden fazla bağlantı açarak bu sorunu aşmaya çalışır.
HTTP/2 aynı yöntemleri ve durum kodlarını korur, ancak çerçeveleme yapısını ikili (binary) formata dönüştürür. Birçok istek, bağımsız akışlar olarak tek bir bağlantıyı paylaşır ve tekrarlanan başlık metni sıkıştırılır; modern bir istek çok fazla başlık verisi taşıdığı için bu önemlidir. Bağlantı hala TCP olduğundan, kaybolan tek bir paket, yeniden iletim gelene kadar o bağlantıdaki tüm akışları durdurur. Sıra başı engelleme sorunu ortadan kalkmamıştır; HTTP katmanından taşıma katmanına taşınmıştır. Server push özelliği HTTP/2'nin bir parçasıydı ancak Chrome'un 2022'de desteği kaldırması nedeniyle pratikte artık kullanılmamaktadır.
HTTP/3 yine aynı semantiği korur ve TCP'yi, UDP (user datagram protocol) üzerine inşa edilmiş bir taşıma protokolü olan QUIC ile değiştirir. QUIC akışları tamamen bağımsızdır, bu nedenle kaybolan bir paket yalnızca ait olduğu akışı durdurur. TLS 1.3, üzerine katman olarak eklenmek yerine QUIC el sıkışmasının içine yerleştirilmiştir, bu nedenle yeni bir bağlantı daha az gidiş-dönüş (round trip) gerektirir. Bunun iki pratik sonucu vardır: UDP 443 numaralı port yol üzerindeki her güvenlik duvarında açık olmalıdır ve UDP trafiğini kısıtlayan veya engelleyen herhangi bir ağ, istemcileri HTTP/2'ye geri dönmeye zorlar.
Somut olarak sizin için neler değişiyor? Tarayıcılar asla HTTP/3 ile başlamaz. HTTP/2 veya HTTP/1.1 üzerinden bağlanırlar, yanıtta bir Alt-Svc: h3=":443"; ma=86400 başlığı görürler ve o ana bilgisayara sonraki bağlantılar için HTTP/3 kullanırlar. Dolayısıyla bu başlık isteğe bağlı bir süsleme değildir. Bu, keşif mekanizmasıdır. Nginx'te HTTP/2, 1.25.1 sürümüyle kendi yönergesi haline gelmiştir (eski listen ... http2 parametresinin yerini alan server bloğu içindeki http2 on;), QUIC ise 1.25.0 mainline sürümünde gelmiştir; burada bir HTTP/3 sitesi, normal listen 443 ssl; ile birlikte listen 443 quic reuseport; gerektirir.
Proxy'lerin bu konudaki olgunluk seviyeleri farklıdır ve bunu fiilen çalıştırdığınız sürümle karşılaştırmanız gerekir. Ağustos 2026 itibarıyla Caddy, HTTP/3'ü varsayılan olarak herhangi bir yapılandırma gerektirmeden sunar. Nginx, yukarıda açıklanan Alt-Svc başlığına ek olarak açık bir quic dinleyicisine ihtiyaç duyar. Traefik, bunu giriş noktası bazında açık bir http3 seçeneği ile etkinleştirir. TLS sonlandırmasını birden fazla Docker uygulamasının önündeki Traefik üzerinde yapıyorsanız, ziyaretçilerinizin aldığı protokol sürümü orada belirlenir ve proxy'den container'ınıza olan bağlantı, tarayıcının ne müzakere ettiğinden bağımsız olarak genellikle düz HTTP/1.1'dir.
Varsaymak yerine doğrulayın. curl --http3 -sS -o /dev/null -D - https://example.com/ yalnızca curl -V özellikleri arasında HTTP3 listelenmişse çalışır ve çoğu dağıtım paketi bunu içermez. Güvenilir kontrol yöntemi kendi günlük kayıtlarınızdır: biçime $server_protocol ekleyin ve gerçek tarayıcıların ne müzakere ettiğini okuyun. Bunların öncesinde, UDP 443'ün gerçekten açık olduğunu onaylayın; çünkü yalnızca TCP 443'e izin veren bir güvenlik duvarı, site HTTP/2 üzerinden çalışmaya devam ederken HTTP/3'ün sessizce başarısız olmasına neden olur. Linux sunucunuzda hangi portların açık ve dinlemede olduğunu bilmek, kontrol etmeniz gereken ilk şeydir.
HTTPS: HTTP protokoldür, TLS ise sarmalayıcıdır
HTTPS ayrı bir protokol değildir. TLS oturumu içinde taşınan aynı istekler ve aynı durum kodlarıdır. 80 numaralı port bunları açık metin olarak, 443 numaralı port ise şifreli olarak taşır. TLS el sıkışması önce tamamlanır, ardından HTTP isteği şifreli kanal üzerinden iletilir. Bu sıralama nedeniyle bir sertifika sorunu hiçbir zaman bir durum koduyla ilişkilendirilmez: hata, tek bir HTTP baytı gönderilmeden önce gerçekleştiği için numaralandırılacak bir yanıt yoktur.
Birden fazla site barındıran bir sunucuda bir sıralama detayı önem taşır. Sertifika, herhangi bir HTTP başlığı mevcut olmadan önce ana bilgisayar adını açık metin olarak taşıyan TLS el sıkışmasındaki bir alan olan SNI (server name indication) kullanılarak seçilir. Bu nedenle sunucu önce SNI üzerinden bir sertifika seçer, ardından ikinci adımda Host başlığından bir sanal ana bilgisayar seçer. Bunlar normalde birbiriyle uyumlu olan iki ayrı arama işlemidir. Uyumsuz olduklarında, tarayıcı NET::ERR_CERT_COMMON_NAME_INVALID gibi bir isim uyuşmazlığı hatası gösterir ve hiçbir istek göndermez; çünkü varsayılan sunucunuzun sertifikası, kapsamadığı bir isim için sunulmuştur.
Halka açık bir site için gerçek bir sertifika alın ve otomatik olarak yenilenmesini sağlayın. Certbot with Let's Encrypt on nginx, sertifika yollarını sunucu bloğunuza yazar ve yenileme zamanlayıcısını sizin için kurar. Dahili bir isim veya kendi ağınızdaki çıplak bir IP adresi gibi hiçbir genel otoritenin doğrulayamayacağı bir ana bilgisayar adı için, her istemciye güvenmesi gerektiğinin söylenmesi şartıyla a self-signed certificate on Ubuntu dürüst bir seçenektir.
TLS çalıştığında, 80 numaralı porttaki her şeyi 443 numaralı porta yönlendirin:
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}Strict-Transport-Security başlığını yalnızca emin olduğunuzda ekleyin. add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always; başlığı, tarayıcılara o ana bilgisayar adı için düz HTTP'yi iki yıl boyunca reddetmelerini söyler ve tarayıcılar bunu kendi önbelleklerinden uygular; bu da başlığı daha sonra kaldırmanın işlemi geri almayacağı anlamına gelir. Birkaç saatlik bir max-age ile başlayın, her alt alan adının gerçekten HTTPS üzerinde olduğunu doğrulayın ve ardından süreyi artırın.
FAQ
HTTP ve HTTPS arasındaki fark nedir?
HTTPS, bir TLS (transport layer security) oturumu içerisinde gönderilen HTTP'dir. Metotlar ve durum kodları aynıdır. Değişen şey, baytların istemci ile TLS sonlandırıcısı arasında şifrelenmesi ve varsayılan portun 80'den 443'e taşınmasıdır. TLS el sıkışması, ilk HTTP baytı gönderilmeden önce tamamlandığı için sertifika hataları hiçbir zaman bir durum kodu üretmez; bu nedenle tarayıcı sertifika uyarısı, 403 gibi bir sayı yerine NET::ERR_CERT_COMMON_NAME_INVALID gibi bir hata adı gösterir.
Sitem neden 502 Bad Gateway hatası veriyor?
Nginx'ten gelen bir 502, nginx'in proxy yaptığı upstream servisinden kullanılabilir bir yanıt alamadığı anlamına gelir; yani ziyaretçinin isteği doğrudur ancak nginx'in arkasındaki bir şey hatalıdır. /var/log/nginx/error.log kısmını okuyun. connect() failed (111: Connection refused) while connecting to upstream, proxy_pass içindeki adres ve portta hiçbir servisin dinleme yapmadığı anlamına gelir; bu nedenle uygulamanın çalıştığını ve beklediğiniz yere bağlandığını kontrol edin. no live upstreams while connecting to upstream, upstream bloğundaki her sunucunun tekrarlanan hatalardan sonra devre dışı bırakıldığı anlamına gelir. Bağlantıyı kabul edip ardından proxy_read_timeout süresi içinde yanıt veremeyen upstream durumları için 504 Gateway Timeout ile karşılaştırın.
Erişim loglarım neden her ziyaretçi için aynı IP adresini gösteriyor?
Çünkü $remote_addr, TCP bağlantısını açan adresi kaydeder; bir reverse proxy veya içerik dağıtım ağının (CDN) arkasında bu adres proxy'nin kendisidir. Ziyaretçinin adresi bunun yerine X-Forwarded-For başlığında gelir. Proxy üzerinde proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ayarını yapın, ardından alıcı nginx üzerinde set_real_ip_from değerini proxy'nin adres aralığına ayarlayın ve real_ip_header X-Forwarded-For; kullanın. Yalnızca kontrol ettiğiniz aralıkları listeleyin; çünkü bu başlık herhangi bir istemcinin gönderebileceği bir metindir. Tüm internete güvenmek, ziyaretçinin logladığınız ve hız sınırlaması uyguladığınız adresi seçmesine olanak tanır.
HTTP/2 veya HTTP/3'ü açmam gerekir mi?
HTTP/2'yi açmak faydalıdır; çünkü halihazırda TLS kullanan bir sitede tek bir direktif ile etkinleştirilir ve çok sayıda küçük dosya içeren sayfaları yavaşlatan bağlantı başına istek sınırını ortadan kaldırır. HTTP/3 daha küçük ve etkisi daha belirsiz bir kazançtır; ayrıca açık bir UDP 443 portu ve QUIC desteğiyle derlenmiş bir proxy gerektirir. Tarayıcıların HTTP/3'e yalnızca daha önceki bir yanıtta Alt-Svc başlığını gördükten sonra geçiş yaptığını unutmayın; bu başlık olmadan listen satırınız ne derse desin hiçbir şey değişmez. Log formatınıza $server_protocol ekleyin ve vakit harcamadan önce ziyaretçilerin gerçekte neyi müzakere ettiğini ölçün.
Dosya mevcut olduğu halde 403 Forbidden ne anlama gelir?
Statik bir sitede 403 hatası genellikle bir HTTP kuralından ziyade dosya sistemi izinleriyle ilgilidir. /var/log/nginx/error.log içindeki open() ... failed (13: Permission denied), nginx çalışan kullanıcısının dosyayı okuyamadığı anlamına gelir; bu durum genellikle dosya modunun kendisinden ziyade, üst dizinin diğer kullanıcılar için çalıştırma (execute) iznine sahip olmamasından kaynaklanır. directory index of ... is forbidden, isteğin dizin listeleme (autoindex) kapalıyken autoindex bir dizine yönlendiği anlamına gelir. Eşleşen location bloğundaki açık bir deny kuralı da 403 döndürür; bu nedenle hata günlüğü bir şey söylemediğinde ilgili bloğu inceleyin.