وضع الحماية

تتناول هذه المقالة وضع الحماية في Bazel، وتثبيت sandboxfs، وتصحيح الأخطاء في بيئة وضع الحماية.

وضع الحماية هو إذن يقيّد الاستراتيجية التي تمنع العمليات عن بعضها البعض أو عن الموارد في النظام. بالنسبة إلى Bazel، يعني ذلك حظر إمكانية الوصول إلى نظام الملفات.

يعمل وضع الحماية الخاص بنظام الملفات Bazel' على تنفيذ العمليات في دليل صالح لا يحتوي إلا على إدخالات معروفة، مثل عدم رؤية برامج التجميع والأدوات الأخرى ملفات المصدر التي لا يجب الوصول إليها، ما لم يكن يعرف المسارات المطلقة لها.

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

على وجه التحديد، ينشئ Bazel دليل execroot/ لكل إجراء، يعمل كدليل عمل Action&39;s في وقت التنفيذ. execroot/ يحتوي هذا الملف على كل ملفات الإدخال للإجراء، ويعمل كحاوية لأي مخرجات يتم إنشاؤها. يستخدم Bazel بعد ذلك أسلوبًا توفّره نظام التشغيل، وهو حاويات على نظامَي التشغيل Linux وsandbox-exec على نظام التشغيل macOS لتقييد الإجراء ضمن execroot/.

أسباب وضع الحماية

  • بدون وضع الحماية للإجراء، لا يعرف Bazel ما إذا كانت الأداة تستخدم ملفات إدخال غير مُعلَن عنها (ملفات غير مُدرجة صراحةً في تبعيات الإجراء). عندما يتغير أحد ملفات الإدخال غير المعلَنة، يظل "بازل" يعتقد أنّ الإصدار محدَّث ولن يعيد إنشاء الإجراء. وهذا ما قد يؤدي إلى إنشاء تصميم تدريجي غير صحيح.

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

  • يحاكي وضع الحماية سلوك التنفيذ عن بُعد. إذا كان الإصدار يعمل بشكلٍ جيد مع وضع الحماية، من المرجّح أن يعمل أيضًا مع التنفيذ عن بُعد. من خلال تنفيذ التنفيذ عن بُعد لتحميل جميع الملفات اللازمة (بما في ذلك الأدوات المحلية)، يمكنك تقليل تكاليف الصيانة للمجموعات بشكل ملحوظ مقارنةً بتثبيت الأدوات على كل جهاز في المجموعة في كل مرة تريد فيها تجربة استخدام برنامج تجميع جديد أو إجراء تغيير على أداة حالية.

استراتيجية وضع الحماية التي يجب استخدامها

يمكنك اختيار نوع وضع الحماية الذي تريد استخدامه، إن أمكن، من خلال العلامات الاستراتيجية. إنّ استخدام استراتيجية sandboxed يساعد Bazel في اختيار أحد عمليات تنفيذ وضع الحماية المدرَجة أدناه، ويفضّل استخدام وضع الحماية الخاص بنظام التشغيل على وضع التشغيل العام الأقل زخرفة. يعمل العاملون الدائمون في وضع الحماية العام إذا اجتازت علامة --worker_sandboxing.

لا تنفّذ استراتيجية local (المعروفة أيضًا باسم standalone) أي نوع من وضع الحماية. ينفّذ الأمر ببساطة تنفيذ سطر الأوامر action&#39؛ مع ضبط دليل العمل على تنفيذ الإجراء في مساحة العمل.

processwrapper-sandbox هي استراتيجية وضع الحماية التي لا تتطلب أيًا من "quot;الإعدادات المتقدّمة": يجب أن تعمل على أي نظام من أنظمة POSIX عند إخراجها من الصندوق. تنشئ الدليل دليلاً إرشاديًا يتألف من روابط رمزية تشير إلى ملفات المصدر الأصلية، وينفّذ سطر الأوامر Action's مع ضبط دليل العمل على هذا الدليل بدلاً من execroot، ثم ينقل عناصر الإخراج المعروفة من وضع الحماية إلى الرمز ويحذف وضع الحماية. ويؤدي ذلك إلى منع الإجراء عن غير قصد من استخدام أي ملفات إدخال لم يتم الإعلان عنها ومن تنفيذ الإجراء باستخدام ملفات مخرجات غير معروفة.

linux-sandbox يتقدّم بخطوات إضافية إلى جانب processwrapper-sandbox. على غرار الإجراء الذي تنفّذه أداة الإرساء، يستخدم نظام التشغيل Linux مساحات الاسم (المستخدم والتثبيت وPID والشبكة وIPC) لعزل الإجراء عن المضيف. وهذا يعني أنّ نظام التشغيل سيجعل نظام الملفات بالكامل للقراءة فقط، باستثناء دليل وضع الحماية، وبالتالي لا يمكن لهذا الإجراء تعديل أي عنصر في نظام الملفات المضيف عن طريق الخطأ. ويساهم ذلك في منع حدوث أخطاء مثل اختبار خطأ بغير قصد -rf'ing دليل $HOME. يمكنك أيضًا منع الإجراء من الوصول إلى الشبكة. يستخدم linux-sandbox مساحات أسماء PID لمنع الإجراء من الاطّلاع على أي عمليات أخرى وقتل جميع العمليات (حتى البرامج الخفية التي تم حذفها من خلال الإجراء) بشكل موثوق في النهاية.

darwin-sandbox متشابهة، ولكن بالنسبة إلى نظام التشغيل macOS. وتستخدم هذه الأداة أداة sandbox-exec التابعة لـ Apple® لتحقيق أداء وضع الحماية تقريبًا مثل وضع الحماية في Linux.

لا يعمل كل من linux-sandbox وdarwin-sandbox في سيناريو "nested";، بسبب القيود المفروضة على الآليات التي توفّرها أنظمة التشغيل. بما أنّ مساحة الإرساء تستخدم أيضًا مساحات عمل Linux لسحر الحاوية، لا يمكنك تشغيل linux-sandbox بسهولة داخل حاوية إرساء، إلا إذا كنت تستخدم docker run --privileged. على نظام التشغيل macOS، لا يمكنك تشغيل sandbox-exec داخل عملية قيد الحماية حاليًا. وبالتالي، في هذه الحالات، يعود Bazel تلقائيًا إلى استخدام processwrapper-sandbox.

إذا كنت تفضّل حدوث خطأ في الإصدار، مثل عدم عرضه عن طريق الخطأ باستخدام استراتيجية تنفيذ أقل صرامة، عليك تعديل قائمة استراتيجيات التنفيذ صراحةً، التي يحاول Bazel استخدامها (على سبيل المثال، bazel build --spawn_strategy=worker,linux-sandbox).

يتطلب التنفيذ الديناميكي عادةً وضع الحماية للتنفيذ المحلي. لإيقاف هذه الميزة، مرِّر العلامة --experimental_local_lockfree_output. يؤدي التنفيذ الديناميكي إلى استخدام وضع العمال الدائمين في وضع الحماية بشكل غير ملحوظ.

سلبيات وضع الحماية

  • يفرض وضع الحماية تكلفة إضافية على الإعداد والإنهاء. وتعتمد هذه التكلفة على عدّة عوامل، من بينها شكل التصميم وأداء نظام التشغيل المضيف. بالنسبة إلى نظام التشغيل Linux، نادرًا ما تكون الإصدارات في وضع الحماية أبطأ بمقدار {0/} بالمئة. ويمكن أن يؤدي ضبط السياسة --reuse_sandbox_directories إلى الحدّ من تكلفة الإعداد وإنهاء التكلفة.

  • يعمل وضع الحماية على إيقاف أي ذاكرة تخزين مؤقت قد تستخدمها الأداة بشكل فعّال. ويمكنك الحدّ من هذه المشكلة عن طريق استخدام العاملين الدائمين، وذلك على تكلفة ضمانات وضع الحماية الضعيفة.

  • يتطلب العمّال المتعددون دعمًا صريحًا للعاملين بوضع الحماية. يعمل العاملون الذين لا يتوافقون مع وضع الحماية المتعدد كعمال عاديين ضمن التنفيذ الديناميكي، ما قد يؤدي إلى تكلفة إضافية للذاكرة.

وضع الحماية

sandboxfs هو نظام ملفات FUSE يكشف طريقة عشوائية عن نظام الملفات الأساسي بدون غرامات زمنية. يستخدم Bazel sandboxfs لإنشاء execroot/ فورًا لكل إجراء، مع تجنّب تكلفة إصدار آلاف مكالمات النظام. يُرجى العِلم أنّ مؤتمر I/O الإضافي في execroot/ قد يكون أبطأ بسبب النفقات العامة.

تثبيت وضع الحماية

استخدم الخطوات التالية لتثبيت sandboxfs وإجراء إصدار من Bazel باستخدامه:

تنزيل

تنزيل وتثبيت sandboxfs لكي ينتهي البرنامج الثنائي sandboxfs في PATH.

تشغيل sandboxfs

  1. (نظام التشغيل macOS فقط) تثبيت OSXFUSE.
  2. (لنظام التشغيل macOS فقط) التشغيل:

    sudo sysctl -w vfs.generic.osxfuse.tunables.allow_other=1
    

    ستحتاج إلى إجراء ذلك بعد التثبيت وبعد كل إعادة تشغيل لضمان عمل خدمات نظام التشغيل macOS الأساسية من خلال وضع الحماية.

  3. يمكنك تشغيل إصدار Bazel باستخدام --experimental_use_sandboxfs.

    bazel build target --experimental_use_sandboxfs
    

تحديد المشاكل وحلّها

إذا رأيت local بدلاً من darwin-sandbox أو linux-sandbox كتعليق توضيحي للإجراءات التي تم تنفيذها، قد يعني ذلك أن وضع الحماية غير مفعَّل. يُرجى تمرير --genrule_strategy=sandboxed --spawn_strategy=sandboxed لتفعيله.

تصحيح الأخطاء

اتّبِع الاستراتيجيات أدناه لتصحيح المشاكل المرتبطة بوضع الحماية.

مساحات الأسماء غير المفعّلة

في بعض الأنظمة الأساسية، مثل عُقد المجموعة Google Kubernetes Engine أو Debian، يتم إيقاف مساحات أسماء المستخدمين تلقائيًا بسبب مخاوف تتعلق بالأمان. إذا كان الملف /proc/sys/kernel/unprivileged_userns_clone يحتوي على 0، يمكنك تفعيل مساحات أسماء المستخدمين من خلال تنفيذ ما يلي:

   sudo sysctl kernel.unprivileged_userns_clone=1

تعذّر تنفيذ القاعدة

قد يتعذّر على وضع الحماية تنفيذ القواعد بسبب إعداد النظام. إذا ظهرت لك رسالة، مثل namespace-sandbox.c:633: execvp(argv[0], argv): No such file or directory، جرِّب إيقاف وضع الحماية مع --strategy=Genrule=local للقواعد العامة، و--spawn_strategy=local لقواعد أخرى.

تصحيح الأخطاء التفصيلي لحالات تعذّر الإصدار

في حال تعذّر الإصدار، يمكنك استخدام --verbose_failures و--sandbox_debug لجعل Bazel يعرض الأمر الذي تم تنفيذه بالضبط عندما تعذّر الإصدار، بما في ذلك الجزء الذي أعدّ وضع الحماية.

مثال على رسالة الخطأ:

ERROR: path/to/your/project/BUILD:1:1: compilation of rule
'//path/to/your/project:all' failed:

Sandboxed execution failed, which may be legitimate (such as a compiler error),
or due to missing dependencies. To enter the sandbox environment for easier
debugging, run the following command in parentheses. On command failure, a bash
shell running inside the sandbox will then automatically be spawned

namespace-sandbox failed: error executing command
  (cd /some/path && \
  exec env - \
    LANG=en_US \
    PATH=/some/path/bin:/bin:/usr/bin \
    PYTHONPATH=/usr/local/some/path \
  /some/path/namespace-sandbox @/sandbox/root/path/this-sandbox-name.params --
  /some/path/to/your/some-compiler --some-params some-target)

يمكنك الآن فحص دليل وضع الحماية الذي تم إنشاؤه والاطّلاع على الملفات التي أنشأها Bazel وتشغيل الأمر مرة أخرى لمعرفة سلوكه.

يُرجى ملاحظة أن Bazel لا يحذف دليل وضع الحماية عند استخدام --sandbox_debug. يجب إيقاف متصفّح --sandbox_debug لأنّه يملأ القرص بمرور الوقت ما لم يتم تصحيح الأخطاء حاليًا.