Product SiteDocumentation Site

14.4. مقدمة إلى AppArmor

14.4.1. المبادئ

AppArmor هو نظام تحكم إلزامي بالوصول Mandatory Access Control ‏(MAC) مبني على واجهة LSM‏ (Linux Security Modules) في لينكس. عملياً، تستشير النواة AppArmor قبل كل استدعاء للنظام حتى تعرف إذا كانت العملية المستدعية مخولة لتنفيذ الإجراء المطلوب. يعتمد AppArmor على هذه الآلية لتقييد التطبيقات بمجموعة محددة من الموارد.
يُطبِّق AppArmor مجموعة قواعد (تدعى ”البروفايل“) على كل برنامج. يختلف البروفايل الذي تطبقه النواة على كل برنامج باختلاف مسار تثبيته؛ ولا تعتمد القواعد على المستخدم الذي يستدعي البرنامج، بخلاف SELinux (الذي ناقشناه في قسم 14.5, “مقدمة إلى SELinux”). يخضع المستخدمون كلهم لنفس القواعد عند تنفيذ نفس البرنامج (لكن صلاحيات المستخدمين التقليدية تطبق عليهم طبعاً وهذا قد يؤدي لاختلاف النتائج!).
تُخزَّن بروفايلات AppArmor في /etc/apparmor.d/ وهي تحوي قائمة من قواعد التحكم بالوصول لكل الموارد التي يمكن أن يستخدمها أي برنامج. يترجم apparmor_parser هذه البروفايلات ويحملها إلى النواة. يمكن تحميل كل بروفايل إما في وضع الإلزام أو وضع الشكوى. يفرض الوضع الأول اتباع السياسة ويبلغ عن محاولات اختراقها، أما الوضع الثاني فلا يفرض السياسة بل يكتفي بتسجيل نداءات النظام التي تخالف السياسة والتي كان الوضع الأول سيمنعها.

14.4.2. تفعيل AppArmor وإدارة بروفايلاته

دعم AppArmor مدمج في النوى القياسية التي توفرها دبيان. لا يحتاج تفعيل AppArmor إلا لتثبيت بضعة حزم وإضافة بعض المتغيرات إلى سطر إقلاع النواة:
# apt install apparmor apparmor-profiles apparmor-utils
[...]
# perl -pi -e 's,GRUB_CMDLINE_LINUX="(.*)"$,GRUB_CMDLINE_LINUX="$1 apparmor=1 security=apparmor",' /etc/default/grub
# update-grub
وبعد إعادة الإقلاع سيعمل AppArmor ويمكن التحقق من ذلك فوراً عبر aa-status:
# aa-status
apparmor module is loaded.
44 profiles are loaded.
9 profiles are in enforce mode.
   /usr/bin/lxc-start
   /usr/lib/chromium-browser/chromium-browser//browser_java
[...]
35 profiles are in complain mode.
   /sbin/klogd
[...]
3 processes have profiles defined.
1 processes are in enforce mode.
   /usr/sbin/libvirtd (1295) 
2 processes are in complain mode.
   /usr/sbin/avahi-daemon (941) 
   /usr/sbin/avahi-daemon (1000) 
0 processes are unconfined but have a profile defined.
يمكن تبديل حالة كل بروفايل بين وضع الإلزام ووضع الشكوى عبر استدعاء aa-enforce وaa-complain مع إعطاء مسار الملف التنفيذي أو مسار ملف السياسة كمتغير. كما يمكن تعطيل البروفايل تماماً عبر aa-disable أو وضعه في حالة الاختبار (لتسجيل نداءات النظام المسموحة أيضاً) عبر aa-audit.
# aa-enforce /usr/sbin/avahi-daemon
Setting /usr/sbin/avahi-daemon to enforce mode.
# aa-complain /etc/apparmor.d/usr.bin.lxc-start
Setting /etc/apparmor.d/usr.bin.lxc-start to complain mode.

14.4.3.  إنشاء بروفايل جديد

رغم أن إنشاء بروفايلات AppArmor سهل، إلا أن معظم البرامج ليس لها بروفايل. سنشرح في هذا القسم طريقة إنشاء بروفايل جديد من الصفر عبر استخدام البرنامج المستهدف وترك AppArmor يراقب نداءات النظام التي يجريها والموارد التي يستخدمها.
أهم البرامج التي يجب تقييدها هي البرامج التي تواجه الشبكة لأنها أكثر ما يستهدفه المهاجمون عن بعد. لهذا السبب يوفر AppArmor الأمر المساعد aa-unconfined الذي يسرد البرامج التي توفر مقابس شبكية مفتوحة دون أن ترتبط مع أي بروفايل. ومع استخدام الخيار --paranoid سيذكر لك كل العمليات التي تملك اتصالاً شبكياً واحداً نشطاً أو أكثر.
# aa-unconfined
801 /sbin/dhclient not confined
890 /sbin/rpcbind not confined
899 /sbin/rpc.statd not confined
929 /usr/sbin/sshd not confined
941 /usr/sbin/avahi-daemon confined by '/usr/sbin/avahi-daemon (complain)'
988 /usr/sbin/minissdpd not confined
1276 /usr/sbin/exim4 not confined
1485 /usr/lib/erlang/erts-6.2/bin/epmd not confined
1751 /usr/lib/erlang/erts-6.2/bin/beam.smp not confined
19592 /usr/lib/dleyna-renderer/dleyna-renderer-service not confined
سنحاول إذاً في المثال التالي إنشاء بروفايل للبرنامج /sbin/dhclient. سوف نستخدم aa-genprof dhclient. سوف يدعوك لاستخدام التطبيق في نافذة أخرى وعندما تنتهي عد إلى aa-genprof لفحص أحداث AppArmor في سجلات النظام وتحويل هذه السجلات إلى قواعد تحكم بالوصول. سوف يقترح عليك قاعدة وصول واحدة أو أكثر مقابل كل حدث مسجل، ويمكنك الموافقة على المقترحات أو تعديلها بعدة طرق:
# aa-genprof dhclient
Writing updated profile for /sbin/dhclient.
Setting /sbin/dhclient to complain mode.

Before you begin, you may wish to check if a
profile already exists for the application you
wish to confine. See the following wiki page for
more information:
http://wiki.apparmor.net/index.php/Profiles

Please start the application to be profiled in
another window and exercise its functionality now.

Once completed, select the "Scan" option below in 
order to scan the system logs for AppArmor events. 

For each AppArmor event, you will be given the 
opportunity to choose whether the access should be 
allowed or denied.

Profiling: /sbin/dhclient

[(S)can system log for AppArmor events] / (F)inish
Reading log entries from /var/log/audit/audit.log.

Profile:  /sbin/dhclient 1
Execute:  /usr/lib/NetworkManager/nm-dhcp-helper
Severity: unknown

(I)nherit / (C)hild / (P)rofile / (N)amed / (U)nconfined / (X) ix On / (D)eny / Abo(r)t / (F)inish
P
Should AppArmor sanitise the environment when
switching profiles?

Sanitising environment is more secure,
but some applications depend on the presence
of LD_PRELOAD or LD_LIBRARY_PATH.

(Y)es / [(N)o]
Y
Writing updated profile for /usr/lib/NetworkManager/nm-dhcp-helper.
Complain-mode changes:
WARN: unknown capability: CAP_net_raw

Profile:    /sbin/dhclient 2
Capability: net_raw
Severity:   unknown

[(A)llow] / (D)eny / (I)gnore / Audi(t) / Abo(r)t / (F)inish
A
Adding capability net_raw to profile.

Profile:  /sbin/dhclient 3
Path:     /etc/nsswitch.conf
Mode:     r
Severity: unknown

  1 - #include <abstractions/apache2-common> 
  2 - #include <abstractions/libvirt-qemu> 
  3 - #include <abstractions/nameservice> 
  4 - #include <abstractions/totem> 
 [5 - /etc/nsswitch.conf]
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
3

Profile:  /sbin/dhclient
Path:     /etc/nsswitch.conf
Mode:     r
Severity: unknown

  1 - #include <abstractions/apache2-common> 
  2 - #include <abstractions/libvirt-qemu> 
 [3 - #include <abstractions/nameservice>]
  4 - #include <abstractions/totem> 
  5 - /etc/nsswitch.conf 
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
A
Adding #include <abstractions/nameservice> to profile.

Profile:  /sbin/dhclient
Path:     /proc/7252/net/dev
Mode:     r
Severity: 6

  1 - /proc/7252/net/dev 
 [2 - /proc/*/net/dev]
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
A
Adding /proc/*/net/dev r to profile

[...]
Profile:  /sbin/dhclient 4
Path:     /run/dhclient-eth0.pid
Mode:     w
Severity: unknown

 [1 - /run/dhclient-eth0.pid]
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
N

Enter new path: /run/dhclient*.pid

Profile:  /sbin/dhclient
Path:     /run/dhclient-eth0.pid
Mode:     w
Severity: unknown

  1 - /run/dhclient-eth0.pid 
 [2 - /run/dhclient*.pid]
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
A
Adding /run/dhclient*.pid w to profile

[...]
Profile:  /usr/lib/NetworkManager/nm-dhcp-helper 5
Path:     /proc/filesystems
Mode:     r
Severity: 6

 [1 - /proc/filesystems]
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
A
Adding /proc/filesystems r to profile

= Changed Local Profiles =

The following local profiles were changed. Would you like to save them?

 [1 - /sbin/dhclient]
  2 - /usr/lib/NetworkManager/nm-dhcp-helper 
(S)ave Changes / Save Selec(t)ed Profile / [(V)iew Changes] / View Changes b/w (C)lean profiles / Abo(r)t
S
Writing updated profile for /sbin/dhclient.
Writing updated profile for /usr/lib/NetworkManager/nm-dhcp-helper.

Profiling: /sbin/dhclient

[(S)can system log for AppArmor events] / (F)inish
F
Setting /sbin/dhclient to enforce mode.
Setting /usr/lib/NetworkManager/nm-dhcp-helper to enforce mode.

Reloaded AppArmor profiles in enforce mode.

Please consider contributing your new profile!
See the following wiki page for more information:
http://wiki.apparmor.net/index.php/Profiles

Finished generating profile for /sbin/dhclient.
لاحظ أن البرنامج لا يعيد عرض محارف التحكم التي تطبعها ولكنني ضمنتها في المقطع السابق لتوضيح الشرح.

1

أول حدث مكتشف هو تنفيذ برنامج آخر. في هذه الحالة، لديك عدة اختيارات: يمكنك تشغيل البرنامج باستخدام بروفايل العملية الأم (خيار الوراثة ”Inherit“)، أو يمكنك تنفيذه باستخدام بروفايل خاص (عبر خياري ”Profile“ و”Named“ اللذان يختلفان عن بعضهما بإمكانية استخدام اسم بروفايل عشوائي فقط)، أو يمكنك تشغيله باستخدام بروفايل فرعي من العملية الأم (خيار ”Child“)، أو يمكنك تشغيله دون أي بروفايل (خيار ”Unconfined“) أو يمكنك عدم السماح بتشغيله نهائياً (خيار ”Deny“).
لاحظ أنك إذا اخترت تشغيله باستخدام بروفايل مخصص غير موجود بعد، فسوف تنشئ الأداة البروفايل المفقود كما ستقترح قواعد وصول لذلك البروفايل في الاستدعاء نفسه.

2

على مستوى النواة، قُسِّمت صلاحيات المستخدم الجذر إلى ”capabilities“ أو قدرات. إذا كانت إحدى نداءات النظام تحتاج لقدرة معينة، يتحقق AppArmor من أن البروفايل يسمح للبرنامج باستخدام هذه المقدرة.

3

هنا يطلب البرنامج صلاحية القراءة للملف /etc/nsswitch.conf. اكتشف aa-genprof أن هذه الصلاحية قد منحت في عدة ”مستخلصات abstractions“ ويعرضها كخيارات بديلة. توفر المستخلصات مجموعات من قواعد الوصول القابلة لإعادة الاستخدام التي تجمع عدة موارد تستخدم مع بعضها عادة. في هذه الحالة، الوصول لهذا الملف يكون عبر دوال nameservice من مكتبة C وقد طبعنا ”3“ لتحديد الخيار ”‎#include <abstractions/nameservice>‎“ وبعدها ”A“ للسماح.

4

يريد البرنامج إنشاء الملف /run/dhclient-eth0.pid. إذا سمحنا بإنشاء هذا الملف بعينه فقط فلن يعمل البرنامج عندما يستخدمه المستخدم على واجهة شبكية مختلفة. لذلك اخترنا ”New“ لاستبدال اسم الملف باسم أشمل ”‎/run/dhclient*.pid“ قبل تسجيل القاعدة باستخدام ”Allow“.

5

لاحظ أن طلب الوصول هذا ليس حزءاً من بروفايل dhclient وإنما من البروفايل الجديد الذي أنشأناه عندما سمحنا للبرنامج /usr/lib/NetworkManager/nm-dhcp-helper بالعمل ببروفايل خاص.
بعد المرور على كل الأحداث المسجلة، يعرض عليك البرنامج حفظ البروفايلات التي أنشأتها أثناء العملية. في هذه الحالة، لدينا بروفايلين وقد حفظناهما معاً باستخدام ”Save“ (لكن يمكنك حفظهما بشكل إفرادي أيضاً) قبل الخروج من البرنامج باستخدام ”Finish“.
في الواقع، aa-genprof ما هو إلا غلاف ذكي للأمر aa-logprof: فهو ينشئ بروفايلاً فارغاً، ويحمله في وضع الشكوى ثم يستدعي aa-logprof وهي عبارة عن أداة تحدث البروفايل اعتماداً على انتهاكات القواعد المسجلة. ويمكنك إعادة استدعاء تلك الأداة لاحقاً لتحسين البروفايل الذي أنشأته الآن.
إذا أردت أن يكون البروفايل الذي أنشأته كاملاً، عليك استخدام البرنامج بكافة الطرق التي يشرع استخدامها. في حالة dhclient، هذا يعني تشغيله عبر مدير الشبكة (Network Manager)، وعبر ifupdown، وتشغيله يدوياً، الخ. في النهاية، قد تصل إلى ملف /etc/apparmor.d/sbin.dhclient مشابه لهذا:
# Last Modified: Tue Sep  8 21:40:02 2015
#include <tunables/global>

/sbin/dhclient {
  #include <abstractions/base>
  #include <abstractions/nameservice>

  capability net_bind_service,
  capability net_raw,

  /bin/dash r,
  /etc/dhcp/* r,
  /etc/dhcp/dhclient-enter-hooks.d/* r,
  /etc/dhcp/dhclient-exit-hooks.d/* r,
  /etc/resolv.conf.* w,
  /etc/samba/dhcp.conf.* w,
  /proc/*/net/dev r,
  /proc/filesystems r,
  /run/dhclient*.pid w,
  /sbin/dhclient mr,
  /sbin/dhclient-script rCx,
  /usr/lib/NetworkManager/nm-dhcp-helper Px,
  /var/lib/NetworkManager/* r,
  /var/lib/NetworkManager/*.lease rw,
  /var/lib/dhcp/*.leases rw,

  profile /sbin/dhclient-script flags=(complain) {
    #include <abstractions/base>
    #include <abstractions/bash>

    /bin/dash rix,
    /etc/dhcp/dhclient-enter-hooks.d/* r,
    /etc/dhcp/dhclient-exit-hooks.d/* r,
    /sbin/dhclient-script r,

  }
}