---
title: "أحكِم إغلاق الخادم، وضَعْ WAF أمام تطبيقك"
description: "يُحكم erpc worker إغلاق الخادم منذ أول نشر، وجدول واحد في erpc.toml يضع WAF أمام API عامة. ما يفعله وما لا يفعله."
canonical: "https://erpc.global/ar/doc/erpc-cli/worker-firewall-and-waf/"
locale: "ar"
---

# أحكِم إغلاق الخادم، وضَعْ WAF أمام تطبيقك

منذ أول نشر، لا يسمح `erpc worker` بدخول SSH إلا من عنوانك، ويُسقط كل اتصال وارد آخر. ويضع جدول `[waf]` بروكسي تصفية أمام الـ API الخاص بك.

تصف هذه الصفحة ERPC CLI `v0.1.0-rc.4`، وهو إصدار تمهيدي.

## جدار الحماية

يضبط النشر جدار حماية الخادم قبل أول تشغيل للتطبيق:

- SSH فقط من `firewall.ssh_allow` ومن العنوان الذي يأتي منه النشر؛
- يُسقَط كل اتصال وارد آخر، باستثناء `run.port` من `firewall.app_allow`؛ وفي تطبيق خلف WAF يحلّ منفذ WAF محله، ولا يكون ذلك إلا حيث يشغّل WAF على الخادم بالفعل القواعد التي يضعها `[waf]` الآن ([أدناه](https://erpc.global/ar/doc/erpc-cli/worker-firewall-and-waf/#ضع-waf-أمام-تطبيقك)).

يعمل كل تغيير تحت مؤقِّت تراجع مدته 120 ثانية، ولا يُحتفَظ به إلا بعد أن ينجح اتصال جديد في الدخول، فلا يمكن لتغيير خاطئ أن يمنعك من الدخول.

غير أن قائمة السماح تبقى بعد زوال العنوان الذي أُنشئت منه: فإذا تغيّر عنوان منزلك، فطريق العودة هو دعم ERPC لخادم ERPC، أو وحدة تحكم المزوّد لخادم خاص بك. احتفظ في `firewall.ssh_allow` بعنوان ثانٍ يمكنك الوصول منه إلى الخادم (مكتب، أو مخرج VPN) قبل أن تعتمد على عنوان منزلي.

إذا تغيّر عنوانك، فأضف كل عنوان ثابت يستخدمه المسؤولون لديك:

```bash
erpc worker firewall allow --to ssh 203.0.113.10 198.51.100.7
```

| الأمر | ما يفعله |
| --- | --- |
| `erpc worker firewall list` | يعرض من يمكنه الوصول إلى الخادم: `erpc.toml` بجانب جدول الخادم |
| `erpc worker firewall allow --to ssh\|app <addresses>` | يسمح بدخول العناوين، ويطبّق ذلك. يُسمح بـSSH من عناوين مفردة؛ ولا تُقبل الشبكة إلا مع `--to app` |
| `erpc worker firewall deny --to ssh\|app <addresses>` | يوقف السماح بدخولها |
| `erpc worker firewall sync` | يعيد جدار حماية الخادم إلى ما يقوله `erpc.toml` |

## ضع WAF أمام تطبيقك

أضف جدولًا واحدًا إلى `erpc.toml`:

```toml
[waf]
port = 8080
```

بعد ذلك يشغّل `erpc worker deploy` بروكسيًا عكسيًا لـHTTP على الخادم، في وحدة systemd خاصة به (`erpc-waf-<app>-<env>`): يعمل باسم مستخدم ديناميكي بلا امتيازات، بلا مفتاح ولا سر ولا أي شيء من الـ worker، ومحدودًا بـ1 GiB من الذاكرة. يستمع على `waf.port`، ويقرأ كل طلب قبل أن يقرأه التطبيق، ويرفض ما تسمّيه قواعده، ويمرّر الباقي إلى التطبيق على `127.0.0.1:<run.port>`.

- **يبقى التطبيق على واجهة loopback.** لا يُفتح منفذه الخاص من الخارج أبدًا. يصل `erpc worker api` وفحص الصحة إلى التطبيق على واجهة loopback، متجاوزَين WAF.
- **من يمكنه الاتصال لا تزال تحدده قائمة جدار الحماية**، ومنفذ WAF هو المكان الوحيد الذي يجوز فيه لتلك القائمة أن تقول «الجميع»:

  ```sh
  erpc worker firewall allow --to app 0.0.0.0/0     # and ::/0
  ```

  إذا لم يُدرَج أحد، يستمع WAF ولا يُسمح لأحد بالدخول، ويذكر النشر ذلك.
- **يُفتح المنفذ بعد أن يستمع WAF عليه**، وليس قبل ذلك أبدًا. النشر الذي لا يعمل فيه WAF يفشل ويذكر السبب، مع بقاء التطبيق قيد التشغيل.
- **عندما تغيّر `[waf]`،** لا يُفتح المنفذ لأي شخص جديد حتى يضع نشرٌ القواعدَ الجديدة موضع التنفيذ.
- **إزالة `[waf]`** من `erpc.toml` ثم النشر يزيلان WAF من الخادم.

## إعدادات WAF

المطلوب هو `port` فقط. كل مفتاح مع قيمته الافتراضية:

```toml
[waf]
port = 8080          # the public port, 1024 or above; the app keeps [run] port
methods = ["GET", "POST", "PUT", "DELETE"]
allow_paths = []     # every path
deny_paths = []
max_body_bytes = 1048576
max_header_bytes = 16384
rate = { per_second = 50, burst = 100 }
max_connections_per_address = 32
ban = { after = 100, window_secs = 60, for_secs = 600 }
block_probes = true
header_timeout_secs = 10
body_timeout_secs = 30
upstream_timeout_secs = 30
new_connections = { per_second = 50, burst = 100 }
```

| المفتاح | ما يفعله | ما يتلقاه المرفوض |
| --- | --- | --- |
| `methods` | الطرق التي تُمرَّر، بالأحرف الكبيرة (16 على الأكثر؛ ولا `CONNECT` أبدًا) | 405، مع `Allow` |
| `allow_paths` | المسارات التي تُمرَّر؛ وعدم إدراج أي مسار يعني كل المسارات. النمط مسار واحد، أو كل ما تحت بادئة عندما ينتهي بـ`*`: `/api/*` تعني `/api` وكل ما تحته. يُقارَن بالمسار بعد فك ترميز النسبة المئوية مرة واحدة، مع التمييز بين الأحرف الكبيرة والصغيرة | 404 |
| `deny_paths` | مسارات تُرفض، تُكتب بالطريقة نفسها وتُفحص أولًا | 403 |
| `max_body_bytes` | أكبر حجم لجسم الطلب، حتى 64 MiB | 413 |
| `max_header_bytes` | أكبر حجم لسطر الطلب والترويسات معًا، من 1024 إلى 65536 | 431 |
| `rate` | عدد الطلبات في الثانية من عنوان واحد، وكم طلبًا يُقبل دفعة واحدة قبل أن ينطبق المعدل | 429، مع `Retry-After` |
| `max_connections_per_address` | الاتصالات التي يحتفظ بها عنوان واحد في وقت واحد | يُغلق الاتصال دون رد |
| `ban` | بعد `after` من الطلبات المحجوبة خلال `window_secs`، يُرفض العنوان مدة `for_secs` (حتى 30 يومًا) | تُغلق اتصالاته دون رد |
| `block_probes` | يرفض ما تطلبه أدوات المسح (`/.env` و`/.git` و`/wp-login.php` وما شابهها) | 403 |
| `header_timeout_secs` | المدة المتاحة للعميل لإرسال رأس الطلب، من 1 إلى 120. وهي أيضًا مدة انتظار عميل توقف في منتصف الجسم، أو توقف عن تلقي ردّه | 408 للرأس؛ و400 لجسم توقف؛ ويُغلق الاتصال لرد لم يُتلقَّ |
| `body_timeout_secs` | المدة الإجمالية التي يجوز أن يستغرقها جسم الطلب، من 1 إلى 600، دون احتساب الوقت الذي ينتظر فيه WAF التطبيق | 408 |
| `upstream_timeout_secs` | المدة المتاحة للتطبيق لقبول الاتصال وبدء الرد، من 1 إلى 600 | 504؛ و502 عندما لا يستمع التطبيق |
| `new_connections` | حد جدار الحماية نفسه لاتصالات TCP الجديدة في الثانية من عنوان واحد إلى منفذ WAF، ويُسقطها nftables قبل أن يراها البروكسي. وما دامت مجموعة العناوين في nftables ممتلئة، لا يُحتسب العنوان غير الموجود فيها، فلا ينطبق عليه هذا الحد حتى تتوفر في المجموعة مساحة من جديد؛ أما حدود البروكسي نفسه (`rate` و`max_connections_per_address` و`ban`) فلا تزال سارية | تُسقَط الحزمة |

تُعطَّل `rate` و`max_connections_per_address` و`ban` و`new_connections` بالقيمة `false` (`ban = false`)، والمفتاح المحذوف يأخذ قيمته الافتراضية. ويذكر `erpc worker check` ما سيفعله جدول `[waf]` وما فيه من أخطاء، قبل أي نشر.

## ما يفعله WAF دون حاجة إلى أي إعداد

- الطلب الذي لا يُقرأ كطلب HTTP/1 واحد لا لبس فيه يتلقى 400، وكذلك المسار الذي ليس بصيغته القياسية.
- طلب تغيير البروتوكول (`Upgrade`) يتلقى 501.
- كل رفض يُحتسب ضمن الحظر، وكل رفض يُنهي اتصاله.
- العنوان هو عنوان IPv4، أو `/64` من IPv6.
- لا يمرّر WAF ترويسات اتصال العميل بالبروكسي (`Connection` والترويسات التي تسمّيها، و`Keep-Alive` و`Proxy-Authenticate` و`Proxy-Authorization` و`Proxy-Connection` و`TE` و`Trailer`)، ولا `Expect`، ولا الترويسات التي يحتوي اسمها على شرطة سفلية، ولا ترويسات `Forwarded` و`X-Real-IP` و`X-Forwarded-Proto` الخاصة بالعميل. ويضبط `X-Real-IP` على العنوان الذي جاء منه الاتصال، ويضيف ذلك العنوان إلى نهاية `X-Forwarded-For`؛ والمُدخل الأخير وحده في `X-Forwarded-For` هو ما يشهد به البروكسي.

## اطّلع على ما يفعله WAF

| الأمر | ما يعرضه |
| --- | --- |
| `erpc worker status` | منفذ WAF، والجهة التي يمرّر إليها، ومنذ متى، والأعداد منذ ذلك الحين |
| `erpc worker firewall list` | من يمكنه الوصول إلى منفذ WAF، وما حُجب، حسب القاعدة |
| `erpc worker logs --waf` | كل طلب محجوب: القاعدة، والحالة، وعنوان العميل، والطريقة، وأول 200 بايت من الهدف |

الطلب المُمرَّر لا يترك سطرًا في السجل، ولا تُسجَّل أي ترويسة أو جسم أبدًا؛ أما استعلام الطلب المحجوب فيُسجَّل، في حدود ما تبلغه الـ 200 بايت. ولا يمكن لما يرسله العميل أن يكتب على طرفيتك: فـWAF يكتب سجله بأحرف ASCII قابلة للطباعة.

## ما لا يفعله WAF

- **لا TLS.** يعمل بـHTTP/1.1 العادي على منفذه.
- **لا HTTP/2:** يرد عليه بـ400.
- **لا WebSocket**، ولا أي `Upgrade` آخر: 501.
- **لا فحص لمحتوى الأجسام.** يُقاس الجسم ولا يُقرأ أبدًا. قائمة طلبات المسح قصيرة، وهي مرشّح للضجيج لا ضمان: لا يزال التطبيق هو من يتحقق من مدخلاته.
- **لا مصادقة.** من يحق له استدعاء التطبيق أمرٌ يقرره التطبيق، وقائمة جدار الحماية.
- **العنوان الواحد عميل واحد.** العملاء خلف NAT أو بروكسي أو CDN واحد يتشاركون معدلًا واحدًا وحظرًا واحدًا؛ والعميل الذي له عناوين كثيرة له معدلات بعددها.
- **يُنسى الحظر والأعداد** عند إعادة تشغيل WAF.
- **يتذكر 8192 عنوانًا على الأكثر** ويحتفظ بـ1024 اتصالًا على الأكثر في وقت واحد.
- **يستمع على IPv4 فقط،** لذا فإن مُدخل IPv6 في `app_allow` لا يصل إلى شيء حتى الآن.
- **يُقارَن المسار بالبايتات التي يُفك ترميزه إليها.** التطبيق الذي يقرأ المسارات بتساهل أكبر (متجاهلًا حالة الأحرف أو معاملات `;`، أو فاكًّا الترميز مرتين) يمكن الوصول إليه باسم لا يغطيه `deny_paths`. أما `allow_paths` فليس فيه هذه الثغرة: ما لم يُدرَج لا يُمرَّر.
- **القارئ البطيء يُخدَم حتى النهاية.** العميل الذي يواصل تلقي الرد، مهما كان بطيئًا، يُخدَم حتى النهاية.
- **يمكن للإغراق أن يقطع رفعًا كبيرًا.** يعمل WAF على خيط واحد، لذا يمكن للإغراق أن يقطع رفعًا كبيرًا بـ408. والتطبيق الذي يقبل أجسامًا كبيرة يرفع `body_timeout_secs` مع `max_body_bytes`.

[دليل الـ worker](https://github.com/elsoul/erpc-cli/blob/v0.1.0-rc.4/docs/worker.md) يتضمن كل قاعدة، بما في ذلك متى يُرجأ تغيير `app_allow` حتى النشر التالي.
