اجرای برنامه پشت CDN
اجرای Songbird پشت یک CDN (شبکه توزیع محتوا) به شدت توصیه میشود، و در بسیاری از موارد — بهخصوص در محیطهای با محدودیت شبکه — ضروری است.
چرا به CDN نیاز دارید
در کشورهایی با محدودیتهای شدید اینترنت — ایران مثال بارز آن است — سرورهای خودمیزبان با یک الگوی ثابت روبرو میشوند: سرور در ابتدا درست کار میکند، اما پس از گذشت مقدار معینی از ترافیک، آدرس IP آن توسط ISPهای مختلف در مناطق مختلف شناسایی و مسدود میشود. نتیجه این است که کاربران یک ISP میتوانند به سرور دسترسی داشته باشند، در حالی که کاربران ISP دیگری نمیتوانند، و وضعیت معمولاً با گذشت زمان بدتر میشود.
مسیریابی ترافیک از طریق CDN این مشکل را در سطح زیرساخت حل میکند:
- CDN آدرسهای IP خودش را به اینترنت عمومی نشان میدهد، نه IP سرور شما.
- نودهای edge یک CDN به صورت جغرافیایی توزیع شدهاند و از محدودههای IP استفاده میکنند که مسدود کردن کامل آنها بسیار دشوارتر است.
- IP واقعی سرور شما پشت CDN پنهان میماند و نمیتوان آن را مستقیماً هدف قرار داد.
- اکثر ارائهدهندگان CDN بهطور خودکار کاهش DDoS، پایاندادن به TLS و کش را هم انجام میدهند.
نحوه عملکرد
کاربر → edge CDN (IP پروکسیشده) → سرور شما (IP واقعی، پنهان)CDN درخواست کاربر را دریافت میکند، آن را به سرور شما ارسال میکند و پاسخ را برمیگرداند. سرور شما فقط با CDN صحبت میکند، نه مستقیماً با کاربران نهایی.
راهاندازی (مثال Cloudflare)
Cloudflare پرکاربردترین گزینه برای این کار است و یک پلن رایگان سخاوتمندانه دارد. همان اصول برای سایر ارائهدهندگان CDN نیز صدق میکند.
۱. افزودن دامنه به Cloudflare
در cloudflare.com ثبتنام کنید، دامنهتان را اضافه کنید و nameserver های دامنه را به موارد ارائهشده توسط Cloudflare تغییر دهید. این کار مدیریت DNS را به Cloudflare واگذار میکند.
۲. ایجاد A record با پروکسی فعال
در داشبورد DNS Cloudflare، یک A record برای زیردامنهتان بسازید:
| نوع | نام | محتوا | وضعیت پروکسی |
|---|---|---|---|
| A | chat (یا @ برای apex) | آدرس-IP-سرور-شما | ✅ پروکسیشده (ابر نارنجی) |
نکته کلیدی این است که وضعیت پروکسی باید روشن باشد (آیکون ابر نارنجی در Cloudflare). این همان چیزی است که ترافیک را از طریق edge Cloudflare مسیریابی میکند، به جای اینکه مستقیماً به سرور شما اشاره کند. اگر آن را روی DNS-only (ابر خاکستری) تنظیم کنید، IP سرور شما افشا میشود و تمام حفاظت را از دست میدهید.
۳. تطابق پورت
اینجاست که اکثر افراد گیر میکنند.
بهطور پیشفرض، Cloudflare فقط مجموعه محدودی از پورتها را در پلن رایگان پروکسی میکند. پورت 443 (HTTPS) همیشه پروکسی میشود. اگر CLIENT_PORT برنامهتان 443 باشد، نیازی به پیکربندی بیشتر نیست.
اگر روی یک پورت غیراستاندارد اجرا میکنید (مثلاً CLIENT_PORT=8443 یا CLIENT_PORT=2053)، دو گزینه دارید:
گزینه الف — استفاده از یک پورت پشتیبانیشده توسط Cloudflare
Cloudflare این پورتهای HTTPS را در پلن رایگان پروکسی میکند: 443، 2053، 2083، 2087، 2096، 8443. CLIENT_PORT را در .env خود روی یکی از اینها تنظیم کنید و دستورالعمل listen در Nginx را هم تطبیق دهید.
گزینه ب — استفاده از پورت 443
سادهترین مسیر. CLIENT_PORT=443 را در .env تنظیم کنید و Nginx را طوری پیکربندی کنید که روی 443 گوش دهد. این همیشه با هر پروکسی CDN کار میکند.
TIP
هنگام استفاده از اسکریپت نصب، میتوانید CLIENT_PORT را از منوی Edit Settings تغییر دهید تا بهطور خودکار بازسازی و اعمال شود.
۴. تنظیم SSL/TLS روی Full (strict)
در Cloudflare: SSL/TLS → Overview → Full (strict).
| حالت | عملکرد |
|---|---|
| Flexible | Cloudflare → سرور شما از طریق HTTP ساده. از این استفاده نکنید. |
| Full | Cloudflare → سرور شما از طریق HTTPS (گواهی self-signed قبول میکند). |
| Full (strict) | Cloudflare → سرور شما از طریق HTTPS (گواهی معتبر لازم دارد). توصیهشده. |
حالت Full (strict) یعنی اتصال بین Cloudflare و سرور شما هم رمزنگاریشده و تأییدشده است. این نیازمند یک گواهی SSL معتبر روی سرور شماست — از Certbot یا Cloudflare Origin Certificate.
INFO
اگر از اسکریپت نصب یا Certbot برای SSL استفاده کردهاید، قبلاً یک گواهی معتبر دارید و Full (strict) کار میکند. اگر از یک گواهی self-signed استفاده کردهاید، به جای آن از حالت Full استفاده کنید.
۵. حفظ IP واقعی بازدیدکنندگان در Nginx (اختیاری)
وقتی ترافیک از طریق Cloudflare میآید، IPای که Nginx میبیند یک IP edge Cloudflare است، نه IP واقعی بازدیدکننده. اما سرور Node.js در Songbird این موضوع را خودش به درستی مدیریت میکند — تنظیم app.set('trust proxy', 1) در آن وجود دارد که به Express میگوید IP واقعی کلاینت را از هدر X-Forwarded-For بخواند؛ هدری که Cloudflare همیشه ارسال میکند. یعنی rate limiting و تمام منطق IP-aware در Songbird بدون هیچ پیکربندی اضافهای در Nginx، پشت CDN به درستی کار میکنند.
تنها چیزی که بدون این مرحله از دست میدهید، IPهای دقیق در لاگهای دسترسی Nginx است. اگر این برای شما مهم است، موارد زیر را داخل بلوک server {} در کانفیگ Nginx اضافه کنید:
# اعتماد به محدودههای IP Cloudflare و خواندن IP واقعی کلاینت از هدر.
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;
real_ip_header CF-Connecting-IP;سپس Nginx را reload کنید:
sudo nginx -t
sudo systemctl reload nginxINFO
Cloudflare بهصورت دورهای محدودههای IP خود را بهروز میکند. لیست کامل و بهروز در cloudflare.com/ips موجود است.
استفاده از سایر ارائهدهندگان CDN
همان الگو برای سایر ارائهدهندگان CDN (ابر آروان، Fastly، BunnyCDN و غیره) نیز صدق میکند:
| مرحله | کار لازم |
|---|---|
| DNS | یک A record بسازید که به IP سرور شما اشاره کند با پروکسی فعال. |
| پورت | از پورتی که CDN پروکسی پشتیبانی میکند استفاده کنید، یا port forwarding را در داشبورد CDN پیکربندی کنید. |
| TLS | HTTPS را بین CDN و سرور origin خود فعال کنید. |
| IP واقعی | Nginx را طوری پیکربندی کنید که به محدودههای IP CDN اعتماد کند و IP واقعی را از هدر مناسب بخواند (معمولاً CF-Connecting-IP، X-Real-IP یا X-Forwarded-For بسته به ارائهدهنده). |
TIP
ابر آروان یک ارائهدهنده CDN ایرانی محبوب است که برای سرورهایی که در ایران هستند یا از ایران در دسترس هستند به خوبی کار میکند، و از همان الگوی A record + پروکسی توضیح داده شده در بالا پشتیبانی میکند.
SSE و اتصالات طولانیمدت
Songbird از Server-Sent Events (SSE) برای بهروزرسانیهای realtime استفاده میکند. SSE نیازمند یک اتصال HTTP پایدار است که باز بماند. برخی پیکربندیهای CDN اتصالات بیکار یا طولانیمدت را میبندند.
اگر کاربران تجربه میکنند که پیامها فقط پس از refresh صفحه بارگذاری میشوند (نشانه خرابی SSE)، بررسی کنید:
- Cloudflare: HTTP/2 را در تنظیمات Speed فعال کنید. Cloudflare بهطور بومی از SSE از طریق HTTP/2 پشتیبانی میکند. همچنین مطمئن شوید مسیر
/api/eventsکش نمیشود — یک Cache Rule اضافه کنید تا کش برای آن مسیر bypass شود. - Response buffering: مطمئن شوید
proxy_buffering offوadd_header X-Accel-Buffering noدر بلوک location/api/eventsدر Nginx باقی مانده باشند. به کانفیگ Nginx مراجعه کنید. - تنظیمات timeout: در Cloudflare، timeout پروکسی در پلن رایگان بهطور پیشفرض ۱۰۰ ثانیه است. کلاینت Songbird بهطور خودکار دوباره متصل میشود، بنابراین این قابل قبول است، اما ارتقا به پلن پولی امکان timeout های طولانیتر را میدهد.