حل مشكلة عرض جميع عناوين IP للمستخدمين على أنها من Cloudflare بدلاً من عناوين IP الحقيقية للمتصفح في Discourse المُنفَّذ عبر 1Panel

لقد قمت بتثبيت 1Panel على خادم VPS الخاص بي، وتثبيت Discourse (عن طريق حاوية)، واستخدمت OpenResty (عن طريق حاوية) كوسيط عكسي. يتم استضافة النطاق في Cloudflare، وقمت بتفعيل خدمة CDN (السحابة الصفراء). فيما يلي حل لمشكلة ظهور عنوان IP للمستخدمين وكأنه قادم من Cloudflare، بدلاً من عنوان IP الخاص بمتصفح المستخدم.

أولاً: إنشاء مهمة مجدولة في 1Panel لتحميل قائمة عناوين IP الخاصة بـ Cloudflare أسبوعياً، وحفظها في دليل تكوين OpenResty.

  1. انقر على “المهام المجدولة” في القائمة الجانبية اليسرى في 1Panel.

  2. انقر على “إنشاء مهمة مجدولة” في الزاوية العلوية اليمنى.

  3. املأ المعلمات التالية (يمكنك النسخ واللصق مباشرة):

  • نوع المهمة: اختر نص برمجي Shell.

  • اسم المهمة: على سبيل المثال تحديث تلقائي لشبكات IP الخاصة بـ Cloudflare.

  • دورة التنفيذ: يُنصح باختيار أسبوعياً (على سبيل المثال، كل سبت الساعة 03:00 صباحاً).

  • محتوى النص البرمجي: انسخ الكود الكامل أدناه والصقه مباشرة (ملاحظة: يرجى تعديل اسم الحاوية ومسار دليل التكوين في أعلى الكود أولاً):

#!/bin/bash
# منطقة التكوين
CONTAINER_NAME="اسم حاوية openresty في 1Panel"
# قم بتغييره إلى دليل proxy للموقع المحدد
CONF_DIR="/opt/1panel/www/sites/www.نطاق_موقعك.club/proxy"

echo "[$(date)] بدء سحب أحدث شبكات IP من Cloudflare الرسمي..."
TEMP_DIR=$(mktemp -d)

# سحب قائمة IP وتحويلها إلى صيغة يفهمها Nginx
curl -fsS https://www.cloudflare.com/ips-v4 | sed 's/.*/set_real_ip_from &;/' > $TEMP_DIR/cf-ips-v4.conf
curl -fsS https://www.cloudflare.com/ips-v6 | sed 's/.*/set_real_ip_from &;/' > $TEMP_DIR/cf-ips-v6.conf

# التحقق من الملفات ونقلها
if [[ -s $TEMP_DIR/cf-ips-v4.conf ]] && [[ -s $TEMP_DIR/cf-ips-v6.conf ]]; then
    mv $TEMP_DIR/cf-ips-v4.conf $CONF_DIR/
    mv $TEMP_DIR/cf-ips-v6.conf $CONF_DIR/
    echo "[$(date)] تم تحديث ملفات التكوين بنجاح في $CONF_DIR."
else
    echo "[$(date)] خطأ: فشل في سحب عناوين IP الخاصة بـ Cloudflare!"
    rm -rf $TEMP_DIR
    exit 1
fi
rm -rf $TEMP_DIR

# اختبار وإعادة تحميل Nginx
echo "[$(date)] جارٍ اختبار تكوين Nginx..."
if docker exec $CONTAINER_NAME nginx -t; then
    docker exec $CONTAINER_NAME nginx -s reload
    echo "[$(date)] نجاح! تم إعادة تحميل تكوين OpenResty."
else
    echo "[$(date)] فشل! لم يجتز اختبار تكوين Nginx."
    exit 1
fi

بعد إنشاء المهمة، لا داعي لل انتظار حتى يوم السبت، يمكنك الاختبار فوراً: ابحث عن المهمة التي أنشأتها刚才 في قائمة “المهام المجدولة”.

انقر على زر “التقرير” على الجانب الأيمن. تحقق من نافذة السجلات المنبثقة. إذا أظهرت الأسطر الأخيرة نجاح! تم إعادة تحميل تكوين OpenResty، فهذا يعني أن العملية بأكملها تعمل بشكل مثالي داخل 1Panel!

ثانياً: إضافة تكوين realip إلى OpenResty

أنشئ ملفاً جديداً في دليل المضيف /opt/1panel/www/sites/www.نطاق_موقعك/proxy/ (يمكن أن يكون اسم الملف أي شيء، بشرط أن ينتهي بـ .conf ليتم تحميله تلقائياً بواسطة التكوين الرئيسي عبر include *.conf): realip.conf

# استخدم المسار داخل الحاوية
include /www/sites/www.نطاق_موقعك/proxy/cf-ips-v4.conf;
include /www/sites/www.نطاق_موقعك/proxy/cf-ips-v6.conf;

real_ip_header CF-Connecting-IP;
real_ip_recursive on;

ثالثاً: إعادة تحميل OpenResty

docker exec اسم_حاوية_openresty_في_1Panel nginx -t
docker exec اسم_حاوية_openresty_في_1Panel nginx -s reload

رابعاً: التحقق مما إذا كان OpenResty قد حصل على عنوان IP الحقيقي

تحقق من سجل الوصول (access log) الخاص بـ OpenResty:

tail -f /opt/1panel/www/sites/www.نطاق_موقعك/log/access.log

إذا كان التكوين صحيحاً، يجب أن يتحول أول عنوان IP في السجل إلى عنوان IP العام الحقيقي الخاص بك، بدلاً من شبكات Cloudflare مثل 173.245.x.x.

خامساً: جانب Discourse

قم بتعديل ملف app.yml، وأضف المحتوى التالي داخل كتلة run::

  # بعد نشر Discourse عبر Docker، يجب إضافة الأقسام الثلاثة التالية لضمان تمرير عنوان IP الحقيقي لمستخدمي المنتدى
  - file:
      path: /etc/nginx/conf.d/outlets/server/set-real-ip-from-docker.conf
      chmod: 644
      contents: |
        set_real_ip_from 172.16.0.0/12;
        set_real_ip_from 127.0.0.1;
  
  - file:
      path: /etc/nginx/conf.d/outlets/server/real-ip-header.conf
      chmod: 644
      contents: |
        real_ip_header x-forwarded-for;
  
  - file:
      path: /etc/nginx/conf.d/outlets/server/real-ip-recursive.conf
      chmod: 644
      contents: |
        real_ip_recursive on;

بهذه الطريقة، سيقوم Nginx المدمج في Discourse بـ:

  1. الثقة بشبكة Docker (172.16.0.0/12)
  2. قراءة عنوان IP الحقيقي من x-forwarded-for
  3. التحليل التكراري للوكالات المتعددة الطبقات

سادساً: ملاحظات

إضافة - "templates/cloudflare.template.yml" إلى ملف app.yml الخاص بـ Discourse تكون فعالة فقط عندما يكون Discourse مواجهًا مباشرةً لـ Cloudflare. نظرًا لأننا أضفنا وكيلًا عكسيًا OpenResty في الوسط، فإن عنوان IP المصدر الذي تراه حاوية Discourse هو في الواقع بوابة Docker (مثل 172.17.0.1 أو 172.18.0.1)، لذا فإن set_real_ip_from <CloudflareIP> الموجود في هذا القالب لن يتطابق.

لذلك، لا حاجة لإضافة - "templates/cloudflare.template.yml" إلى ملف app.yml الخاص بـ Discourse.


تحديث 03-07-2026

إعجابَين (2)

المراجع

سلسلة الثقة لمعالجة عنوان IP الحقيقي للمستخدم النهائي - وثائق / الاستضافة الذاتية - Discourse Meta

تحديث المنشور الرئيسي للموضوع.