# جدار الحماية pf في macOS: ما الذي يستطيع فعله، ولماذا لا يمكن أن يكون جدار حماية تطبيقاتك > نظرة عملية على pf، مرشِّح الحزم من BSD داخل macOS: فحص القواعد وتحميلها بـ pfctl، والأسباب الملموسة — أسماء المضيفين، وهوية العملية، والمطالبات — التي جعلته لم يُبنَ أبدًا ليكون جدار حماية لكل تطبيق. HisnLabs Security & Research Team · Published 2026-09-17 Canonical: https://hisnlabs.com/ar/blog/macos-pf-firewall-limits يأتي كل جهاز Mac مزوَّدًا بشيئين يسميهما الناس «جدار الحماية». الأول هو جدار حماية التطبيقات (Application Firewall) في إعدادات النظام، وهو مفتاح لكل تطبيق للاتصالات الواردة. أما الثاني، الأكثر هدوءًا، فهو `pf`، مرشِّح الحزم من BSD الذي ورثه macOS من سلالة FreeBSD/OpenBSD والذي تستخدمه Apple نفسها خلف الكواليس لمشاركة الإنترنت وVPN وNAT. يمكن للمستخدمين المتقدمين والمسؤولين التحدث معه مباشرة عبر `pfctl`، وتعرض أدلة كثيرة مقتطف `pf.conf` وتكتفي بذلك. ما لا تشرحه تلك الأدلة غالبًا هو أين يتوقف pf عن أن يكون مفيدًا للشيء الذي يريده معظم الناس فعليًا: مراقبة والتحكم في ما ترسله تطبيقاتهم الخاصة إلى الخارج. هذا تمرين عملي لا محاضرة — سنفعّل pf، ونكتب قاعدة، ونقرأ الحالة التي يحتفظ بها، ثم ننظر بالضبط في سبب كون تلك الحالة الشكل الخاطئ لجدار حماية خاص بالتطبيقات. ## ما هو pf فعليًا pf مرشِّح حزم على مستوى النواة: يفحص الحزم أثناء عبورها واجهات الشبكة ويقرر، قاعدة تلو الأخرى، ما إذا كان سيمررها أو يحظرها. ليس لديه أي مفهوم لـ«التطبيقات» — يعمل بحتًا على رؤوس الحزم: عنوان المصدر والوجهة، والمنفذ، والبروتوكول، والواجهة، والاتجاه. هذا ليس قصورًا نسي أحدهم إصلاحه؛ إنه التصميم نفسه. بُني pf لتصفية الحركة على طبقة الشبكة، الطبقة نفسها التي تعمل عليها أجهزة التوجيه والبوابات، وهو بارع جدًا في تلك المهمة. تتحدث معه عبر `pfctl`، أداة التحكم. دليل استخدامها صريح بشأن الفصل بين ما يفعله: فهو يحمّل مجموعات قواعد من ملف إعداد، ويُبلغ عن الحالة التي تحتفظ بها النواة. خياران هما الأهم لتفعيل المرشِّح وتعطيله، بحسب صياغة دليل الاستخدام نفسه: `-e` («تفعيل مرشِّح الحزم») و`-d` («تعطيل مرشِّح الحزم»). لا شيء آخر في pf يُفعَّل أو يُعطَّل بمفرده — تتحرك مجموعة القواعد بأكملها معًا. ## تفعيله وقراءة حالته تمرين سريع، على جهاز Mac ترتاح فيه لاستخدام sudo. أولًا، تحقق مما إذا كان المرشِّح مفعّلًا بالفعل واطّلع على عداداته: *الطرفية — حالة pf وعداداته* ```console $ sudo pfctl -s info # example output, trimmed — the real thing includes per-rule and per-source-tracking stats with -v Status: Enabled for 0 days 02:14:07 Debug: err State Table Total Rate current entries 42 searches 88213 9.7/s inserts 611 0.1/s removals 569 0.1/s ``` ثم اسرد القواعد التي تحتفظ بها النواة حاليًا. يفعل `pfctl -s rules` هذا بالضبط؛ ويشير دليل الاستخدام إلى أنه مع `-v` يطبع أيضًا عدد مرات تقييم كل قاعدة، والحزم والبايتات: *الطرفية — القواعد المحمَّلة حاليًا* ```console $ sudo pfctl -s rules # example output, trimmed scrub-anchor "com.apple/*" all fragment reassemble anchor "com.apple/*" all block drop in log quick from to any ``` ذلك السطر `com.apple/*` ليس زخرفة. تحمّل Apple قواعدها الخاصة في مراسٍ (anchors) مسمّاة — مصطلح pf لمجموعة قواعد فرعية مكتفية بذاتها يمكن استبدالها دون إعادة تحميل كل شيء آخر. يستهدف خيار `-a` في `pfctl` مرسى محددًا، ووفق دليل الاستخدام، فإن استخدامه مع حرف بدل يفعّل الطباعة المتكررة للمراسي المتداخلة، وهذه هي الطريقة لرؤية ما حمّلته Apple نفسها إلى جانب أي شيء تضيفه أنت: *الطرفية — سرد كل مرسى محمَّل بشكل متكرر* ```console $ sudo pfctl -a '*' -s rules # example output, trimmed to the anchors that exist on a stock Mac ``` ### كتابة قاعدة اختبار وتحميلها ملف مرسى بسيط يحظر عنوان IP واحدًا صادرًا، محفوظ باسم `/etc/pf.anchors/test-block`: */etc/pf.anchors/test-block* ```text block drop out quick on en0 proto tcp to 203.0.113.10 port 443 ``` لتحميل ملف مرسى واحد، يقرأ `pfctl -f` القواعد من ملف، ووفق دليل استخدامه، يصف الملف بأنه يحتوي على وحدات ماكرو وجداول وخيارات وقواعد تصفية: *الطرفية — تحميل القاعدة وتأكيدها* ```console $ sudo pfctl -f /etc/pf.anchors/test-block $ sudo pfctl -s rules block drop out quick on en0 proto tcp from any to 203.0.113.10 port = 443 ``` > **Warning:** هذا تمرين مخبري، لا توصية بتحرير `/etc/pf.conf` يدويًا على جهاز Mac تستخدمه يوميًا. خطأ في صياغة مجموعة قواعد نشطة يمكن أن يقطع جلسة SSH الخاصة بك أو يحظر حركة كنت بحاجة إليها — وكما يوضح القسم التالي، فإن قواعدك المكتوبة يدويًا لا تصمد بالطريقة التي قد تتوقعها. ## لماذا لا يمكن أن يكون pf جدار حماية تطبيقاتك لا شيء مما يلي خلل. إنه ما يحدث حين توجّه مرشِّح حزم على طبقة الشبكة نحو مهمة تتطلب معرفة أي عملية أرسلت الحزمة. ### لا فكرة لديه عن أي تطبيق أرسل الحزمة تطابق قواعد pf على عنوان IP والمنفذ والبروتوكول والواجهة والاتجاه. لا يوجد حقل لـ«اسم العملية» أو «معرّف الحزمة» أو «توقيع الكود»، لأن pf يقع عند الطبقة التي توجد فيها الحزم لكن لا توجد فيها العمليات. تطبيقان مختلفان تمامًا يفتحان اتصالات TCP إلى العنوان والمنفذ نفسيهما لا يمكن تمييزهما بالنسبة لـ pf. إن أردت السماح لـ Slack بالوصول إلى مضيف بينما تحظر كل تطبيق آخر من الوصول إلى المضيف نفسه، لا يستطيع pf وحده التعبير عن تلك القاعدة. ### القاعدة على اسم مضيف هي قاعدة على أيًا كان عنوان IP الذي كان لذلك الاسم وقت التحميل كثيرًا ما تشير ملفات pf.conf إلى اسم مضيف من أجل الوضوح — `block from evil.example.com`. لكن ما يُحمَّل فعليًا ليس ذلك الاسم؛ بل أيًا كان العنوان الذي حُلّ إليه. يذكر دليل استخدام pf.conf من OpenBSD ذلك بوضوح: «تحليل اسم المضيف وترجمة الواجهة إلى عنوان يتمّان وقت تحميل مجموعة القواعد». لا يوجد بحث DNS وقت التشغيل أثناء تدفق الحركة — يحدث الاستبدال مرة واحدة، حين تشغّل `pfctl -f`، وتستمر القاعدة في مطابقة ذلك العنوان الواحد حتى تعيد تحميلها. هذا جيد بالنسبة لخادم بعنوان IP ثابت. لكنه ينهار لحظة أن يكون الاسم وراءه شبكة توصيل محتوى (CDN)، أو موازن تحميل سحابي، أو أي خدمة تُناوِب أو توازن التحميل عبر عناوين كثيرة — وهو ما يصف معظم الإنترنت في 2026. تضيق القاعدة المقصودة لحظر «هذه الخدمة» بصمت لتصبح «أيًا كان عنوان تلك الخدمة الذي أجاب حين حمّلت القاعدة»، وتمر الحركة إلى كل عنوان آخر يحلّه الاسم نفسه دون عائق. ### لا مطالبات، لا حوار — مجرد مجموعة قواعد ثابتة ليس لدى pf نموذج تفاعل. لا يستطيع إيقاف اتصال مؤقتًا وسؤال «يريد Mail الوصول إلى 51.x.x.x على المنفذ 993 لأول مرة — هل تسمح بذلك؟». إما أن يطابق قاعدة كتبتها بالفعل، أو ينحدر إلى الإعداد الافتراضي. يجب توقّع كل قرار وكتابته مسبقًا، بمصطلحات IP ومنفذ، قبل حدوث الحركة. لا يوجد ما يعادل مطالبة الاتصال الأول، لأن المطالبة تتطلب معرفة أي تطبيق يسأل، ولا تملك pf تلك المعلومة من الأساس. ### إعدادك المكتوب يدويًا لا يصمد أمام تحديث تعامل Apple ملف `/etc/pf.conf` والمراسي التي يحمّلها كإعداد يديره النظام مرتبط بداخليات macOS — مشاركة الإنترنت، وVPN، ومراسي جدار حماية التطبيقات نفسها تعتمد عليه جميعًا. تحديثات macOS حرة في إعادة كتابة ذلك الملف أو استبداله. إن حرّرته يدويًا لإضافة قواعدك الخاصة، فلا ضمان أن تصمد أمام التحديث التالي؛ وتكتشف ذلك بالطريقة الصعبة، بعد فوات الأوان، أن قاعدتك توقفت عن التطبيق بصمت. ملف إعداد يصونه شخص يدويًا ويكتب فوقه نظام التشغيل دوريًا مكان سيء للاحتفاظ فيه بالشيء الوحيد الذي كنت تهتم به فعليًا — «هل تحدث جهاز الـ Mac الخاص بي مع ذلك العنوان مجددًا». ### لا عارض سجلات، لا سجل تاريخي، لا خريطة يستطيع pf تسجيل الحزم المطابقة إلى واجهة زائفة، `pflog0`، إن تضمنت قاعدة الكلمة المفتاحية `log` — ظاهرة أعلاه في قاعدة قائمة الحظر من مخرجات `-s rules` السابقة. لكن ذلك السجل تدفق التقاط حزم، يُقرأ بـ `tcpdump -i pflog0`، لا سجلًا تاريخيًا قابلًا للبحث. لا يوجد عارض مدمج، ولا قائمة لكل تطبيق بما حُظر ومتى، ولا دولة أو منظمة مرتبطة بعنوان، ولا شيء يمكنك عرضه على أحد للإجابة عن «ماذا حاول هذا الـ Mac الوصول إليه الأسبوع الماضي». تحصل على حزم خام، وعليك بناء البقية بنفسك. ## الطبقة التي بنتها Apple فعليًا لهذه المهمة إجابة Apple نفسها على «أريد تصفية حركة جهاز الـ Mac الخاص بي لكل تطبيق» ليست pf — بل إطار عمل Network Extension، وتحديدًا مزوّدو مرشِّح المحتوى فيه. يصف توثيق مطوري Apple النموذج مباشرة: «يفحص مرشِّح محتوى شبكة على الجهاز محتوى شبكة المستخدم أثناء مروره عبر مكدس الشبكة، ويقرر ما إذا كان ينبغي حظر ذلك المحتوى أو السماح له بالمرور إلى وجهته النهائية»، ومزوّد بيانات مرشِّح — `NEFilterDataProvider` — «يستقبل محتوى شبكة المستخدم ويفحص ذلك المحتوى لتقرير ما إذا كان سيُحظر أو يُسمح به». تُمثَّل التدفقات ككائنات `NEFilterFlow` (بحالات ملموسة هي `NEFilterBrowserFlow` و`NEFilterSocketFlow`)، وهذه هي القطعة المفقودة التي لم يمتلكها pf أبدًا: كائن تدفق يمكن لتطبيق تصفية فحصه وربطه بالعملية التي فتحته، قبل تقرير التمرير أو الحظر. هذا أيضًا سبب كون جدار حماية التطبيقات المدمج (المفتاح في إعدادات النظام) حيوانًا مختلفًا عن pf، لا واجهة أمامية له. يصفه دليل Apple نفسه بمصطلحات واردة فقط: فهو «يمكنه حماية جهاز الـ Mac الخاص بك من اتصال غير مرغوب فيه تبدأه حواسيب أخرى»، ويعمل بالسماح لك بـ«اختيار تطبيقات وخدمات، وتحديد ما إذا كان بإمكانها الوصول عبر جدار الحماية». لكل تطبيق، نعم — لكن فقط للاتصالات الواردة، وفقط عبر الآلية المحددة التي بنتها Apple لتلك المهمة الواحدة. إنه يجيب عن سؤال مختلف عن «ما الذي يرسله تطبيقي إلى الخارج». | النهج | يرى IP/المنفذ | يعرف أي تطبيق | يتعامل مع عناوين IP المُعاد تسميتها/المُناوَبة | يمكنه مطالبة المستخدم | الاتجاه | | --- | --- | --- | --- | --- | --- | | pf (‏`pfctl`) | نعم | لا | لا — يُحل مرة واحدة وقت التحميل | لا | أي منهما، حسب القاعدة | | جدار حماية التطبيقات (إعدادات النظام) | لا (مفتاح على مستوى التطبيق) | نعم | لا ينطبق | لا | وارد فقط | | مرشِّح محتوى Network Extension | نعم | نعم، عبر كائن التدفق | نعم — يُقيَّم لكل تدفق حي | نعم، بواسطة التطبيق المبني عليه | صادر ووارد | *ثلاث طرق لتصفية الحركة على جهاز Mac، وما يعرفه كل منها فعليًا* لا شيء من هذا يجعل pf عديم الفائدة. إن كنت تشغّل جهاز Mac كموجّه خفيف، أو تحتاج إلى رفض نطاق معروف بأنه سيئ على مستوى النواة بغض النظر عن أي عملية تسأل، أو تريد فهم ما تفعله ميزات مشاركة الإنترنت وVPN الخاصة بـ Apple نفسها خلف الكواليس، فإن pf هو الأداة الصحيحة والوحيدة لتلك المهمة، و`pfctl -s rules` / `-s info` هما الطريقة الصحيحة للنظر فيه. ما لم يكن pf ليفعله أبدًا هو الإجابة عن السؤال الذي يطرحه معظم الناس فعليًا: أي من تطبيقاتي يتحدث مع من، الآن، وهل يمكن أن يُسأل عني قبل أن يصل تطبيق جديد إلى ذلك. ## دور FireAI وHisnLabs pf and the built-in Application Firewall are both worth using — FireAI does not replace either; it fills the specific gap neither one can, by tying outbound decisions to the app’s code signature and asking before an unknown one gets a first connection. FireAI هو منتج HisnLabs نفسها: جدار حماية بذكاء اصطناعي يعمل على جهاز Mac مباشرة. يعرض بلغة واضحة كل اتصال تجريه تطبيقاتك، ويترك لك القرار فيما يخرج من جهازك — ذكاؤه الاصطناعي يعمل محليًا، فلا يُرسَل ترافيكك إلينا ولا إلى أي جهة أخرى أبدًا. فريق أبحاث الأمن في HisnLabs هو من يحافظ على دقة هذه القرارات: يصنّف النطاقات بين قياس عن بُعد عادي وخدمة حقيقية، ويتتبّع بلد وشبكة كل اتصال، ويدرّب النموذج المحلي (ميزة FireAI Pilot) على حركة اتصال حقيقية، دون أن يغادر أي شيء جهاز Mac. يمكنك الاطلاع على القرارات التقنية وراء ذلك، أو تجربة FireAI لمدة 17 يومًا، على [FireAI من HisnLabs](https://hisnlabs.com/fireai/ar/download). ## Sources - [pfctl(8) man page (Xcode man pages mirror)](https://keith.github.io/xcode-man-pages/pfctl.8.html) - [OpenBSD pf.conf(5) man page](https://man.openbsd.org/pf.conf) - [Apple Developer: Content filter providers (NetworkExtension)](https://developer.apple.com/documentation/networkextension/content-filter-providers) - [Apple Support: Block connections to your Mac with a firewall](https://support.apple.com/guide/mac-help/block-connections-to-your-mac-with-a-firewall-mh34041/mac)