بیشتر اپلیکیشنها پشت یک reverse proxy بالا میآیند: Nginx یک پورت عمومی (۸۰ و ۴۴۳) را میگیرد، TLS را خاتمه میدهد، درخواستها را به برنامه میفرستد و در برابر ترافیک بد سپر میشود. این راهنما یک کانفیگ تمیز و امن را قدمبهقدم میسازد و میگوید هر خط چرا لازم است.
سادهترین reverse proxy
برنامه روی 127.0.0.1:3000 گوش میدهد و میخواهیم با example.com در دسترس باشد. فایل را در /etc/nginx/conf.d/example.conf (یا sites-available) بگذارید:
server {
listen 80;
server_name example.com www.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
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_set_header کوچکاند ولی مهم: بدون Host برنامه نمیداند کاربر کدام دامنه را خواسته؛ بدون X-Forwarded-* هر درخواست از 127.0.0.1 و با http به نظر میرسد، که لینکهای بازگشتی و لاگها را خراب میکند. ابزار زیر دقیقاً همین ساختار را از فرم میسازد و کانفیگ موجودتان را هم برای نبود این هدرها بررسی میکند.
HTTPS و ریدایرکت از HTTP
بعد از گرفتن گواهی (مثلاً با Certbot و Let’s Encrypt)، یک server block برای ۸۰ فقط ریدایرکت میکند و یکی برای ۴۴۳ کار اصلی را میکند:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
http2 on; # در nginx ≥ 1.25.1؛ در نسخههای قدیمی: listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
add_header Strict-Transport-Security "max-age=31536000" always;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}
ssl_certificate باید به fullchain.pem اشاره کند، نه فقط به گواهی دامنه. اگر زنجیرهی میانی ارسال نشود، بعضی کلاینتها (و بسیاری از ابزارهای خط فرمان) خطای «گواهی معتبر نیست» میدهند در حالیکه مرورگر دسکتاپ ممکن است سالم نشان بدهد.بعد از فعالسازی، وضعیت گواهی، تاریخ انقضا و کاملبودن زنجیره را بررسی کنید. HSTS را هم بعد از اطمینان از پایداری HTTPS فعال کنید؛ چون مرورگر تا پایان max-age فقط با HTTPS به دامنه وصل میشود و برگشتدادن آن سخت است.
SSLSSL Certificate Checkerتاریخ انقضا، SAN و زنجیرهی گواهی دامنهی خود را بررسی کنید.WebSocket و اتصالهای بلندمدت
WebSocket با یک درخواست HTTP Upgrade شروع میشود و Nginx بهطور پیشفرض آن هدرها را نمیفرستد. اضافه کنید:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
location /ws/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s; # وگرنه اتصال بیکار بعد از ۶۰ ثانیه بسته میشود
}
بلوک map باید در سطح http (بیرون از server) باشد؛ فایلهای داخل conf.d بهطور پیشفرض داخل همان سطح include میشوند.
Upstream، keepalive و چند نمونهی برنامه
وقتی چند نمونه از برنامه دارید یا میخواهید اتصالهای به upstream را نگه دارید، یک بلوک upstream تعریف کنید:
upstream app_backend {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
keepalive 32;
}
server {
# ...
location / {
proxy_pass http://app_backend;
proxy_http_version 1.1;
proxy_set_header Connection ""; # لازم برای keepalive به upstream
# ... بقیهی هدرها
}
}
محدودیت نرخ، حجم و زمان
سه تنظیم کوچک جلوی بخش بزرگی از مشکلات را میگیرند:
# در سطح http:
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
# ...
client_max_body_size 10m; # حداکثر حجم آپلود؛ پیشفرض فقط 1m است
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://127.0.0.1:3000;
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
}
}
limit_req_zoneیک «سطل» بر اساس IP میسازد؛rate=10r/sیعنی در حالت پایدار ده درخواست در ثانیه وburst=20اجازهی اوج کوتاه میدهد.- خطای
413 Request Entity Too Largeتقریباً همیشه ازclient_max_body_sizeاست. - اگر پشت CDN یا لودبالانسر هستید، IP واقعی کاربر در هدر است؛ برای درستکارکردن
limit_reqباید باset_real_ip_fromوreal_ip_headerآن را بازیابی کنید، وگرنه همهی کاربران با یک IP شمرده میشوند.
عیبیابی 502 و 504
| نشانه | علت محتمل | بررسی |
|---|---|---|
| 502 | برنامه خاموش یا پورت اشتباه | ss -ltnp | grep 3000 و curl -I http://127.0.0.1:3000 |
| 502 (Permission denied) | دسترسی سوکت یا SELinux | در RHEL: setsebool -P httpd_can_network_connect 1 |
| 504 | برنامه کند است | لاگ برنامه؛ سپس proxy_read_timeout |
| 413 | آپلود بزرگتر از حد | client_max_body_size |
| redirect loop | برنامه فکر میکند HTTP است | هدر X-Forwarded-Proto و تنظیم «trust proxy» برنامه |
همیشه قبل از اعمال، پیکربندی را تست کنید و بعد reload بزنید؛ خطای نوشتاری هنگام reload جلوی اعمال را میگیرد، ولی در restart ممکن است سرویس را از دسترس خارج کند:
sudo nginx -t && sudo systemctl reload nginx
sudo tail -f /var/log/nginx/error.log
برای دیدن اینکه از دید بیرون چه میگذرد (کد وضعیت، ریدایرکتها و هدرها):
HTTPHTTP Headers Viewerکد وضعیت، زنجیرهی ریدایرکت و هدرهای امنیتی را بررسی کنید.نصب Nginx روی سرور ایران
پکیجهای رسمی Nginx (نسخههای جدیدتر از مخزن توزیع) را از صفحهی محصول nginx در dacker.ir میتوانید با apt یا dnf از یک مخزن داخلی نصب کنید؛ مراحل افزودن کلید و فایل مخزن در راهنمای نصب پکیجها روی سرور ایران آمده است.
جمعبندی
یک reverse proxy قابلاعتماد با چهار هدر پایه، HTTPS با زنجیرهی کامل، تنظیمهای مناسب برای WebSocket و محدودیت نرخ و حجم ساخته میشود، و هر تغییر باید قبل از reload با nginx -t تست شود. برای دیدن وضعیت واقعی سرویس، لاگها و متریکهای Nginx را هم مانیتور کنید؛ راهاندازی Prometheus و Grafana نقطهی شروع آن است. برای عیبیابی مشکلات دسترسی خارج از Nginx، چکلیست DNS و SSL را ببینید.
پرسشهای متداول
خطای 502 Bad Gateway یعنی چه؟
error.log دلیل دقیق را مینویسد.خطای 504 Gateway Timeout چطور؟
proxy_read_timeout را بالا ببرید؛ در غیر این صورت علت کندی برنامه را پیدا کنید.فرق reload و restart؟
reload پیکربندی جدید را بدون قطع اتصالهای جاری اعمال میکند؛ restart فرایند را میبندد و دوباره باز میکند. در تولید همیشه ابتدا nginx -t و سپس reload.چرا برنامهی من IP کاربر را 127.0.0.1 میبیند؟
X-Forwarded-For و X-Real-IP را بفرستید و برنامه را طوری تنظیم کنید که فقط از پراکسیهای مورد اعتماد به آنها اعتماد کند.