> ## Content Index
> Fetch the complete content index at: https://arabroot.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# حماية موقعك من روبوتات الذكاء الاصطناعي مع Anubis
- URL: https://arabroot.io/articles/حماية-موقعك-من-روبوتات-الذكاء-الاصطناعي-مع-anubis/
- Published: 2026-10-13T09:45:00.000Z
- Updated: 2026-10-13T13:26:41.000Z
- Description: كيف يوقف Anubis روبوتات جمع البيانات بمسألة إثبات عمل، دون أن يحجب محركات البحث وقراء RSS عن موقعك.
- Author: فريق عرب رووت
- Tags: الأدلة التقنية, الشبكات والبنية التحتية, الشبكات والوصول, الاستضافة الذاتية

إذا كان لديك موقع عام، كمدونة أو توثيق أو مستودع Git على Gitea، وفتحت سجل الطلبات Access Log، فسوف تجد بين الزوار برامج تقرأ كل صفحة في الموقع، ثم تعود بعد ساعات لتقرأها مرة أخرى، ومنها اليوم روبوتات تجمع المحتوى لتدريب نماذج الذكاء الاصطناعي. وبعض هذه الروبوتات يعرف نفسه بوضوح ويحترم ملف `robots.txt`، وبعضها يتظاهر بأنه متصفح Chrome عادي ويغير عنوان IP مع كل طلب، فلا ينفع معه الحظر بالاسم ولا بالعنوان.

وفي [خدمات Cloudflare وبدائلها](https://arabroot.io/articles/%D8%AE%D8%AF%D9%85%D8%A7%D8%AA-cloudflare-%D9%88%D8%A8%D8%AF%D8%A7%D8%A6%D9%84%D9%87%D8%A7-%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9-%D8%A7%D9%84%D9%85%D8%B5%D8%AF%D8%B1/#bots-turnstile) ذكرنا Anubis في سطر واحد كبديل مفتوح المصدر لحماية Cloudflare من الروبوتات، وفي هذا المقال سوف نشغله فعلاً أمام موقع تجريبي، ونرى من يمر ومن يتوقف، وكم ينتظر الزائر الحقيقي، وكيف يمكن أن تحجب محركات البحث وقراء RSS بخطأ صغير في الإعداد.

وسوف نناقش في هذا المقال ما يلي:

- ماذا تفعل روبوتات الذكاء الاصطناعي بموقعك، وما الذي يستطيع ملف `robots.txt` أن يفعله وما الذي لا يستطيعه، وأين وصلت المقترحات الجديدة مثل `llms.txt`.
- كيف يعمل Anubis: إثبات العمل Proof of Work، ونظام الأوزان، والسياسة Policy التي تقرر من يمر ومن يحل المسألة ومن يحظر.
- تجربة عملية: Anubis أمام موقع خلف Nginx مع HTTPS، ونتيجة عشرة أنواع من الزوار، من curl إلى GPTBot إلى Googlebot.
- كم ينتظر المستخدم الحقيقي، قسناه بمتصفح Chromium عبر Playwright.
- نكسرها: سياسة تحجب Googlebot وقارئ RSS، ثم الإصلاح.
- أثر Anubis على سهولة الوصول Accessibility ومحركات البحث، ومتى لا يناسبك.

## ماذا تفعل روبوتات الذكاء الاصطناعي بموقعك؟

الزاحف Crawler برنامج يطلب صفحات موقعك ويتبع الروابط فيها، ومحركات البحث تفعل ذلك منذ عشرات السنين، والفرق أن محرك البحث يعيد إليك زواراً من نتائجه، بينما زاحف التدريب يأخذ المحتوى ليدخل في بيانات تدريب نموذج، ولا يعيد زائراً في الغالب. والشركات الكبرى توثق زواحفها بأسماء واضحة، والجدول التالي يبين أمثلة من صفحاتها الرسمية:

| الاسم في User-Agent | الشركة      | الغرض بحسب الشركة                                                              | يحترم robots.txt؟                                                                                                                                                |
| ------------------- | ----------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GPTBot              | شركة OpenAI | جمع محتوى قد يستخدم في تدريب النماذج                                           | نعم بحسب [صفحة OpenAI](https://developers.openai.com/api/docs/bots?ref=arabroot.io)                                                                              |
| OAI-SearchBot       | شركة OpenAI | إظهار المواقع في نتائج البحث داخل ChatGPT                                      | نعم                                                                                                                                                              |
| ChatGPT-User        | شركة OpenAI | زيارة صفحة لأن مستخدماً طلبها في المحادثة                                      | تقول الصفحة إن القواعد قد لا تنطبق لأن الطلب من المستخدم                                                                                                         |
| Google-Extended     | شركة Google | ليس زاحفاً منفصلاً، وإنما اسم في robots.txt يمنع استخدام المحتوى لتدريب Gemini | نعم، ولا يؤثر على الظهور في Google Search بحسب [صفحة Google](https://developers.google.com/search/docs/crawling-indexing/google-common-crawlers?ref=arabroot.io) |

والمشكلة ليست في هذه الزواحف الموثقة، فهي تقرأ `robots.txt` وتلتزم به في الغالب، وإنما في البرامج التي لا تعرف نفسها، والتي تطلب نفس الصفحات آلاف المرات من عناوين مختلفة، فتحمل السيرفر ما لا يحمله الزوار الحقيقيون. والمستودعات Git أكثر ما يتأثر بذلك، لأن كل Commit وكل ملف في كل إصدار صفحة مستقلة يمكن أن تطلب.

📌

في يناير 2025 كتبت المطورة Xe Iaso في [مدونتها](https://xeiaso.net/notes/2025/amazon-crawler/?ref=arabroot.io) أن زاحف Amazon يضغط سيرفر Gitea الذي تستضيفه بنفسها حتى أصبح غير مستقر، فجربت منعه في `robots.txt` فلم يتوقف، ثم حظرت كل طلب فيه كلمة Amazon في User-Agent، فاستمرت الطلبات من عناوين مختلفة، وذكرت أن قرابة 10% منها لم تكن تحمل اسم Amazon أصلاً، فوضعت السيرفر خلف VPN مؤقتاً، ثم كتبت Anubis لتعيد فتحه للعموم. والدرس أن الحظر بالاسم والعنوان لا يكفي مع برنامج يكذب في الاسم ويغير العنوان، والحل أن تجعل كل طلب يكلف من يرسله شيئاً.

## ما الذي يستطيعه ملف robots.txt؟

الملف `robots.txt` أصبح معياراً رسمياً في سبتمبر 2022 بالوثيقة [RFC 9309](https://www.rfc-editor.org/rfc/rfc9309.html?ref=arabroot.io)، وهو قائمة طلبات من صاحب الموقع إلى الزواحف، فيقول مثلاً: لا تقرأ هذا المسار، أو لا يقرأ GPTBot أي شيء:

```text
User-agent: GPTBot
Disallow: /

User-agent: Google-Extended
Disallow: /

User-agent: *
Allow: /
```

ولكن الوثيقة نفسها تقول إن هذه القواعد ليست وسيلة للتحكم في الوصول Access Authorization، أي أن الملف طلب مهذب، يلتزم به من يريد أن يلتزم، ولا يوقف من لا يريد. لذلك فهو مفيد مع الزواحف الموثقة، ولا يفيد مع البرامج التي تتجاهله.

وقد يتساءل البعض: وماذا عن الملفات الجديدة مثل `llms.txt`؟ والإجابة أن [llms.txt](https://llmstxt.org/?ref=arabroot.io) مقترح نشره Jeremy Howard في 3 سبتمبر 2024، وهدفه عكس ما قد تظن، فهو ملف يساعد النماذج على فهم موقعك عندما تحتاجه أثناء مساعدة مستخدم، ولا يمنع ولا يسمح بالزحف. أما المعيار الذي يعمل على التعبير عن تفضيلاتك في استخدام المحتوى للذكاء الاصطناعي فهو عمل مجموعة [AI Preferences](https://datatracker.ietf.org/wg/aipref/about/?ref=arabroot.io) في IETF، وحتى أكتوبر 2026 ما زالت وثيقتاها مسودات Internet-Draft، آخرها draft-ietf-aipref-vocab بالإصدار 08 في سبتمبر 2026، ولم تصدر كمعيار RFC بعد. وفي كل الأحوال هذه تفضيلات يعبر عنها الموقع، وليست حماية تمنع البرنامج الذي لا يحترمها.

## كيف يعمل Anubis؟

أداة Anubis برنامج مكتوب بلغة Go من شركة Techaro، برخصة MIT، وآخر إصدار عند كتابة المقال هو 1.28.1 في 9 أكتوبر 2026\. ويقف بين ال Reverse Proxy والتطبيق، فكل طلب يمر عليه أولاً، ويقرر واحداً من ثلاثة أفعال:

- **السماح ALLOW:** يمرر الطلب إلى التطبيق مباشرة.
- **الحظر DENY:** يرد بصفحة رفض ولا يصل الطلب إلى التطبيق.
- **مسألة التحقق CHALLENGE:** يرد بصفحة فيها JavaScript تطلب من المتصفح أن يحل مسألة إثبات عمل Proof of Work، فإذا حلها حصل على Cookie موقع لمدة أسبوع افتراضياً، ومرت طلباته التالية دون مسألة.

ومسألة إثبات العمل هي أن يجد المتصفح رقماً Nonce، إذا أضيف إلى نص المسألة كان هاش SHA-256 للناتج يبدأ بعدد معين من الأصفار، وهذا العدد هو الصعوبة Difficulty. والطريقة الوحيدة للحل هي التجربة، فكل صفر إضافي يضرب متوسط المحاولات في 16، فالصعوبة 2 تحتاج في المتوسط 256 محاولة، والصعوبة 4 تحتاج 65,536 محاولة. وهذا لا يكاد يلاحظ في متصفح زائر واحد، ولكنه يصبح كلفة حقيقية على من يطلب ملايين الصفحات، لأنه سوف يحل مسألة جديدة لكل عنوان ولكل Cookie يخسرها.

الصورة التالية تبين مسار الطلب:

![طلب من متصفح يصل إلى Nginx ثم إلى Anubis، فيقرأ Anubis السياسة، فيمرر Googlebot من عناوين Google، ويحظر GPTBot، ويرسل للمتصفح مسألة إثبات عمل، فإذا حلها حصل على Cookie ووصل إلى الموقع](https://arabroot.io/content/images/2026/10/anubis-01-flow.webp)

السياسة تقرر الفعل، ومسألة إثبات العمل لمن لا تعرفه السياسة

### السياسة والأوزان

السياسة Policy ملف YAML فيه قائمة قواعد تقرأ بالترتيب، وأول قاعدة تطابق تقرر الفعل. والسياسة الافتراضية في الإصدار 1.28.1 تستورد قوائم جاهزة من داخل البرنامج، وأهمها:

- قائمة الحظر لروبوتات الذكاء الاصطناعي المعروفة بأسمائها، ومنها GPTBot وClaudeBot وBytespider وAmazonbot.
- قائمة الحظر للمتصفحات الآلية التي تعرف نفسها، مثل HeadlessChrome.
- قائمة السماح لزواحف البحث الجيدة `_allow-good.yaml`، ومنها Googlebot وBingbot وDuckDuckBot وApplebot، وكل واحد منها مربوط بنطاقات عناوين IP التي تنشرها شركته، فالاسم وحده لا يكفي.
- قائمة `keep-internet-working.yaml` التي تسمح دائماً بالمسارات `/robots.txt` و`/sitemap.xml` و`/.well-known/` و`/favicon.ico`.

وبعد القوائم يأتي نظام الأوزان Weights، فكل طلب يبدأ بوزن صفر، وأي User-Agent فيه كلمة `Mozilla` أو `Opera` يأخذ 10 نقاط، ثم تقرر حدود Thresholds الفعل بحسب الوزن. وهذا جزء من الملف كما هو في الإصدار 1.28.1، بعد حذف التعليقات:

```yaml
  - name: generic-browser
    user_agent_regex: >-
      Mozilla|Opera
    action: WEIGH
    weight:
      adjust: 10
thresholds:
  - name: minimal-suspicion # This client is likely fine, its soul is lighter than a feather
    expression: weight <= 0 # a feather weighs zero units
    action: ALLOW # Allow the traffic through
  - name: moderate-suspicion
    expression:
      all:
        - weight >= 10
        - weight < 20
    action: CHALLENGE
    challenge:
      algorithm: fast
      difficulty: 2 # two leading zeros, very fast for most clients
```

في الإعداد أعلاه لاحظ التالي:

- الطلب الذي لا يدعي أنه متصفح، مثل `curl` أو برنامج RSS باسم واضح، وزنه صفر فيمر دون مسألة، وهذا مقصود، لأن Anubis يفترض أن من يتظاهر بأنه متصفح يجب أن يثبت ذلك بتشغيل JavaScript.
- الصعوبة للمتصفح العادي 2 فقط، وترتفع إلى 4 ثم 6 كلما زاد الوزن بقواعد أخرى، كالدول أو شبكات الاستضافة إذا فعلت قاعدة بيانات GeoIP.
- قواعد الدول وأرقام الشبكات ASN في السياسة الافتراضية لا تعمل دون قاعدة بيانات GeoIP، وقد ظهر تحذير بذلك في سجل التشغيل في تجربتنا.

## التجربة: Anubis أمام موقع خلف Nginx

الترتيب في التجربة هو نفس الترتيب الذي توصي به [وثائق Anubis](https://anubis.techaro.lol/docs/admin/installation?ref=arabroot.io): Reverse Proxy ينهي TLS، ثم Anubis، ثم الموقع. والمكونات كما يلي:

| المكون           | ال Image                                   | دوره                                                          |
| ---------------- | ------------------------------------------ | ------------------------------------------------------------- |
| الموقع           | nginx:1.31.6-alpine                        | صفحة عربية وملف feed.xml وملف robots.txt                      |
| أداة Anubis      | ghcr.io/techarohq/anubis:v1.28.1           | بالسياسة الافتراضية                                           |
| ال Reverse Proxy | nginx:1.31.6-alpine                        | شهادة ذاتية التوقيع للمختبر على المنفذ 443                    |
| العملاء          | mcr.microsoft.com/playwright:v1.64.0-noble | الأداة curl 8.5.0 والمتصفح Chromium 156 عبر Playwright 1.64.0 |

وتشغيل Anubis أمر واحد، فنحدد عنوان الموقع خلفه ب `TARGET`:

```bash
docker run -d --name lab-edge1-anubis --network lab-edge1-net \
  -e BIND=:8923 -e TARGET=http://lab-edge1-site:80 \
  ghcr.io/techarohq/anubis:v1.28.1
```

أما إعداد Nginx أمامه فهو كما يلي، ولاحظ الترويسة `X-Real-IP`، فهي التي يقرأ منها Anubis عنوان الزائر:

```nginx
server {
    listen 443 ssl;
    ssl_certificate     /etc/nginx/certs/front.crt;
    ssl_certificate_key /etc/nginx/certs/front.key;
    set_real_ip_from 192.168.80.0/20;
    real_ip_header X-Lab-Client-IP;
    location / {
        proxy_pass http://lab-edge1-anubis:8923;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
```

في الإعداد أعلاه لاحظ التالي:

- السطران `set_real_ip_from` و`real_ip_header` للمختبر فقط، فهما يسمحان لجهاز الاختبار على شبكة المختبر أن يحدد العنوان الذي يظهر به في ترويسة `X-Lab-Client-IP`، حتى نحاكي طلباً قادماً من عنوان تابع ل Google. ولا تضعهما في سيرفر حقيقي، والسبب أن أي زائر سوف يستطيع حينها أن يدعي أي عنوان.
- لا تجعل Anubis يستقبل الطلبات من الإنترنت مباشرة، فهو يثق بالترويسة `X-Real-IP` التي يضعها ال Proxy، وإذا وصل إليه الزائر مباشرة استطاع أن يكتبها بنفسه، فيدعي أنه Googlebot من عنوان Google.

### من يمر ومن يتوقف؟

كتبنا سكربتاً صغيراً يرسل طلباً واحداً بكل User-Agent، ويقرأ الرد ليعرف هل هو صفحة الموقع أم صفحة المسألة أم صفحة الحظر، وهذا جزء منه:

```bash
p "curl (default UA)"            /          ""
p "scraper with Chrome UA"       /          "$CHROME"
p "GPTBot"                       /          'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)'
p "Googlebot UA, lab IP"         /          "$GOOGLE"
p "Googlebot UA, 66.249.64.10"   /          "$GOOGLE" 66.249.64.10
p "FreshRSS"                     /feed.xml  'FreshRSS/1.26.3 (Linux; https://freshrss.org)'
p "Thunderbird (feed reader)"    /feed.xml  'Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Thunderbird/140.3.0'
```

والمخرج سوف يكون كما يلي:

```text
=== policy: default
curl (default UA)                  /              200  site page
scraper with Chrome UA             /              200  challenge page
GPTBot                             /              200  deny page
ClaudeBot                          /              200  deny page
Bytespider                         /              200  deny page
Googlebot UA, lab IP               /              200  challenge page
Googlebot UA, 66.249.64.10         /              200  site page
FreshRSS                           /feed.xml      200  RSS feed
Thunderbird (feed reader)          /feed.xml      200  challenge page
robots.txt with Chrome UA          /robots.txt    200  robots.txt
```

في المخرج أعلاه لاحظ التالي:

- كل الردود بالرمز `200`، حتى الحظر والمسألة، لأن السياسة الافتراضية تضع `status_codes` للحالتين على 200، فلا تعتمد على رمز الرد في المراقبة، واقرأ سجل Anubis نفسه، أو غير الرمز في السياسة إذا كانت أدواتك تحتاجه.
- الطلب من `curl` باسمه الحقيقي مر دون مسألة، أما نفس `curl` عندما ادعى أنه Chrome فحصل على صفحة المسألة، ولا يستطيع حلها لأنه لا ينفذ JavaScript، وهذا هو الروبوت الذي يكذب في اسمه.
- الروبوتات التي تعرف نفسها كروبوتات ذكاء اصطناعي حظرت مباشرة، والسجل يقول السبب، فطلب GPTBot طابق القاعدة `bot/ai-crawlers-training`.
- الزاحف Googlebot بنفس الاسم حصل على المسألة عندما جاء من عنوان المختبر، ومر مباشرة عندما جاء من العنوان `66.249.64.10` الذي يقع في نطاق `66.249.64.0/27` المذكور في قائمة Googlebot داخل Anubis، فمن يكتب Googlebot في اسمه لا يمر إلا من عناوين Google.
- قارئ FreshRSS أخذ الملف `feed.xml` لأن اسمه لا يحتوي Mozilla، أما Thunderbird، وهو يقرأ RSS أيضاً، فحصل على صفحة المسألة بدل الملف، لأن اسمه يبدأ بكلمة Mozilla، وهو لا يشغل JavaScript عند جلب الخلاصة. وهذه مشكلة في السياسة الافتراضية نفسها سوف نصلحها بعد قليل.

### كم ينتظر الزائر الحقيقي؟

قسنا الزمن بمتصفح Chromium عبر Playwright، في سياق جديد Fresh Context في كل مرة حتى لا تبقى Cookie من المرة السابقة، من لحظة طلب الصفحة حتى ظهور عنوان الموقع، وسجلنا معه الرقم `elapsedTime` الذي ترسله صفحة المسألة نفسها، والرقم Nonce الذي وجده المتصفح أي عدد المحاولات تقريباً. وهذا جزء القياس من السكربت بعد حذف أسطر التسجيل منه:

```javascript
for (let i = 0; i < RUNS; i++) {
  const ctx = await b.newContext({ ignoreHTTPSErrors: true, userAgent: CHROME });
  const p = await ctx.newPage();
  const t0 = Date.now();
  await p.goto(URL);
  await p.waitForSelector('text=مدونة المختبر', { timeout: 60000 });
  times.push(Date.now() - t0);
  await ctx.close();
}
```

والمخرج بالسياسة الافتراضية، أي الصعوبة 2 للمتصفح العادي، سوف يكون كما يلي:

```text
chromium 156.0.8078.4 label
cookies after pass: techaro.lol-anubis-cookie-verification-347ddb4a,techaro.lol-anubis-auth-347ddb4a
total ms in order: 8025 8596 3012 2271 5303
solve ms (elapsedTime sent by the page): 2090 5080 1055 540 2016
runs 5 ms: 2271 3012 5303 8025 8596 median 5303
```

ثم غيرنا الصعوبة في نفس الحد إلى 4 بملف سياسة، وأعدنا القياس بسبع محاولات:

```text
chromium 156.0.8078.4 label d4
cookies after pass: techaro.lol-anubis-cookie-verification-347ddb4a,techaro.lol-anubis-auth-347ddb4a
run 6 page not reached; title = Making sure you're not a bot!
run 7 page not reached; title = Making sure you're not a bot!
total ms in order: 31136 14513 12084 32867 4880
solve ms (elapsedTime sent by the page): 16641 12307 8799 30007 2886
nonce (hashes tried): 59408 23894 33084 62241 50007
runs 5 ms: 4880 12084 14513 31136 32867 median 14513
```

وهنا يجب أن نكون صريحين في قراءة هذه الأرقام:

- الجهاز الذي قسنا عليه كان مشتركاً مع تجارب أخرى تستهلك المعالج بقوة وقت القياس، فالأزمنة هنا أطول بكثير مما يراه زائر على حاسوب عادي، وتختلف كثيراً بين محاولة وأخرى، لذلك لا تأخذ منها رقماً مطلقاً.
- الرقم الثابت هو عدد المحاولات: في الصعوبة 4 وجد المتصفح الحل بعد ما بين 23,894 و62,241 محاولة، وهذا متسق مع المتوسط المتوقع 65,536، أي أن الصعوبة 4 تطلب عملاً أكبر بنحو 256 مرة من الصعوبة 2.
- في محاولتين من سبع لم يصل المتصفح إلى الموقع خلال 60 ثانية في الصعوبة 4، وعلى جهاز ضعيف أو هاتف قديم قد يعيش الزائر نفس التجربة، لذلك لا ترفع الصعوبة لكل الزوار، واتركها للحالات التي يرتفع فيها الوزن.
- المسألة تحل مرة واحدة، ثم تبقى Cookie `anubis-auth` صالحة 168 ساعة افتراضياً، فالزائر لا يرى المسألة في كل صفحة.

والصورة التالية من تجربتنا تبين صفحة المسألة كما يراها الزائر:

![صفحة Anubis بعنوان Making sure you're not a bot! أثناء الحساب، وتحت العنوان الصعوبة 2 وشريط التقدم](https://arabroot.io/content/images/2026/10/anubis-02-challenge.webp)

صفحة المسألة في Anubis 1.28.1 كما ظهرت في تجربتنا، وقد أخرنا تحميل سكربت الحساب ثماني ثوان حتى نلتقطها

### خطأ وقعنا فيه: Anubis خلف HTTP

في أول تشغيل جعلنا ال Proxy على HTTP عادي لأن المختبر محلي، فحل المتصفح المسألة، ثم ظهرت له صفحة الخطأ بدل الموقع، وفي سجل Anubis السطر التالي:

```text
user has cookies disabled, this is not an anubis bug
```

والسبب أن Anubis يضع خاصية `Secure` على ال Cookie افتراضياً بالإعداد `COOKIE_SECURE=true`، والمتصفح لا يحفظ Cookie فيها هذه الخاصية على اتصال HTTP، فيعود الزائر دون ال Cookie ويفشل. وحتى عندما عطلنا الخاصية بقي الطلب يفشل، لأن ال Cookie المؤقتة التي يضعها Anubis أثناء المسألة كانت تحمل خاصية `Partitioned`، والمتصفح لا يقبلها دون `Secure`. والحل الصحيح ليس تعطيل الخصائص، وإنما أن يكون أمام Anubis اتصال HTTPS دائماً، حتى في المختبر، وهذا ما فعلناه بشهادة ذاتية التوقيع.

### نكسرها: سياسة تحجب محركات البحث وقراء RSS

لنفرض أن أحد الفريق رأى أن بعض الروبوتات ما زالت تمر، فأضاف في بداية السياسة قاعدة تطلب المسألة من الجميع:

```yaml
bots:
  # added to "challenge everyone": placed before the allow lists
  - name: challenge-everyone
    user_agent_regex: .*
    action: CHALLENGE
```

وأعدنا تشغيل Anubis بهذه السياسة، ثم نفس السكربت، والمخرج سوف يكون كما يلي:

```text
=== policy: policy-broken.yaml
curl (default UA)                  /              200  challenge page
scraper with Chrome UA             /              200  challenge page
GPTBot                             /              200  challenge page
ClaudeBot                          /              200  challenge page
Bytespider                         /              200  challenge page
Googlebot UA, lab IP               /              200  challenge page
Googlebot UA, 66.249.64.10         /              200  challenge page
FreshRSS                           /feed.xml      200  challenge page
Thunderbird (feed reader)          /feed.xml      200  challenge page
robots.txt with Chrome UA          /robots.txt    200  challenge page
```

في المخرج أعلاه لاحظ التالي:

- كل الزوار العشرة حصلوا على صفحة المسألة، ومنهم Googlebot من عنوان Google، لأن القاعدة الشاملة جاءت قبل قائمة السماح، وأول قاعدة تطابق هي التي تقرر، وبالتالي لن تجد Google صفحاتك بعد هذا التغيير.
- قارئا RSS حصلا على صفحة HTML بدل الخلاصة، فيظهر لمشتركيك خطأ في القارئ، أو تتوقف الخلاصة دون أن يعرفوا السبب.
- حتى `/robots.txt` أصبح خلف المسألة، فالزاحف المهذب الذي يريد أن يقرأ قواعدك لا يستطيع.
- والمفاجأة أن GPTBot وأمثاله لم يعودوا محظورين، وإنما يحصلون على مسألة، لأن القاعدة الشاملة سبقت قائمة الحظر أيضاً، أي أن التغيير الذي أردت به التشدد خفف الحظر على من كنت تريد حظره.

والإصلاح أمران: أن تحذف القاعدة الشاملة، أو تضعها بعد قوائم السماح إذا كنت تحتاجها فعلاً، لأن أول قاعدة تطابق هي التي تقرر، وأن تسمح لمسارات الخلاصات بالاسم، لأن هذه الملفات تقرأها برامج دائماً وليس إنساناً في متصفح:

```yaml
bots:
  # feeds and robots.txt are read by programs, never by a person in a browser
  - name: rss-feeds
    path_regex: ^/(feed\.xml|rss\.xml|atom\.xml)$
    action: ALLOW
```

ثم بقية السياسة الافتراضية كما هي بعد هذه القاعدة، والمخرج بعد الإصلاح سوف يكون كما يلي:

```text
=== policy: policy-fixed.yaml
curl (default UA)                  /              200  site page
scraper with Chrome UA             /              200  challenge page
GPTBot                             /              200  deny page
ClaudeBot                          /              200  deny page
Bytespider                         /              200  deny page
Googlebot UA, lab IP               /              200  challenge page
Googlebot UA, 66.249.64.10         /              200  site page
FreshRSS                           /feed.xml      200  RSS feed
Thunderbird (feed reader)          /feed.xml      200  RSS feed
robots.txt with Chrome UA          /robots.txt    200  robots.txt
```

في المخرج أعلاه لاحظ التالي:

- عادت النتيجة إلى السياسة الافتراضية في كل السطور، مع فرق واحد: Thunderbird أخذ الخلاصة `feed.xml` بدل صفحة المسألة.
- قاعدة السماح خاصة بمسارات الخلاصات وحدها، فإذا طلب نفس البرنامج صفحة عادية بنفس الاسم حصل على المسألة كما كان.
- بعد أي تعديل على السياسة شغل نفس الاختبار بأسماء Googlebot وقراء RSS التي يستخدمها جمهورك، فهذا أسرع من اكتشاف المشكلة بعد أسبوع من تراجع الزيارات.

### إزالة التجربة

```bash
docker rm -f lab-edge1-anubis lab-edge1-front lab-edge1-site
docker network rm lab-edge1-net
```

## أثر Anubis على الزوار وسهولة الوصول

أداة Anubis تضع شرطاً على كل زائر جديد يدعي أنه متصفح: أن يشغل JavaScript وأن يقبل Cookies. والنتائج العملية لذلك كما يلي:

- **من يعطل JavaScript لا يصل إلى الموقع**، وقد شغلنا المتصفح دون JavaScript فبقي على صفحة المسألة بعد عشرين ثانية، وفيها جملة تقول إن الحل دون JavaScript ما زال قيد العمل، كما في الصورة أدناه. وتقول [صفحة الأسئلة الشائعة](https://anubis.techaro.lol/docs/user/frequently-asked-questions?ref=arabroot.io) إن المشروع لن يطلب من المستخدم أن يلصق كوداً ليحل المسألة بنفسه، والسبب أن هذا أسلوب البرامج الخبيثة.
- **الإضافات التي تقيد JavaScript** مثل JShelter تعطل المسألة، والمشروع يشرح في وثائقه كيف تستثني الموقع منها.
- **الأجهزة الضعيفة تنتظر أكثر**، فالمسألة تعمل على المعالج، وتعطيل الترجمة الفورية JIT في المتصفح لأسباب أمنية يجعلها أبطأ بكثير بحسب نفس الصفحة.
- **لا يوجد سؤال بصري أو صوتي** كما في CAPTCHA، فمستخدم قارئ الشاشة Screen Reader لا يطلب منه شيء، وهذه ميزة حقيقية، ولكن الصفحة التي يسمعها إنجليزية، فبين 29 ملف ترجمة في الإصدار 1.28.1 لا توجد ترجمة عربية، وعندما فتحناها بمتصفح لغته العربية بقي النص إنجليزياً والخاصية `lang="en"`.

والصورة التالية تبين الصفحة كما يراها من عطل JavaScript:

![صفحة Anubis في متصفح عطل JavaScript، وفيها كلمة Loading ثم جملة تطلب تفعيل JavaScript وتقول إن الحل دونه ما زال قيد العمل](https://arabroot.io/content/images/2026/10/anubis-03-no-js.webp)

دون JavaScript تبقى الصفحة هنا ولا يصل الزائر إلى الموقع

وقد شرحنا ما يحتاجه الموقع العربي حتى يستخدمه الجميع في [سهولة الوصول Accessibility](https://arabroot.io/articles/%D8%B3%D9%87%D9%88%D9%84%D8%A9-%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-accessibility-%D9%83%D9%8A%D9%81-%D8%AA%D8%A8%D9%86%D9%8A-%D9%85%D9%88%D9%82%D8%B9%D8%A7-%D9%8A%D8%B3%D8%AA%D8%AE%D8%AF%D9%85%D9%87-%D8%A7%D9%84%D8%AC%D9%85%D9%8A%D8%B9/)، وكيف تختبره في [اختبار سهولة الوصول لموقع عربي](https://arabroot.io/articles/%D8%A7%D8%AE%D8%AA%D8%A8%D8%A7%D8%B1-%D8%B3%D9%87%D9%88%D9%84%D8%A9-%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-accessibility-%D9%84%D9%85%D9%88%D9%82%D8%B9-%D8%B9%D8%B1%D8%A8%D9%8A/).

## ومحركات البحث؟

محركات البحث الكبيرة لا تحل المسائل، لذلك يعتمد ظهور موقعك في نتائجها على قوائم السماح في السياسة، وهي في الإصدار 1.28.1 تربط كل زاحف بعناوينه المنشورة كما رأيت. وفيما يلي ما يجب أن تراقبه:

- لا تضع قبل قوائم السماح قاعدة تطابق كل شيء، كما رأيت في فقرة الكسر.
- تحقق بعد التحديث من وجود قائمة `_allow-good.yaml` في سياستك إذا كتبت سياستك بنفسك ولم تستورد الافتراضية.
- المسارات `/robots.txt` و`/sitemap.xml` مسموحة دائماً في القائمة الافتراضية، فلا تحذف قائمة `keep-internet-working.yaml`.
- معاينة الروابط Link Preview في تطبيقات المحادثة برامج أيضاً، وفي مجلد القوائم داخل Anubis قوائم جاهزة لبعضها مثل Telegram، ولكنها غير مستوردة في السياسة الافتراضية، فجرب رابطاً من موقعك في التطبيقات التي يستخدمها جمهورك، واستورد ما تحتاجه.

## متى لا يناسبك Anubis؟

- **واجهات API:** التطبيق الذي يستدعي ال API لا يشغل JavaScript، فلا تضع Anubis أمام مسارات ال API، واستخدم لها حد معدل الطلبات كما في [Rate Limiting وخوارزمياته](https://arabroot.io/articles/%D8%AA%D8%AD%D8%AF%D9%8A%D8%AF-%D9%85%D8%B9%D8%AF%D9%84-%D8%A7%D9%84%D8%B7%D9%84%D8%A8%D8%A7%D8%AA-rate-limiting-%D9%88%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A7%D8%AA%D9%87/).
- **الهجمات الحجمية:** Anubis يجعل الزحف مكلفاً، ولكنه لا يوقف إغراق الشبكة، فهذا له طبقاته في [طبقات الحماية من DDoS](https://arabroot.io/articles/%D8%B7%D8%A8%D9%82%D8%A7%D8%AA-%D8%A7%D9%84%D8%AD%D9%85%D8%A7%D9%8A%D8%A9-%D9%85%D9%86-%D9%87%D8%AC%D9%85%D8%A7%D8%AA-ddos/).
- **هجمات على محتوى الطلب:** المتصفح الذي حل المسألة يستطيع بعدها أن يرسل حقن SQL كما يشاء، فهذا عمل جدار WAF كما في [جدار WAF على سيرفرك](https://arabroot.io/articles/%D8%AC%D8%AF%D8%A7%D8%B1-waf-%D8%B9%D9%84%D9%89-%D8%B3%D9%8A%D8%B1%D9%81%D8%B1%D9%83-%D8%A7%D9%8A-%D8%A7%D8%AF%D8%A7%D8%A9-%D8%AA%D8%AE%D8%AA%D8%A7%D8%B1/).
- **روبوت يشغل متصفحاً كاملاً:** برنامج يستخدم Chrome حقيقياً ويغير اسمه سوف يحل المسألة كأي زائر، وكل ما تفعله الصعوبة أنها تجعل كل صفحة أغلى عليه.

## أخطاء شائعة

- **تشغيل Anubis خلف HTTP:** الزائر يحل المسألة ثم يرى «cookies disabled»، فاجعل أمامه HTTPS دائماً.
- **كشف منفذ Anubis للإنترنت:** يصبح عنوان الزائر قابلاً للتزوير بالترويسة `X-Real-IP`، فاجعل الوصول إليه من ال Proxy وحده.
- **قاعدة شاملة في أول السياسة:** تحجب Googlebot وقراء RSS، والترتيب في السياسة يغير النتيجة.
- **الاعتماد على رمز الرد في المراقبة:** الحظر والمسألة يردان بالرمز 200 في الإعداد الافتراضي.
- **رفع الصعوبة للجميع:** كل خطوة تضرب العمل في 16، والزائر على هاتف قديم هو من يدفع الثمن.
- **الاعتماد على `robots.txt` وحده:** هو طلب مهذب للزواحف الموثقة، وليس حماية.

## الخلاصة

وصلنا لنهاية الموضوع، وأهم ما فيه:

- ملف `robots.txt` معيار رسمي منذ 2022، ولكنه ليس وسيلة تحكم في الوصول، و`llms.txt` لا يمنع الزحف أصلاً، ومعايير IETF لتفضيلات الذكاء الاصطناعي ما زالت مسودات.
- أداة Anubis تحظر روبوتات الذكاء الاصطناعي المعروفة بالاسم، وتمرر زواحف البحث من عناوينها المنشورة، وتطلب من كل من يدعي أنه متصفح أن يثبت ذلك بمسألة إثبات عمل.
- في تجربتنا مر curl وFreshRSS لأنهما لم يدعيا أنهما متصفح، وتوقف curl المتنكر في Chrome، وحصل Thunderbird على صفحة المسألة بدل خلاصة RSS حتى أضفنا قاعدة سماح لمسار الخلاصة.
- كل خطوة في الصعوبة تضرب العمل في 16، والصعوبة 2 الافتراضية للمتصفح العادي هي التوازن المعقول، أما 4 فقد تجعل الأجهزة الضعيفة تنتظر طويلاً.
- ضعه خلف HTTPS، ولا تكشف منفذه، ولا تضعه أمام ال API، ولا تضع قاعدة شاملة قبل قوائم السماح.

[![](https://arabroot.io/content/images/2026/10/cloudflare-services-cover-cover.webp)دليلخدمات Cloudflare بكلمات بسيطة وبدائلها مفتوحة المصدرما الذي تقدمه كل خدمة من Cloudflare، وما المتاح منها مجاناً، وما البديل مفتوح المصدر الذي تشغله على سيرفرك.](https://arabroot.io/articles/%D8%AE%D8%AF%D9%85%D8%A7%D8%AA-cloudflare-%D9%88%D8%A8%D8%AF%D8%A7%D8%A6%D9%84%D9%87%D8%A7-%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9-%D8%A7%D9%84%D9%85%D8%B5%D8%AF%D8%B1/)[![](https://arabroot.io/content/images/2026/10/self-hosted-waf-cover-cover.webp)دليلجدار WAF على سيرفرك: أي أداة تختار؟كيف تختار جدار حماية تطبيقات الويب لسيرفرك، ولماذا قد يرفض اسماً عربياً عادياً، وكيف تصلح ذلك دون أن تضعف الحماية.](https://arabroot.io/articles/%D8%AC%D8%AF%D8%A7%D8%B1-waf-%D8%B9%D9%84%D9%89-%D8%B3%D9%8A%D8%B1%D9%81%D8%B1%D9%83-%D8%A7%D9%8A-%D8%A7%D8%AF%D8%A7%D8%A9-%D8%AA%D8%AE%D8%AA%D8%A7%D8%B1/)[![](https://arabroot.io/content/images/2026/10/rate-limiting-cover-cover.webp)دليلتحديد معدل الطلبات Rate Limiting وخوارزمياتهكيف تعمل خوارزميات تحديد معدل الطلبات، وأيها يناسب واجهتك، وكيف تطبقها على عدة سيرفرات وترد بالرمز 429 الصحيح.](https://arabroot.io/articles/%D8%AA%D8%AD%D8%AF%D9%8A%D8%AF-%D9%85%D8%B9%D8%AF%D9%84-%D8%A7%D9%84%D8%B7%D9%84%D8%A8%D8%A7%D8%AA-rate-limiting-%D9%88%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A7%D8%AA%D9%87/)[![](https://arabroot.io/content/images/2026/10/ddos-prevention-cover-cover.webp)دليلطبقات الحماية من هجمات DDoS وأين تقف كل طبقةكيف تبني دفاعاً بالطبقات ضد DDoS من المزود وال CDN إلى ضبط النواة والتخزين المؤقت، ومتى لا يكفي سيرفرك وحده.](https://arabroot.io/articles/%D8%B7%D8%A8%D9%82%D8%A7%D8%AA-%D8%A7%D9%84%D8%AD%D9%85%D8%A7%D9%8A%D8%A9-%D9%85%D9%86-%D9%87%D8%AC%D9%85%D8%A7%D8%AA-ddos/)[![](https://arabroot.io/content/images/2026/10/accessibility-testing-cover-cover.webp)دليلاختبار سهولة الوصول Accessibility لموقع عربيما الذي تجده أدوات فحص سهولة الوصول وما الذي يفوتها، وما الذي يخص المواقع العربية، وكيف تمنع عودة المشاكل في خط CI.](https://arabroot.io/articles/%D8%A7%D8%AE%D8%AA%D8%A8%D8%A7%D8%B1-%D8%B3%D9%87%D9%88%D9%84%D8%A9-%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-accessibility-%D9%84%D9%85%D9%88%D9%82%D8%B9-%D8%B9%D8%B1%D8%A8%D9%8A/)

## سجل التحديثات

- أكتوبر 2026: كتابة المقال، وتنفيذ التجربة على Docker Engine 29.8.0 مع Anubis 1.28.1 وNginx 1.31.6 وPlaywright 1.64.0 مع Chromium 156 وcurl 8.5.0.