أساسيات لينكس

المستخدمون والمجموعات وأمر sudo

18 دقيقة الدرس 5 من 26

المستخدمون والمجموعات وأمر sudo

كل عملية وكل ملف وكل اتصال شبكي على نظام Linux يعمل تحت هوية محددة. هذه الهوية تحدد ما يمكنه قراءته وكتابته وتنفيذه. فهم نموذج المستخدمين والمجموعات في Linux ليس معرفة خلفية اختيارية لمهندس DevOps — بل هو أساس أمان الحد الأدنى من الصلاحيات، والسبب في أن منفذي CI الآلية لا تعمل بصلاحيات root، وأول ما يفحصه المدقق بعد أي اختراق. هذا الدرس يعلّم النموذج كما يفكر فيه مهندسو الإنتاج: دقة ميكانيكية مع أولوية الأمان.

فكرة جوهرية: التحكم في وصول Linux قائم كلياً على الهوية. النواة لا تهتم بكلمات المرور أو الشهادات أثناء التشغيل — بل تهتم بمعرّف المستخدم الرقمي (UID) ومعرّفات المجموعات (GIDs) المرتبطة بعملية ما. كل قرار صلاحية يتلخص في: "هل هذه التوليفة من UID/GID تمتلك بتات الحق الصحيحة على هذه العقدة؟"

ملف /etc/passwd

على الرغم من اسمه، لا يخزّن /etc/passwd كلمات المرور بعد الآن (انتقلت إلى ملف shadow منذ عقود). يخزّن الحقول السبعة التي تعرّف كل حساب مستخدم على النظام. اقرأه مباشرة — فهو مقروء للجميع ولا تُخفي أي أداة بنيته.

# قراءة ملف passwd cat /etc/passwd # سطور نموذجية (التنسيق: login:x:UID:GID:comment:home:shell) root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash deploy:x:1001:1001:Deploy service account:/home/deploy:/bin/bash # تفسير سطر واحد # الحقل 1 اسم تسجيل الدخول : deploy # الحقل 2 علامة كلمة المرور : x (الهاش الحقيقي في /etc/shadow، للـroot فقط) # الحقل 3 UID : 1001 # الحقل 4 GID الأساسية : 1001 # الحقل 5 تعليق GECOS : Deploy service account # الحقل 6 المجلد الرئيسي : /home/deploy # الحقل 7 shell تسجيل الدخول: /bin/bash # /usr/sbin/nologin = لا يمكن فتح shell تفاعلي

نطاقات UID التي ستصادفها على كل توزيعات Linux:

  • UID 0root. حساب واحد، صلاحية غير محدودة. النواة تتجاوز فحوصات الصلاحية للـUID 0.
  • UID 1–999 — حسابات النظام. تُنشأ بواسطة مدراء الحزم للخدمات الخلفية (www-data وpostgres وredis). لديها /usr/sbin/nologin كـshell — لا أحد يستطيع الدخول بها تفاعلياً.
  • UID 1000+ — المستخدمون البشريون. أول حساب بشري هو 1000 بالاصطلاح على Debian/Ubuntu وكذلك على RHEL/Amazon Linux.
ممارسة الإنتاج: كل خدمة خلفية يجب أن تعمل تحت حسابها النظامي المخصص بدون shell دخول ومجلد رئيسي تملكه. خادم ويب يعمل بـwww-data لا يستطيع إلا قراءة الملفات المقروءة عالمياً أو المملوكة لـwww-data. عملية www-data المخترقة لا تستطيع لمس /home/ubuntu أو قراءة أسرار خدمات أخرى. هذا هو مبدأ الحد الأدنى من الصلاحيات مطبقاً على هوية العملية.

المجموعات — مشاركة الوصول دون مشاركة الهوية

المجموعة هي مجموعة مسمّاة من المستخدمين يمكن منحهم صلاحيات بشكل جماعي. كل ملف له مالك (UID) ومجموعة مالكة (GID). بتات الصلاحية مقسّمة على ثلاث فئات: المالك والمجموعة والآخرون.

عضوية المجموعات مخزّنة في /etc/group:

# تنسيق /etc/group: groupname:x:GID:member1,member2,... cat /etc/group | grep -E 'docker|sudo|deploy' # ناتج نموذجي sudo:x:27:ubuntu,alice docker:x:999:ubuntu,deploy deploy:x:1001: # تحقق من مجموعاتك id # uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),27(sudo),999(docker) # تحقق من مجموعات مستخدم آخر id deploy # uid=1001(deploy) gid=1001(deploy) groups=1001(deploy),999(docker) # إضافة مستخدم لمجموعة (يسري عند تسجيل الدخول التالي) sudo usermod -aG docker deploy # إضافة مستخدم لعدة مجموعات دفعة واحدة sudo usermod -aG docker,deploy alice

أهم المجموعات تشغيلياً في بيئة DevOps نموذجية:

  • sudo (Debian/Ubuntu) / wheel (RHEL/Amazon Linux) — تمنح وصول sudo
  • docker — تسمح بتشغيل أوامر Docker دون sudo (تحذير: هذا فعلياً وصول root على المضيف)
  • adm — تسمح بقراءة ملفات سجلات النظام في /var/log
  • www-data — تستخدمها nginx/Apache؛ سكريبتات النشر غالباً تضيف مستخدم deploy هنا للكتابة في جذور الويب
Linux user, group, and file permission model alice (UID 1002) primary GID 1002 deploy (UID 1001) primary GID 1001 www-data (UID 33) system account docker (GID 999) alice, deploy www-data (GID 33) deploy, www-data /var/run/docker.sock owner: root group: docker perms: srw-rw---- /var/www/html/ owner: deploy group: www-data perms: rwxrwsr-x How a kernel access check works: 1. Is process UID == file owner UID? Use owner bits. 2. Else: is any process GID == file GID? Use group bits. 3. Else: use other bits. 4. UID 0 bypasses all three steps.
كيف يحل Linux الوصول: هوية العملية (UID + GIDs) تُفحص مقابل بتات صلاحية المالك والمجموعة والآخرين بالترتيب.

إنشاء المستخدمين وإدارتهم

على خوادم الإنتاج ستنشئ نوعين من الحسابات: حسابات المشغّلين البشريين وحسابات الخدمات. الأوامر تختلف قليلاً بينهما.

# ── حساب مشغّل بشري ────────────────────────────────────────────────────────── # useradd ينشئ الحساب؛ -m ينشئ /home/alice؛ -s يحدد الـshell sudo useradd -m -s /bin/bash -c "Alice Smith, SRE" alice # تعيين كلمة مرور (يطلب إدخالها تفاعلياً) sudo passwd alice # أو تعيين كلمة مرور منتهية لإجبار التغيير عند أول دخول (أكثر أماناً) sudo chage -d 0 alice # ── حساب خدمة / daemon ────────────────────────────────────────────────────── # --system: UID في نطاق النظام (1-999)؛ بلا مجلد رئيسي افتراضياً؛ shell nologin sudo useradd --system --no-create-home --shell /usr/sbin/nologin prometheus # التحقق id prometheus # uid=997(prometheus) gid=997(prometheus) groups=997(prometheus) # ── تعديل حساب موجود ───────────────────────────────────────────────────────── sudo usermod -c "Alice Smith, Staff SRE" alice # تحديث التعليق sudo usermod -s /bin/zsh alice # تغيير الـshell sudo usermod -L alice # قفل الحساب (تعطيل الدخول) sudo usermod -U alice # إلغاء قفل الحساب # ── حذف حساب ───────────────────────────────────────────────────────────────── sudo userdel alice # حذف الحساب، ترك المجلد الرئيسي sudo userdel -r alice # حذف الحساب والمجلد الرئيسي معاً

حساب Root ونموذج sudo

UID 0 (root) هو المستخدم الخارق. النواة تمنحه وصولاً غير مشروط لكل ملف وكل عملية وكل جهاز. تسجيل الدخول المباشر كـroot معطّل تقريباً على جميع خوادم الإنتاج — كلمة مرور root مجهولة، وخيار SSH PermitRootLogin مضبوط على no. بدلاً من ذلك يُتحكّم بالوصول عبر sudo.

su مقابل sudo:

  • su - root — يفتح shell بصلاحية root. يتطلب معرفة كلمة مرور root. لا يترك سجلاً تدقيقياً لكل أمر على حدة. مثبَّط بشدة في الإنتاج الحديث.
  • sudo command — يرفع صلاحيات أمر واحد. يتطلب كلمة مرورك الخاصة. كل استدعاء مسجّل في /var/log/auth.log (أو journald) مع المستخدم المستدعي والأمر ومسار العمل. هذا هو النموذج الذي تستخدمه جميع مزودات السحابة الكبرى.
خطأ إنتاجي شائع: لا تضف حساب خدمة أبداً إلى مجموعة sudo. منفذ CI، أو مستخدم النشر، أو عملية تطبيق يجب أن تُحقق عملها عبر صلاحيات الملفات وعضوية المجموعات، لا عبر الصلاحيات المرتفعة. إذا كان سكريبت النشر يحتاج لإعادة تشغيل nginx، أعطِه إدخالاً محدداً في sudoers لذلك الأمر الواحد فقط — لا sudo غير مقيّد. المهاجم الذي يخترق تلك العملية يجب أن يجد نطاق تأثير ضيّقاً.

إعداد sudo عبر /etc/sudoers

سياسة sudo موجودة في /etc/sudoers والمجلد /etc/sudoers.d/. دائماً حرّر بـvisudo — يتحقق من الصياغة قبل الحفظ، مما يمنع ملفاً مشوّهاً من إقفالك خارج النظام.

# لا تحرر /etc/sudoers مباشرة أبداً — استخدم visudo دائماً sudo visudo # صياغة /etc/sudoers: # من أين=(كمن) ماذا # sudo الكامل لمجموعة sudo (الإعداد الافتراضي لـUbuntu) %sudo ALL=(ALL:ALL) ALL # السماح لمستخدم deploy بإعادة تشغيل nginx وإعادة تحميله — لا شيء آخر deploy ALL=(root) NOPASSWD: /bin/systemctl restart nginx, /bin/systemctl reload nginx # السماح لـalice بتشغيل أي أمر لكن يجب إدخال كلمة المرور alice ALL=(ALL) ALL # الأفضل استخدام ملفات منفصلة لتجنب تحرير sudoers الرئيسي # إنشاء /etc/sudoers.d/deploy (chmod 440، مملوك لـroot:root) sudo tee /etc/sudoers.d/deploy <<'EOF' deploy ALL=(root) NOPASSWD: /bin/systemctl restart nginx, /bin/systemctl reload nginx EOF sudo chmod 440 /etc/sudoers.d/deploy # التدقيق: عرض ما يسمح به sudo لمستخدم معين sudo -l -U deploy # Matching Defaults entries for deploy on server1: # env_reset, mail_badpass # User deploy may run the following commands on server1: # (root) NOPASSWD: /bin/systemctl restart nginx # (root) NOPASSWD: /bin/systemctl reload nginx

سجل تدقيق sudo

كل استدعاء لـsudo مسجّل. على توزيعات systemd المصدر الموثوق هو journal؛ الملف التقليدي هو /var/log/auth.log (Debian/Ubuntu) أو /var/log/secure (RHEL). على نطاق الشركات الكبرى هذه السجلات تُحوَّل إلى نظام SIEM (Splunk أو Elastic أو Chronicle) وتُنبَّه على الحالات الشاذة — أوامر root غير متوقعة خارج أوقات العمل، أوامر من حساب خدمة، أو محاولات sudo فاشلة (رش كلمات المرور).

# عرض نشاط sudo الأخير من journald journalctl _COMM=sudo --since "24 hours ago" --no-pager # إدخال ناجح نموذجي: # Jun 10 14:32:11 prod-01 sudo[12345]: alice : TTY=pts/0 ; PWD=/home/alice ; # USER=root ; COMMAND=/bin/systemctl restart nginx # إدخال فاشل نموذجي (كلمة مرور خاطئة أو ليس في sudoers): # Jun 10 14:33:07 prod-01 sudo[12346]: bob : user NOT in sudoers ; # TTY=pts/1 ; PWD=/home/bob ; USER=root ; COMMAND=/bin/bash # من auth.log grep sudo /var/log/auth.log | tail -20
ممارسة متقدمة — sudo بلا كلمة مرور للأتمتة: خطوط أنابيب CI/CD وكتب تشغيل Ansible تحتاج لتشغيل أوامر مميزة دون إشراف بشري. النهج الصحيح هو حساب خدمة مخصص بحقوق sudo NOPASSWD محدودة بـالأوامر التي يحتاجها تحديداً. لا تستخدم NOPASSWD: ALL أبداً — ذلك مكافئ لتسليم وصول root بلا قيود. ادمجه مع مصادقة SSH بمفاتيح فقط وبلا shell تفاعلي (/usr/sbin/nologin) للحصول على حساب أتمتة بأضيق صلاحيات ممكنة.

التبديل بين المستخدمين والعمل بهوية أخرى

فهم الفرق بين su وsudo -i وsudo -u مهم عند تشخيص مشاكل الصلاحيات في الإنتاج:

  • sudo -i — يفتح shell دخول root (يحمّل بيئة root). استخدمه بتقتير؛ الأفضل sudo لكل أمر على حدة.
  • sudo -u deploy command — تشغيل أمر واحد بهوية مستخدم deploy. ضروري لاختبار "ما الذي يستطيع حساب الخدمة هذا فعله فعلاً؟"
  • sudo -s — يفتح shell root مع الحفاظ على بيئتك الحالية. مفيد لتشخيص مشاكل متغيرات البيئة.
  • su - deploy — التبديل إلى مستخدم deploy بدخول كامل. يتطلب معرفة كلمة مرور deploy أو أن تكون root. يُستخدم أقل الآن بوجود sudo -u.

في الدرس 6 ستتعرف على كيفية تشابك هذه الهويات مع بتات الصلاحية على الملفات — سلاسل rwxr-xr-x التي رأيتها في ناتج ls -l ستكتسب معنى ميكانيكياً كاملاً بمجرد فهم نموذج المستخدمين الذي بنيته هنا.