2026年11月12日

2026年11月12日

إعداد Cloudflare مع WordPress: الخوادم الاسمية وSSL وIP الحقيقي وWAF

هذه المقالة نسخة مُوطَّنة من الأصل الياباني. اقرأ الأصل الياباني

تمرّ عملية إضافة Cloudflare إلى WordPress بأربع خطوات بالترتيب: ① إضافة الموقع إلى Cloudflare وتغيير الخوادم الاسمية (Name Servers) للنطاق، ② ضبط وضع التشفير في SSL/TLS على Full (strict)، ③ استعادة عنوان IP الحقيقي للزائر على جهة الخادم، ④ حماية صفحة تسجيل الدخول بقواعد WAF المخصصة. وتتيح الخطة المجانية CDN وSSL والحماية من DDoS والقواعد المخصصة (حتى 5 قواعد).

تشرح هذه المقالة كل إعداد وما يجب التحقق منه بعد التحويل. قد تتغير أسماء شاشات Cloudflare ومواضعها، لذا كُتبت المقالة وفق الوثائق الرسمية (developers.cloudflare.com) كما كانت في نوفمبر 2026.

ما يجب تقريره قبل البدء

  • ستنقل إدارة DNS إلى Cloudflare. لا تتغير الجهة المسجِّلة للنطاق (Registrar)، لكن تعديل سجلات DNS سيتم من شاشة Cloudflare.
  • لا تُمرّر سجلات DNS الخاصة بالبريد (مثل MX) عبر الوكيل (Proxy). الذي يمر عبر Cloudflare هو اتصالات الويب (HTTP/HTTPS) فقط.
  • تأكد من وجود شهادة SSL صالحة على الخادم الأصلي (Origin) الذي يستضيف WordPress. إذا كان HTTPS يعمل بشهادة مثل Let's Encrypt فلا حاجة إلى تغيير شيء.
  • إذا فعّلت DNSSEC لدى الجهة المسجِّلة فعطّله قبل تغيير الخوادم الاسمية. بقاء سجل DS قديم يتسبب في فشل تحليل الأسماء.

الخطوة 1: إضافة الموقع وتغيير الخوادم الاسمية

  1. أنشئ حساب Cloudflare وأضف النطاق من لوحة التحكم (Dashboard). يمكنك اختيار الخطة Free.
  2. تقرأ Cloudflare سجلات DNS الحالية وتعرضها في قائمة، فتحقق من عدم وجود نقص. بعض السجلات لا يمكن قراءتها، لذا قارنها بشاشة إدارة DNS الحالية وأضف المفقود يدويًا.
  3. اجعل حالة الوكيل مفعّلة (السحابة البرتقالية) لسجلات A (أو AAAA وCNAME) الخاصة بموقع الويب. واجعلها معطّلة (DNS only، السحابة الرمادية) لسجلات MX ولسجلات A الخاصة بخادم البريد.
  4. تعرض Cloudflare اسمي خادمين اسميين. يكون الاسم بالصيغة 〇〇.ns.cloudflare.com ويُخصَّص لكل حساب على حدة. استخدم الاسمين اللذين ظهرا في شاشتك، لا الأسماء المذكورة في مقالات أخرى.
  5. في شاشة إدارة الجهة المسجِّلة للنطاق، غيّر الخوادم الاسمية إلى هذين الاسمين.

تحقق من اكتمال التحويل بالأمر التالي. قد يستغرق سريان التغيير بضع ساعات.

# هل أصبحت الخوادم الاسمية هي خادمَي Cloudflare
dig NS example.com +short

# هل يمرّ الطلب عبر Cloudflare (يُعاد server: cloudflare وcf-ray)
curl -sI https://example.com | grep -iE '^(server|cf-ray):'

إذا صارت حالة النطاق نشطة (Active) في شاشة Cloudflare فقد اكتمل التحويل.

الخطوة 2: ضبط SSL/TLS على Full (strict)

في SSL/TLS لدى Cloudflare أوضاع تحدد كيفية التشفير بين الزائر وCloudflare، وبين Cloudflare والخادم الأصلي.

الوضع بين Cloudflare والخادم الأصلي التعامل معه في WordPress
Off بلا تشفير لا يُستخدم
Flexible HTTP (بلا تشفير) لا يُستخدم. يسبب حلقات إعادة توجيه ومحتوى مختلطًا
Full HTTPS (دون التحقق من الشهادة) حل مؤقت إلى أن تجهّز شهادة
Full (strict) HTTPS (مع التحقق من الشهادة) اختر هذا الوضع

يُغيَّر الوضع من صفحة نظرة عامة (Overview) في SSL/TLS بلوحة تحكم Cloudflare. الخيار الافتراضي «Automatic SSL/TLS» يختار تلقائيًا وضعًا آمنًا ضمن ما يدعمه الخادم الأصلي. أما إذا اخترت Full (strict) بنفسك فلن يعمل الموقع بوضع لم تقصده. يمكن أن تكون شهادة الخادم الأصلي من جهة إصدار عامة (مثل Let's Encrypt) أو شهادة Origin CA التي تصدرها Cloudflare.

سبب تجنّب Flexible هو الآتي. في Flexible يصل الطلب إلى الخادم الأصلي عبر HTTP، فيرد WordPress أو الخادم بتحويل إلى HTTPS لأن الطلب جاء بـ HTTP، فتعود Cloudflare لتجلب الصفحة من الخادم الأصلي بـ HTTP من جديد، وهكذا في حلقة متكررة (يعرض المتصفح ERR_TOO_MANY_REDIRECTS). أما مع Full (strict) فيصل الطلب إلى الخادم الأصلي بـ HTTPS أيضًا، فلا حاجة إلى شيفرة إضافية في WordPress تقرأ X-Forwarded-Proto وتعيد كتابة $_SERVER['HTTPS'].

تحقق كذلك من أن «عنوان WordPress (URL)» و«عنوان الموقع (URL)» في «الإعدادات ← عام» (Settings → General) يبدآن بـ https://. وإذا بقيت صور ونحوها بـ http:// فراجع إصلاح المحتوى المختلط.

الخطوة 3: استعادة عنوان IP الحقيقي للزائر

عند المرور عبر Cloudflare يصبح مصدر الاتصال الذي يصل إلى الخادم (REMOTE_ADDR) هو عنوان IP تابعًا لـ Cloudflare. وعندئذ تعامل سجلات الوصول وعناوين IP للتعليقات والإضافات التي تحدّ من محاولات تسجيل الدخول كل الزوار على أنهم عنوان Cloudflare. تمرّر Cloudflare عنوان IP للزائر في ترويسة CF-Connecting-IP، فاضبط الإعداد بحيث لا تثق بهذه الترويسة إلا إذا كان مصدر الاتصال هو Cloudflare.

إذا أعدت كتابة REMOTE_ADDR بقيمة الترويسة دون التحقق من مصدر الاتصال، فسيتمكن من يصل إلى الخادم الأصلي مباشرة دون المرور بـ Cloudflare من ادعاء أي عنوان IP يشاء عبر الترويسة. ولهذا السبب لا تستخدم الشيفرة المنتشرة في المقالات القديمة التي تكتفي بإسناد HTTP_CF_CONNECTING_IP إلى REMOTE_ADDR إن وُجدت.

قائمة عناوين IP الخاصة بـ Cloudflare منشورة في https://www.cloudflare.com/ips/. قد تتغير القائمة، فراجعها دوريًا.

في حالة Nginx

استخدم ngx_http_realip_module. اذكر كل نطاقات Cloudflare داخل كتلة http أو server.

# نطاقات IP لـ Cloudflare (حتى نوفمبر 2026. راجع أحدثها في cloudflare.com/ips)
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;
sudo nginx -t && sudo systemctl reload nginx

في حالة Apache (Debian / Ubuntu)

استخدم mod_remoteip. أنشئ /etc/apache2/conf-available/remoteip.conf واذكر نطاقات Cloudflare في RemoteIPTrustedProxy.

RemoteIPHeader CF-Connecting-IP
RemoteIPTrustedProxy 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22
RemoteIPTrustedProxy 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20
RemoteIPTrustedProxy 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13
RemoteIPTrustedProxy 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22
RemoteIPTrustedProxy 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32
RemoteIPTrustedProxy 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32
sudo a2enmod remoteip
sudo a2enconf remoteip
sudo apache2ctl configtest
sudo systemctl restart apache2

لإظهار عنوان IP الحقيقي في سجل الوصول، غيّر %h إلى %a في LogFormat (combined) داخل /etc/apache2/apache2.conf.

إذا تعذّر تغيير إعدادات الخادم (wp-config.php)

إذا كنت على استضافة مشتركة أو خادم لا تستطيع تعديل إعدادات خادم الويب فيه، فنفّذ الفحص نفسه في wp-config.php. ضعه قبل السطر require_once ABSPATH . 'wp-settings.php';. لا تُستخدم قيمة CF-Connecting-IP (بشرط أن تكون عنوان IP صحيحًا) إلا إذا كان مصدر الاتصال ضمن نطاقات Cloudflare.

<?php
// استخدم CF-Connecting-IP عنوانَ IP للزائر فقط عندما يمرّ الطلب عبر Cloudflare
$cf_ranges = [
    '173.245.48.0/20', '103.21.244.0/22', '103.22.200.0/22', '103.31.4.0/22',
    '141.101.64.0/18', '108.162.192.0/18', '190.93.240.0/20', '188.114.96.0/20',
    '197.234.240.0/22', '198.41.128.0/17', '162.158.0.0/15', '104.16.0.0/13',
    '104.24.0.0/14', '172.64.0.0/13', '131.0.72.0/22',
    '2400:cb00::/32', '2606:4700::/32', '2803:f800::/32', '2405:b500::/32',
    '2405:8100::/32', '2a06:98c0::/29', '2c0f:f248::/32',
];

function cf_ip_in_range(string $ip, string $cidr): bool
{
    [$net, $bits] = explode('/', $cidr);
    $ip_bin  = inet_pton($ip);
    $net_bin = inet_pton($net);
    if ($ip_bin === false || $net_bin === false || strlen($ip_bin) !== strlen($net_bin)) {
        return false;
    }
    $bits  = (int) $bits;
    $bytes = intdiv($bits, 8);
    if ($bytes > 0 && substr($ip_bin, 0, $bytes) !== substr($net_bin, 0, $bytes)) {
        return false;
    }
    $rest = $bits % 8;
    if ($rest === 0) {
        return true;
    }
    $mask = (0xFF << (8 - $rest)) & 0xFF;
    return (ord($ip_bin[$bytes]) & $mask) === (ord($net_bin[$bytes]) & $mask);
}

if (!empty($_SERVER['HTTP_CF_CONNECTING_IP']) && !empty($_SERVER['REMOTE_ADDR'])) {
    foreach ($cf_ranges as $range) {
        if (cf_ip_in_range($_SERVER['REMOTE_ADDR'], $range)) {
            $visitor = filter_var($_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP);
            if ($visitor !== false) {
                $_SERVER['REMOTE_ADDR'] = $visitor;
            }
            break;
        }
    }
}

يحتوي wp-config.php أصلًا على <?php في أول سطر، فلا تنسخ <?php الموجودة في السطر الأول من الشيفرة أعلاه، والصق من السطر الثاني فصاعدًا. وخذ نسخة احتياطية من wp-config.php قبل اللصق.

الخطوة 4: حماية صفحة تسجيل الدخول بقواعد WAF المخصصة

تتيح الخطة المجانية إنشاء حتى 5 قواعد مخصصة في WAF لدى Cloudflare، ويمكنك اختيار أي إجراء عدا Log (مثل Block وManaged Challenge). أنشئها من صفحة Security rules في لوحة التحكم: اختر «Create rule» ثم «Custom rules»، وحدّد الشرط (Field وOperator وValue) والإجراء، ثم اضغط «Deploy».

المثال 1: فتح صفحة الدخول ولوحة التحكم لعنوان IP الخاص بك فقط

هذا مثال لمن لديه عنوان IP ثابت في المنزل أو العمل. تُكتب العبارة هكذا (استبدل 203.0.113.10 و198.51.100.0/24 بعناوينك).

(http.request.uri.path eq "/wp-login.php" or starts_with(http.request.uri.path, "/wp-admin/"))
and http.request.uri.path ne "/wp-admin/admin-ajax.php"
and not ip.src in {203.0.113.10 198.51.100.0/24}

اجعل الإجراء Block. استُثني /wp-admin/admin-ajax.php من الشرط لأن وظائف الصفحات العامة، مثل نماذج الاتصال والتمرير اللانهائي، قد تستدعيه دون تسجيل دخول.

المثال 2: بلا IP ثابت، التقييد بالدولة مع Managed Challenge

(http.request.uri.path eq "/wp-login.php" or http.request.uri.path eq "/xmlrpc.php")
and not ip.src.country in {"JP"}

للفحص حسب الدولة استخدم ip.src.country (رمز من حرفين حسب ISO 3166-1). أما ip.geoip.country في المقالات القديمة فمهجور. اجعل الإجراء Managed Challenge في البداية، وراجع أحداث الأمان (Security events) للتأكد من أن وصولًا مشروعًا لم يُحجب، ثم حوّله إلى Block إن لزم. وتوصي وثائق Cloudflare بهذا الأسلوب أيضًا. أما xmlrpc.php فيُستخدم عند النشر من Jetpack أو تطبيقات الهاتف، لذا تأكد من استخدامه من عدمه قبل إضافته إلى الشرط.

التقييد بالدولة إجراء مساعد يمكن الالتفاف عليه بـ VPN ونحوه. اجمعه مع المصادقة الثنائية وتحديد عدد محاولات تسجيل الدخول. وتجد طريقة الفحص بالدولة من جهة Nginx في تقييد الوصول حسب الدولة في Nginx باستخدام GeoIP2.

الخطوة 5: سلوك الكاش الافتراضي والمسح عند النشر

لا تخزّن Cloudflare HTML مؤقتًا افتراضيًا. الذي تخزّنه هو الملفات الثابتة التي يحددها امتدادها، مثل الصور وCSS وJavaScript والخطوط. كما لا تخزّن الاستجابات التي تتضمن ترويسة Set-Cookie. لذلك فإن شاشتي الإدارة وتسجيل الدخول لن تُخزَّنا في Cloudflare إن لم تضبط شيئًا.

إذا أردت تخزين HTML أيضًا فوسّع النطاق بـ Cache Rules، لكن عليك حينئذ استثناء /wp-admin/ و/wp-login.php والمعاينة وما يظهر للمستخدمين المسجّلين. الخطأ في الاستثناء قد يعرض شاشات المديرين لأشخاص آخرين، فالأسلم أن تبقى على الإعداد الافتراضي ما لم تكن واثقًا.

إذا استبدلت CSS أو صورة ولم يتغير ما يُعرض، فامسح (Purge) الكاش من إعدادات الكاش في لوحة التحكم. وإذا أردت المسح تلقائيًا عند كل نشر أو تحديث لمقالة فاستدعِ واجهة Cloudflare البرمجية (API). أنشئ في Cloudflare أولًا رمز API (API Token) بصلاحية «Cache Purge» فقط، واكتبه في wp-config.php كثابت مع معرّف النطاق (Zone ID، ويظهر في صفحة النظرة العامة للنطاق).

define( 'CF_ZONE_ID', 'معرّف النطاق' );
define( 'CF_API_TOKEN', 'رمز API' );

ضع الشيفرة التالية في functions.php لقالب فرعي، أو في إضافة صغيرة تكتبها بنفسك (ويصلح كذلك Code Snippets ونحوها).

<?php
// عند نشر مقالة أو تحديثها، امسح من Cloudflare كاش المقالة والصفحة الرئيسية
function cf_purge_urls(array $urls): bool
{
    if (!defined('CF_ZONE_ID') || !defined('CF_API_TOKEN')) {
        return false;
    }

    $response = wp_remote_post(
        'https://api.cloudflare.com/client/v4/zones/' . CF_ZONE_ID . '/purge_cache',
        [
            'headers' => [
                'Authorization' => 'Bearer ' . CF_API_TOKEN,
                'Content-Type'  => 'application/json',
            ],
            'body'    => wp_json_encode(['files' => array_values($urls)]),
            'timeout' => 15,
        ]
    );

    if (is_wp_error($response)) {
        error_log('Cloudflare purge failed: ' . $response->get_error_message());
        return false;
    }

    $result = json_decode(wp_remote_retrieve_body($response), true);
    return !empty($result['success']);
}

add_action('publish_post', function (int $post_id): void {
    if (wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) {
        return;
    }
    cf_purge_urls([get_permalink($post_id), home_url('/')]);
});

يعمل publish_post عند نشر مقالة وعند تحديث مقالة منشورة. وإلى جانب files الذي يحدد عناوين URL، يتيح purge_cache في API خيار purge_everything لمسح كل شيء، لكن المسح الكامل يعني إعادة جلب كل الملفات الثابتة أيضًا، فلا تستخدمه عند كل نشر لمقالة.

ما يجب التحقق منه بعد التحويل

  • يظهر في نتيجة curl -sI كل من server: cloudflare وcf-ray، وتظهر أيقونة القفل في المتصفح
  • يمكنك تسجيل الدخول إلى لوحة التحكم وحفظ مقالة ورفع وسائط
  • تُسجَّل في التعليقات الجديدة وسجل الوصول عناوين IP للزوار لا عناوين Cloudflare
  • يصل البريد من نموذج الاتصال (أي أن سجل MX غير ممرَّر عبر الوكيل)
  • إذا أنشأت قاعدة WAF مخصصة فافتح wp-login.php من اتصال غير مسموح به (مثل شبكة الجوال في الهاتف) وتأكد من ظهور الحجب أو التحدي

المشكلات الشائعة

ظهور ERR_TOO_MANY_REDIRECTS

تحقق من أن وضع SSL/TLS ليس Flexible. ثبّت شهادة على الخادم الأصلي وغيّر الوضع إلى Full (strict) فتُحل المشكلة.

تعذّر الدخول إلى لوحة التحكم

قد يكون شرط قاعدة WAF المخصصة لا يتضمن عنوان IP أو دولتك. عطّل القاعدة مؤقتًا من لوحة تحكم Cloudflare، وتحقق في أحداث الأمان من القاعدة التي حجبتك، ثم صحّح العبارة.

ظهور كل الزيارات من عنوان IP واحد

لم تتم استعادة IP الحقيقي في الخطوة 3. في Nginx تحقق من نطاق set_real_ip_from وreal_ip_header، وفي Apache تحقق من تفعيل remoteip.

الخلاصة

  • غيّر الخوادم الاسمية إلى الاسمين المخصصين لحسابك، ولا تُمرّر عبر الوكيل سجلات البريد مثل MX
  • اضبط SSL/TLS على Full (strict). فـ Flexible يسبب حلقات إعادة التوجيه والمحتوى المختلط
  • استعد IP الحقيقي بالثقة في CF-Connecting-IP فقط عندما يكون مصدر الاتصال ضمن نطاقات Cloudflare
  • قيّد صفحة تسجيل الدخول بقواعد WAF المخصصة حسب IP أو الدولة، وابدأ بـ Managed Challenge لترى النتيجة
  • لا يُخزَّن HTML افتراضيًا. ويجري المسح عند النشر برمز API بصلاحية «Cache Purge» فقط

مقالات ذات صلة

المراجع: Restoring original visitor IPs (Cloudflare)، Encryption modes (Cloudflare)، Custom rules (Cloudflare WAF)، Default cache behavior (Cloudflare)

لديك أسئلة حول WordPress؟ ناشر هذا الموقع موجود في اليابان ويرد باللغة اليابانية. تواصل معنا (باليابانية)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲