Nginx ile Ters Vekil (Reverse Proxy): Gunicorn Uygulamasını Güvenle Yayınlamak
Flask/gunicorn uygulamasının önüne Nginx koymak: kurulum, sunucu bloğu, gerçek istemci adresi, istek sınırları, güvenlik başlıkları, günlükler ve yaygın hataların çözümü.
Gunicorn bir uygulama sunucusudur; internete doğrudan açılmak için tasarlanmamıştır. Yavaş istemcilere, sahte başlıklara ve büyük yüklere karşı korumasızdır. Önüne Nginx gibi bir ters vekil koymak hem güvenlik hem performans sağlar: bağlantıları Nginx karşılar, yalnızca temiz istekleri uygulamaya iletir. Bu rehberde küçük bir Flask uygulaması için pratik bir kurulum yapıyoruz.
Mimari
İstemci → (Cloudflare Tunnel ya da doğrudan) → Nginx (80/443) → gunicorn (127.0.0.1:8000) → Flask. Gunicorn yalnızca yerel adreste dinler, dışarıdan erişilemez (systemd servis kurulumu). Tünel kullanıyorsanız (tünel rehberi) Nginx'i tüneli ve uygulamayı arasına koyabilirsiniz; her ikisi de mümkündür, ama gereksiz katmandan kaçının: tek uygulama ve tünel varsa Nginx zorunlu değildir.
Kurulum
sudo apt install nginx -y
sudo systemctl enable --now nginx
Sunucu bloğunu /etc/nginx/sites-available/panel dosyasına yazın:
server {
listen 80;
server_name panel.ornek.com;
client_max_body_size 5m;
location /static/ {
alias /home/panel/uygulama/static/;
expires 7d;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 60s;
}
}
Etkinleştirin: sudo ln -s /etc/nginx/sites-available/panel /etc/nginx/sites-enabled/, sudo nginx -t ile sözdizimini doğrulayın, sudo systemctl reload nginx ile yükleyin. Her yapılandırma değişikliğinden önce nginx -t çalıştırmak, hatalı bir ayarla servisi düşürmenizi engeller.
Gerçek istemci adresi
Uygulama Nginx'in arkasında olduğundan tüm istekler 127.0.0.1'den gelmiş görünür. X-Forwarded-For başlığı gerçek adresi taşır, ama istemci bu başlığı sahte gönderebilir. Flask'te ProxyFix gibi bir ara katman kullanıyorsanız yalnızca güvendiğiniz vekil sayısını (genellikle 1) belirtin. Böylece hatalı giriş sınırlaması ve denetim kayıtları sahte adresle atlatılamaz (Flask güvenli giriş).
İstek sınırları
Küçük bir sunucuyu korumak için Nginx'te hız sınırlaması tanımlayabilirsiniz. http bloğunda:
limit_req_zone $binary_remote_addr zone=giris:10m rate=5r/m;
Giriş sayfasına location /giris { limit_req zone=giris burst=5 nodelay; proxy_pass ...; } ekleyerek dakikada 5 istekle sınırlayabilirsiniz; bu, parola deneme saldırılarını yavaşlatır. Uygulama içindeki hatalı giriş sınırıyla birlikte iki katman olur.
Güvenlik başlıkları
server bloğuna şunları ekleyin:
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;
server_tokens off;
server_tokens off, hata sayfalarında Nginx sürümünün görünmesini engeller. HTTPS kullanıyorsanız (Let's Encrypt ya da tünelin TLS'i) Strict-Transport-Security başlığı da eklenebilir; ama bunu yalnızca HTTPS'in kalıcı çalıştığından emin olduktan sonra yapın.
Günlükler ve tanı
Nginx günlükleri /var/log/nginx/access.log ve error.log dosyalarındadır. Sık hatalar:
| Hata | Anlam | Çözüm |
|---|---|---|
| 502 Bad Gateway | Gunicorn çalışmıyor ya da yanlış port | systemctl status, curl localhost:8000 |
| 504 Gateway Timeout | Uygulama çok yavaş | proxy_read_timeout, yavaş sorguyu bul |
| 413 Request Entity Too Large | Yükleme client_max_body_size'ı aştı |
Sınırı artır |
| 403 / 404 statik dosya | alias yolu ya da izin yanlış |
chmod, yol sonundaki / |
Günlük okuma alışkanlıkları için journalctl rehberi; disk dolmasın diye günlük döndürme (logrotate) Nginx kurulumunda hazır gelir. Kaynak tüketimi için bellek ve işlemci tanılama yazısına bakın.
Güvenlik duvarı
Nginx yalnızca 80 ve 443'ü dinlemeli; gunicorn portu dışarıya kapalı olmalı. sudo ufw allow 'Nginx Full' yeterlidir (UFW rehberi). Port taraması ile doğrulayın.
Sık sorulan sorular
Nginx mi Caddy mi? Caddy otomatik HTTPS ve daha kısa yapılandırma sunar; Nginx daha yaygındır ve çok daha fazla kaynakla belgelenmiştir. İkisi de küçük sunucuda iyi çalışır.
Pi 3'te Nginx yük bindirir mi? Hayır; birkaç megabayt bellek kullanır, statik dosyaları uygulamadan çok daha verimli sunar.
Websocket ya da uzun istekler? Ek başlıklar (Upgrade, Connection) ve daha uzun zaman aşımı gerekir.