SSD Nodes Learn
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-07-22

تشغيل الخدمات بحساب محدود الصلاحيات

تشغيل خدمة بحساب root يحوّل أي علة بسيطة إلى وصول كامل إلى الخادم. امنح كل خدمة حسابها الخاص محدود الصلاحيات، أو دع systemd يتولى ذلك عبر DynamicUser.

لماذا لا نُشغّل كل شيء بحساب root

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

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

حساب مخصص لكل خدمة

النهج التقليدي هو إنشاء مستخدم نظام (system user) مستقل لكل خدمة، مستخدم يملك فقط ملفات تلك الخدمة ولا يستطيع تسجيل الدخول. حساب نظام لتطبيق ويب قد يبدو هكذا:

sudo useradd --system --no-create-home --shell /usr/sbin/nologin appsvc

كل خيار له أهميته. --system يجعله حساب خدمة لا حساب دخول بشري. --no-create-home يتجاوز إنشاء دليل منزلي لا حاجة له إليه. --shell /usr/sbin/nologin يعني أنه حتى لو تمكّن مهاجم بطريقة ما من الاستيلاء على الحساب، فلن يستطيع فتح shell به. الحساب موجود فقط ليملك عملية (process) وملفاتها.

بعد ذلك امنح ذلك المستخدم الملفات التي يحتاجها فقط، ولا شيء غير ذلك:

sudo chown -R appsvc:appsvc /opt/myapp

الآن تقرأ الخدمة وتكتب داخل دليلها الخاص، وليس لها ما تفعله في أي موضع آخر على القرص. وإذا استُغلّت يومًا، فإن الملفات التي يستطيع المهاجم تغييرها تقتصر على /opt/myapp؛ ويظل بإمكان الحساب قراءة أي شيء يستطيع الجميع قراءته (world-readable)، لكنه لا يستطيع تعديل بقية النظام.

دع systemd يشغّلها بهذا المستخدم

بمجرد وجود الحساب، أخبر systemd بتشغيل الخدمة باستخدامه. في ملف الـ unit، يكفي سطر واحد لذلك:

[Service]
ExecStart=/opt/myapp/bin/server
User=appsvc
Group=appsvc

User=appsvc يعني أن العملية تبدأ بصلاحيات ذلك الحساب المحدودة بدلًا من صلاحيات root. هذه هي الطريقة المعتادة والمجرَّبة لتشغيل تطبيق تحت systemd، وتستحق أن تُطبَّق على كل خدمة تكتب لها unit.

أو تجاوز الحساب كليًا باستخدام DynamicUser

يمكن لـ systemd أن يذهب خطوة أبعد وينشئ لك مستخدمًا مؤقتًا لا يوجد إلا أثناء عمل الخدمة. اضبط DynamicUser=yes ولن تحتاج إلى إدارة أي حساب على الإطلاق:

[Service]
ExecStart=/opt/myapp/bin/server
DynamicUser=yes
StateDirectory=myapp

عند البدء، يخصّص systemd معرّف مستخدم (user ID) لم يُستخدم من قبل؛ وعند التوقف، يحرّره. كما تحصل الخدمة على /tmp خاص بها، ورؤية للقراءة فقط لمعظم نظام الملفات، ودليل حالة (state directory) قابل للكتابة تحت /var/lib/myapp يُعِدّه StateDirectory= ويسلّمه لها. بالنسبة لخدمة قائمة بذاتها لا تحتاج إلا إلى دليل حالتها الخاص، فإن DynamicUser=yes هو أقل الطرق جهدًا للحصول على عزل قوي، لأنه لا يوجد أصلًا أي حساب طويل الأمد يستهدفه مهاجم.

كتابة الـ units يدويًا أمر دقيق ومزعج، وضبط توجيهات التحصين (hardening directives) بشكل صحيح هو معظم القيمة المطلوبة. يمكن للمولّد الموجود في دليل خدمات ومؤقتات systemd أن يملأ هذه الخيارات نيابة عنك حتى يكون الـ unit صحيحًا من المحاولة الأولى.

كيف يتناسب هذا مع البقية

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

قبل أن تنتقل إلى ما بعد ذلك، راجع قائمة تحقق للتحصين تخص الجهاز بأكمله، وولّد نسخة مخصصة لك تعمل عليها:

ToolVPS hardening checklist

FAQ

لماذا لا ينبغي أن أُشغّل خدمة بحساب root؟

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

كيف أنشئ مستخدمًا لا يستطيع تسجيل الدخول؟

نفّذ الأمر sudo useradd --system --no-create-home --shell /usr/sbin/nologin NAME. الـ shell المسمى nologin يعني أن الحساب لا يستطيع فتح جلسة تفاعلية حتى لو سُرقت بيانات اعتماده، و--system يُعلِّمه بوصفه حساب خدمة، و--no-create-home يتجاوز إنشاء دليل منزلي لا حاجة له إليه. امنحه ملكية ملفاته الخاصة فقط باستخدام chown.

ما هو DynamicUser في systemd؟

DynamicUser=yes يخبر systemd بإنشاء مستخدم مؤقت للخدمة لا يوجد إلا أثناء عملها، بحيث لا تدير أبدًا حسابًا طويل الأمد. كما يمنح الخدمة /tmp خاصًا بها، ورؤية للقراءة فقط لمعظم نظام الملفات، ودليل حالة تتم إدارته تلقائيًا. إنها أقل الطرق جهدًا لتشغيل خدمة قائمة بذاتها تحت هوية مؤقتة ومحدودة الصلاحيات.

هل يغني تشغيل خدمة بمستخدم غير root عن جدار الحماية؟

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

ما الملفات التي ينبغي أن يملكها مستخدم الخدمة؟

فقط الملفات التي تحتاجها الخدمة فعليًا، ولا شيء أكثر. امنح الحساب ملكية دليل العمل الخاص به وبياناته، واترك كل شيء آخر مملوكًا لـ root. النمط الجيد هو sudo chown -R svc-app:svc-app /opt/svc-app لدليل التطبيق، بينما تبقى الإعدادات تحت /etc مملوكة لـ root ومقروءة فقط من قبل الخدمة. الهدف هو أنه إذا اختُرقت العملية يومًا، فإن الملفات التي تستطيع تغييرها تقتصر على بياناتها الخاصة، لا على بقية النظام.

#أمان#least-privilege#systemd#users#hardening#linux