Reverse Proxy چیست؟ راه اندازی ریورس پراکسی با Nginx

Reverse Proxy یا پراکسی معکوس سروری است که جلوی یک یا چند سرور دیگر می‌نشیند، درخواست کاربران را می‌گیرد، به سرور مناسب پشت خودش می‌فرستد و پاسخ را طوری برمی‌گرداند که انگار از خودش آمده است. کاربر فقط با پراکسی حرف می‌زند و سرورهای پشتی را مستقیم نمی‌بیند. Nginx، HAProxy، Apache، Caddy و Traefik رایج‌ترین نرم‌افزارهای این کار هستند و سرویس‌هایی مثل Cloudflare هم برای سایت‌هایی که پشتشان قرار دارند همین نقش را دارند.

Reverse Proxy چه کاری انجام می‌دهد؟

بیشتر سایت‌ها و برنامه‌های تحت وب امروزی پشت یک Reverse Proxy اجرا می‌شوند، چون چند کار را در یک نقطه جمع می‌کند:

  • گواهی SSL روی پراکسی نصب می‌شود و برنامه‌های پشتی می‌توانند با HTTP ساده کار کنند. به این کار TLS Termination می‌گویند.
  • چند برنامه با دامنه‌ها یا مسیرهای مختلف روی یک IP و یک پورت ۴۴۳ سرویس می‌دهند؛ پراکسی بر اساس نام دامنه یا مسیر، هر درخواست را به برنامه خودش می‌فرستد.
  • درخواست‌ها بین چند سرور یکسان تقسیم می‌شوند و اگر یکی از کار بیفتد، بقیه جواب می‌دهند.
  • فایل‌های ثابت و پاسخ‌های قابل کش در خود پراکسی نگه داشته و فشرده می‌شوند و بار سرورهای پشتی کم می‌شود.
  • سرورهای پشتی از اینترنت پنهان می‌مانند و محدودیت نرخ درخواست، فهرست IP مجاز و لاگ همه درخواست‌ها در یک جا اعمال می‌شود.

تفاوت Reverse Proxy و Forward Proxy

هر دو واسط هستند، ولی از طرف دو گروه متفاوت کار می‌کنند. Forward Proxy از طرف کاربران یک شبکه به اینترنت وصل می‌شود؛ مثلاً پراکسی شبکه یک سازمان که ترافیک خروجی کارکنان را کش یا ثبت می‌کند. سایت مقصد به‌جای کاربر، پراکسی را می‌بیند. Reverse Proxy از طرف سرورها کار می‌کند؛ کاربر به‌جای سرور واقعی، پراکسی را می‌بیند.

تفاوت Reverse Proxy و Load Balancer

لودبالانسر درخواست‌ها را بین چند سرور یکسان تقسیم می‌کند. Reverse Proxy می‌تواند همین کار را بکند، ولی کارش لزوماً توزیع بار نیست؛ ممکن است فقط یک سرور پشتش باشد و فقط SSL و مسیریابی را انجام دهد. لودبالانسرها در دو لایه کار می‌کنند: لایه ۴ که فقط اتصال TCP را جابه‌جا می‌کند، و لایه ۷ که محتوای HTTP مثل دامنه و مسیر را می‌خواند. Nginx در عمل هر دو نقش را دارد. HAProxy مخصوص توزیع بار ساخته شده و امکانات بیشتری برای بررسی سلامت سرورها دارد؛ نصب آن را در HAProxy در لینوکس نوشته‌ایم.

راه‌اندازی Reverse Proxy با Nginx

فرض کنید یک برنامه Node.js روی همان سرور و روی پورت ۳۰۰۰ اجرا می‌شود و می‌خواهید با دامنه app.example.com در دسترس باشد. در Ubuntu یک فایل در /etc/nginx/sites-available/app.example.com با این محتوا بسازید:

server {
    listen 80;
    server_name app.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;
    }
}

بعد سایت را فعال کنید، کانفیگ را تست کنید و Nginx را reload کنید:

sudo ln -s /etc/nginx/sites-available/app.example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

هدرهای proxy_set_header به برنامه می‌گویند درخواست اصلی برای کدام دامنه بوده، IP واقعی کاربر چه بوده و کاربر با HTTP آمده یا HTTPS. بدون آن‌ها برنامه همه درخواست‌ها را از 127.0.0.1 می‌بیند و ممکن است لینک‌ها را با آدرس اشتباه بسازد. برای فعال کردن HTTPS روی همین پراکسی، Certbot را طبق راهنمای نصب SSL رایگان اجرا کنید؛ گواهی روی Nginx می‌نشیند و برنامه تغییری لازم ندارد. برای تنظیمات عمومی Nginx هم وب سرور لینوکس: نصب و پیکربندی پیشرفته را ببینید.

WebSocket

برنامه‌هایی که از WebSocket استفاده می‌کنند، مثل چت یا داشبوردهای زنده، پشت این کانفیگ ساده قطع و وصل می‌شوند. این سه خط را به همان location اضافه کنید:

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

اسلش انتهای proxy_pass

یک جزئیات کوچک که زیاد اشتباه می‌شود: اگر در proxy_pass بعد از آدرس و پورت، مسیری بنویسید (حتی فقط یک اسلش)، Nginx بخش منطبق location را از آدرس حذف می‌کند. با کانفیگ زیر، درخواست /api/users به صورت /users به برنامه می‌رسد. بدون اسلش انتهایی، همان /api/users فرستاده می‌شود.

location /api/ {
    proxy_pass http://127.0.0.1:8080/;
}

زمان انتظار و حجم آپلود

Nginx به‌طور پیش‌فرض ۶۰ ثانیه منتظر پاسخ برنامه می‌ماند و بعد خطای 504 می‌دهد. اگر گزارش یا خروجی سنگینی دارید که بیشتر طول می‌کشد، proxy_read_timeout را فقط برای همان مسیر بالا ببرید. حد پیش‌فرض حجم درخواست هم یک مگابایت است؛ آپلود فایل بزرگ‌تر خطای 413 می‌دهد و با client_max_body_size تغییر می‌کند.

توزیع بار بین چند سرور با Nginx

با بلوک upstream، Nginx درخواست‌ها را به نوبت بین چند سرور تقسیم می‌کند:

upstream app_servers {
    server 10.0.0.11:3000 max_fails=3 fail_timeout=30s;
    server 10.0.0.12:3000 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://app_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

اگر سروری سه بار پشت سر هم جواب ندهد، Nginx تا ۳۰ ثانیه آن را کنار می‌گذارد. این بررسی سلامت غیرفعال است، یعنی فقط بر اساس درخواست‌های واقعی کاربران انجام می‌شود. بررسی فعال و دوره‌ای سلامت سرورها در نسخه متن‌باز Nginx وجود ندارد و برای آن معمولاً HAProxy انتخاب می‌شود. اگر برنامه وضعیت کاربر را در حافظه خود سرور نگه می‌دارد، مثل سشن‌های PHP، باید سشن‌ها را در Redis یا دیتابیس مشترک بگذارید تا کاربر با رفتن به سرور دیگر از حساب خارج نشود.

IP واقعی کاربر پشت Reverse Proxy

برنامه‌ای که پشت پراکسی است، IP پراکسی را به‌جای IP کاربر می‌بیند. هدر X-Forwarded-For که بالاتر تنظیم کردیم IP اصلی را منتقل می‌کند، ولی برنامه فقط وقتی باید به آن اعتماد کند که درخواست واقعاً از پراکسی خودتان آمده باشد؛ وگرنه هر کسی می‌تواند این هدر را جعل کند.

اگر خود Nginx پشت Cloudflare است، ماژول real_ip آن IP واقعی را از هدر Cloudflare می‌خواند. محدوده‌های IP را از فهرست رسمی Cloudflare بردارید و برای هر محدوده یک خط set_real_ip_from بنویسید:

set_real_ip_from 173.245.48.0/20;
real_ip_header CF-Connecting-IP;

خطاهای رایج پشت Reverse Proxy

  • خطای 502: برنامه پشتی خاموش است یا روی آدرس و پورتی که در proxy_pass نوشته‌اید گوش نمی‌دهد. عیب‌یابی کامل آن در خطای 502 Bad Gateway آمده است.
  • خطای 504: برنامه دیرتر از proxy_read_timeout جواب داده است.
  • خطای 413: حجم آپلود از client_max_body_size بیشتر است.
  • ریدایرکت بی‌پایان بعد از فعال کردن HTTPS: برنامه نمی‌داند کاربر با HTTPS آمده و مدام به HTTPS ریدایرکت می‌کند. هدر X-Forwarded-Proto را بفرستید و برنامه را طوری تنظیم کنید که آن را بخواند.
  • خطای Permission denied در AlmaLinux و Rocky: SELinux اتصال Nginx به پورت برنامه را بسته است و با setsebool -P httpd_can_network_connect 1 باز می‌شود.

سوالات متداول

آیا Cloudflare یک Reverse Proxy است؟

بله. وقتی پراکسی Cloudflare برای یک رکورد روشن است، کاربران به سرورهای Cloudflare وصل می‌شوند و Cloudflare درخواست را به سرور شما می‌فرستد. به همین دلیل IP سرور اصلی پنهان می‌ماند و خطاهای ارتباط Cloudflare با سرور شما با کدهای مخصوص خودش، مثل 521 و 522، نمایش داده می‌شوند.

Reverse Proxy امنیت را بالا می‌برد؟

به‌تنهایی نه، ولی جای مناسبی برای اعمال کنترل‌های امنیتی است. سرورهای پشتی از اینترنت پنهان می‌مانند، SSL در یک جا مدیریت می‌شود و محدودیت نرخ درخواست، فهرست IP مجاز و فایروال برنامه وب (WAF) را می‌توان جلوی همه برنامه‌ها گذاشت.

Nginx بهتر است یا HAProxy؟

اگر علاوه بر پراکسی، فایل‌های ثابت هم سرو می‌کنید یا به کش و مسیریابی بر اساس دامنه و مسیر نیاز دارید، Nginx انتخاب ساده‌تری است. اگر کار اصلی توزیع بار بین چند سرور با بررسی فعال سلامت و آمار دقیق اتصال‌هاست، HAProxy برای همین کار ساخته شده است. خیلی از زیرساخت‌ها هر دو را با هم به کار می‌برند.

Nginx Proxy Manager چیست؟

یک رابط گرافیکی تحت وب برای Nginx است که معمولاً با Docker اجرا می‌شود. با آن می‌توانید بدون نوشتن کانفیگ، دامنه‌ها را به برنامه‌های مختلف وصل کنید و گواهی Let’s Encrypt بگیرید. برای چند برنامه ساده مناسب است، ولی تنظیمات پیشرفته هنوز به نوشتن کانفیگ Nginx نیاز دارند.

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *