| DBUS-DAEMON(1) | دستورهای کاربر | DBUS-DAEMON(1) |
نام (NAME)
dbus-daemon - دیمن گذرگاه پیام D-Bus
خلاصه دستور (SYNOPSIS)
dbus-daemon
dbus-daemon [--version] [--session] [--system] [--config-file=FILE] [--print-address [=DESCRIPTOR]] [--print-pid [=DESCRIPTOR]] [--fork] [--nosyslog] [--syslog] [--syslog-only] [--ready-event-handle=value]
توضیحات (DESCRIPTION)
برنامه dbus-daemon دیمن گذرگاه پیام D-Bus است. برای اطلاعات بیشتر درباره تصویر کلی به نشانی https://www.freedesktop.org/wiki/Software/dbus مراجعه کنید. سامانه D-Bus در درجه نخست کتابخانهای است که ارتباط یکبهیک میان هر دو برنامهای را فراهم میکند؛ dbus-daemon برنامهای است که از این کتابخانه برای پیادهسازی یک دیمن گذرگاه پیام استفاده میکند. چندین برنامه میتوانند به این دیمن گذرگاه پیام متصل شده و با یکدیگر پیام ردوبدل کنند.
دو نمونه استاندارد از گذرگاه پیام وجود دارد: گذرگاه پیام سراسری سیستم (که در بسیاری از سیستمها به عنوان سرویس راهاندازی "messagebus" نصب میشود) و گذرگاه پیام نشست ورود به ازای هر کاربر (که با هر بار ورود کاربر راهاندازی میشود). dbus-daemon برای هر دوی این نمونهها به کار میرود، اما با پروندههای پیکربندی متفاوت.
گزینه --session معادل "--config-file=/usr/share/dbus-1/session.conf" و گزینه --system معادل "--config-file=/usr/share/dbus-1/system.conf" است. با ایجاد پروندههای پیکربندی بیشتر و استفاده از گزینه --config-file، میتوان دیمنهای گذرگاه پیام دیگری را با کاربردهای ویژه ایجاد کرد.
دیمن سراسری سیستم معمولاً توسط یک اسکریپت راهاندازی (init script) که به طور معمول تنها "messagebus" نامیده میشود راهاندازی میگردد.
دیمن سراسری سیستم عمدتاً برای انتشار همگانی رویدادهای سیستم، مانند تغییرات در صف چاپگر یا اضافه و حذف شدن دستگاهها به کار میرود.
دیمن به ازای هر نشست برای ارتباطات بینفرایندی گوناگون میان برنامههای محیط میزکار استفاده میشود (با این وجود، به هیچ وجه به سامانه X یا واسط گرافیکی وابسته نیست).
سیگنال SIGHUP باعث میشود دیمن D-Bus پرونده پیکربندی خود را به صورت «جزئی» مجدداً بارگذاری کرده و حافظههای نهان اطلاعات کاربر/گروه خود را پاکسازی نماید. اعمال برخی تغییرات در پیکربندی مستلزم قطع ارتباط تمامی برنامهها از گذرگاه است؛ بنابراین آن تغییرات تنها در صورت راهاندازی مجدد دیمن اعمال خواهند شد. تغییرات خطمشیها (policy) باید با دریافت سیگنال SIGHUP اعمال شوند.
گزینهها (OPTIONS)
گزینههای زیر پشتیبانی میشوند:
--config-file=FILE
--fork
--nofork
--print-address[=DESCRIPTOR]
--print-pid[=DESCRIPTOR]
--session
--system
--version
--introspect
--address[=ADDRESS]
--systemd-activation
--nopidfile
--syslog
--syslog-only
--nosyslog
--ready-event-handle=value
فایلهای پیکربندی (CONFIGURATION FILE)
هر دیمن گذرگاه پیام دارای یک پرونده پیکربندی است که آن را برای یک کاربرد خاص سفارشیسازی میکند. برای نمونه، یک پرونده پیکربندی ممکن است گذرگاه پیام را به عنوان یک گذرگاه سراسری سیستم پیکربندی کند، در حالی که پرونده دیگری آن را به عنوان یک گذرگاه به ازای هر نشست ورود کاربر تنظیم نماید.
پرونده پیکربندی همچنین محدودیتهای منابع، پارامترهای امنیتی و موارد دیگر را تعیین میکند.
پرونده پیکربندی بخشی از هیچ مشخصات تعاملپذیری استانداردی نیست و سازگاری رو به عقب آن تضمین نمیشود؛ این سند یک راهنما و مستند است، نه یک مشخصات فنی الزامآور.
تنظیمات استاندارد گذرگاههای پیام سراسری سیستم و به ازای هر نشست در پروندههای "/usr/share/dbus-1/system.conf" و "/usr/share/dbus-1/session.conf" پیکربندی شدهاند. این پروندهها معمولاً با تگ <include> یک پرونده system-local.conf یا session-local.conf را در مسیر /etc/dbus-1 فراخوانی میکنند؛ شما میتوانید تنظیمات بازنویسی محلی خود را در آن پروندهها قرار دهید تا از دستکاری پروندههای پیکربندی اصلی جلوگیری شود.
گذرگاه پیام استاندارد سیستم معمولاً پروندههای XML دیگری را از مسیر /usr/share/dbus-1/system.d میخواند. بستههای نرمافزاری شخص ثالث باید خطمشیهای پیشفرضی را که برای عملکرد صحیح آنها نیاز است درون این پوشه نصب کنند؛ این امکان از نگارش 1.10 سامانه dbus (منتشر شده در سال ۲۰۱۵) پشتیبانی شده است.
گذرگاه پیام استاندارد سیستم معمولاً پروندههای XML را از مسیر /etc/dbus-1/system.d نیز میخواند که باید توسط مدیران سیستم برای بازنویسی خطمشیهای پیشفرض استفاده شود.
بستههای نرمافزاری شخص ثالث در گذشته پروندههای XML را در مسیر /etc/dbus-1/system.d نصب میکردند، اما امروزه این شیوه منسوخ تلقی میشود: آن شاخه باید به عنوان مسیر اختصاصی مدیر سیستم در نظر گرفته شود.
پرونده پیکربندی یک سند XML است و باید دارای اعلان نوع سند (doctype declaration) زیر باشد:
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
عناصر زیر میتوانند در پرونده پیکربندی وجود داشته باشند:
عنصر ریشه (Root element).
نوع شناختهشده گذرگاه پیام. مقادیر شناختهشده فعلی "system" و "session" هستند؛ چنانچه مقادیر دیگری تنظیم شوند، یا باید به مشخصات فنی D-Bus افزوده شوند و یا دارای فضای نام اختصاصی باشند. آخرین عنصر <type> در پرونده ارجحیت دارد (مقادیر پیشین نادیده گرفته میشوند). این عنصر تنها متغیرهای محیطی ویژهای را که در کلاینتهای فعالشده تنظیم میشوند کنترل میکند. بخش عمده خطمشیای که یک گذرگاه نشست را از گذرگاه سیستم متمایز میسازد، توسط سایر عناصر موجود در پرونده پیکربندی مدیریت میشود.
اگر نوع شناختهشده گذرگاه پیام برابر "session" باشد، متغیر محیطی DBUS_STARTER_BUS_TYPE بر روی "session" و متغیر محیطی DBUS_SESSION_BUS_ADDRESS بر روی آدرس گذرگاه نشست تنظیم خواهد شد. به همین ترتیب، اگر نوع گذرگاه "system" باشد، متغیر محیطی DBUS_STARTER_BUS_TYPE بر روی "system" و متغیر محیطی DBUS_SYSTEM_BUS_ADDRESS بر روی آدرس گذرگاه سیستم تنظیم میگردد (که معمولاً به هر حال یک نشانی شناختهشده است).
مثال: <type>session</type>
فراخوانی یک پرونده در این نقطه به صورت <include>filename.conf</include>. اگر نام پرونده به صورت نسبی باشد، موقعیت آن نسبت به پرونده پیکربندی فراخواننده سنجیده میشود.
تگ <include> دارای یک ویژگی اختیاری به نام "ignore_missing=(yes|no)" است که در صورت تعیین نشدن، مقدار پیشفرض آن "no" میباشد. این ویژگی مشخص میکند که آیا غیبت پرونده فراخوانیشده یک خطای مرگبار تلقی شود یا خیر.
فراخوانی تمامی پروندههای موجود در یک پوشه به صورت <includedir>foo.d</includedir> در این نقطه. پروندههای موجود در پوشه با ترتیبی تعریفنشده خوانده میشوند. تنها پروندههایی که به پسوند ".conf" ختم شوند وارد میگردند.
این قابلیت با هدف امکان گسترش گذرگاه سیستم توسط بستههای نرمافزاری خاص در نظر گرفته شده است. برای مثال، اگر سرویس چاپ CUPS بخواهد اعلانهای تغییرات در صف چاپگر را ارسال کند، میتواند پروندهای را در /usr/share/dbus-1/system.d نصب نماید که به تمامی برنامهها اجازه دریافت این پیام و به کاربر دیمن چاپگر اجازه ارسال آن را بدهد.
حساب کاربریای که دیمن باید تحت آن اجرا شود، به صورت نام کاربری یا شناسه عددی کاربر (UID). اگر دیمن هنگام شروع به کار نتواند به این UID تغییر هویت دهد، با خطا خارج خواهد شد. در صورت عدم وجود این عنصر، دیمن UID خود را تغییر نداده و به آن توجهی نمیکند.
آخرین مدخل <user> در پرونده ارجحیت دارد و سایر مدخلها نادیده گرفته میشوند.
تغییر کاربر پس از اتمام مقداردهی اولیه گذرگاه انجام میشود. بنابراین سوکتها و موارد دیگر پیش از تغییر هویت کاربر ایجاد میشوند، اما هیچ دادهای پیش از تغییر کاربر از کلاینتها خوانده نخواهد شد. این بدان معناست که سوکتها و پروندههای PID را میتوان در مکانهایی ساخت که نوشتن در آنها نیازمند امتیازات ریشه (root) است.
در صورت وجود، دیمن گذرگاه به یک دیمن واقعی تبدیل میشود (فرآیند را fork کرده و در پسزمینه اجرا میشود و غیره). معمولاً ترجیح داده میشود این کار از طریق پرونده پیکربندی انجام شود تا گزینه خط فرمانی --fork.
در صورت وجود، دیمن گذرگاه umask اولیه خود را در حین fork کردن حفظ میکند. این گزینه میتواند برای جلوگیری از اثرگذاری بر رفتار فرایندهای فرزند مفید باشد.
در صورت وجود، دیمن گذرگاه لاگهای خود را در syslog ثبت خواهد کرد. گزینههای خط فرمانی --syslog، --syslog-only و --nosyslog بر این تنظیم ارجحیت دارند.
در صورت وجود، دیمن گذرگاه شناسه فرایند (PID) خود را در پرونده مشخصشده مینویسد. گزینه خط فرمانی --nopidfile بر این تنظیم ارجحیت دارد.
در صورت وجود، به اتصالاتی که با سازوکار ANONYMOUS احراز هویت شدهاند اجازه اتصال داده میشود. این گزینه هیچ تاثیر عملی ندارد مگر آنکه سازوکار ANONYMOUS از طریق عنصر <auth> (که در ادامه توضیح داده شده) نیز فعال شده باشد.
استفاده از این دستورالعمل در پیکربندی گذرگاههای شناختهشده سیستم یا نشست، آنها را ناامن خواهد کرد و هرگز نباید انجام شود. به همین ترتیب، در گذرگاههای سفارشی نیز استفاده از این دستورالعمل معمولاً گذرگاه سفارشی را ناامن میسازد، مگر آنکه پیکربندی آن مشخصاً برای جلوگیری از آسیبرسانی کاربران ناشناس یا ارتقای دسترسی طراحی شده باشد.
افزودن آدرسی که گذرگاه باید روی آن گوش فرا دهد. این آدرس در قالب استاندارد D-Bus است که شامل نام لایه انتقال (transport) به همراه پارامترها و گزینههای ممکن میباشد.
در پلتفرمهای غیر ویندوزی، لایههای انتقال مبتنی بر یونیکس (unix، systemd، launchd) هم برای گذرگاه سیستم و هم برای گذرگاه نشست حالت پیشفرض بوده و به شدت توصیه میشوند.
در ویندوز، انتقالهای مبتنی بر یونیکس در دسترس نیستند، بنابراین باید از انتقالهای مبتنی بر TCP استفاده شود. همانند X11 از راه دور، انتقالهای tcp و nonce-tcp فاقد حفاظت از یکپارچگی یا محرمانگی دادهها هستند؛ بنابراین معمولاً تنها باید روی رابط لوپبک محلی استفاده شوند، برای مثال با آدرسی مانند tcp:host=127.0.0.1 یا nonce-tcp:host=localhost. به ویژه، پیکربندی گذرگاه شناختهشده سیستم یا گذرگاه نشست برای گوش دادن روی یک آدرس TCP غیر لوپبک ناامن است.
توسعهدهندگان گاهی وسوسه میشوند که از TCP راه دور به عنوان ابزاری برای اشکالزدایی استفاده کنند. با این حال، اگر این قابلیت در محصولات نهایی فعال بماند، نتیجه به شکل خطرناکی ناامن خواهد بود. توسعهدهندگان به جای استفاده از TCP راه دور، باید اتصالات را از طریق Secure Shell یا پروتکلی مشابه رله کنند.
اتصالات TCP از راه دور در گذشته گاهی برای به اشتراکگذاری یک گذرگاه نشست واحد میان نشستهای ورود همان کاربر روی ماشینهای مختلف درون یک شبکه محلی مطمئن (در ترکیب با X11 بدون رمزنگاری، پوشه خانگی اشتراکی روی NFS و احراز هویت NIS/YP) استفاده میشد. این کار در برابر مهاجم روی همان شبکه محلی ناامن است و باید اکیداً منسوخ در نظر گرفته شود؛ به طور مشخصتر، این کار دقیقاً به همان روشها و به همان دلایل ناامن بودن X11 بدون رمزنگاری و سامانههای NFSv2/NFSv3 ناامن است. نگهدارندگان D-Bus توصیه میکنند برای هر جفت (کاربر، ماشین) از یک گذرگاه نشست جداگانه استفاده شود که تنها از داخل همان ماشین در دسترس باشد.
مثال: <listen>unix:path=/tmp/foo</listen>
مثال: <listen>tcp:host=localhost,port=1234</listen>
اگر چندین عنصر <listen> وجود داشته باشد، گذرگاه روی چندین آدرس به گوش میایستد. گذرگاه نشانی خود را به ترتیبی در اختیار سرویسهای آغازشده یا سایر بخشها قرار میدهد که آخرین نشانی ارائهشده در <listen> در ابتدای فهرست باشد. بدین معنا که برنامهها ابتدا تلاش میکنند به آخرین نشانی <listen> متصل شوند.
سوکتهای tcp میتوانند آدرسهای IPv4، IPv6 یا نام میزبان (hostname) را بپذیرند. اگر یک نام میزبان به چندین آدرس ترجمه شود، سرور به تمامی آنها متصل (bind) میشود. با گزینههای family=ipv4 یا family=ipv6 میتوان سرور را مقید به زیرمجموعهای از آدرسها کرد.
مثال: <listen>tcp:host=localhost,port=0,family=ipv4</listen>
یک حالت خاص، استفاده از شماره پورت صفر (یا حذف شماره پورت) است که به معنای انتخاب یک پورت آزاد توسط سیستمعامل میباشد. پورت انتخابشده را میتوان با پارامتر خط فرمانی --print-address دریافت کرد و همچنین در موارد دیگری که سرور آدرس خود را گزارش میکند (مانند زمانی که متغیر DBUS_SESSION_BUS_ADDRESS مقداردهی شده است) در دسترس خواهد بود.
مثال: <listen>tcp:host=localhost,port=0</listen>
نشانیهای tcp/nonce-tcp همچنین از گزینه bind=hostname پشتیبانی میکنند که در نشانیهای قابل گوش فرادادن برای پیکربندی رابطی که سرور روی آن به گوش میایستد به کار میرود: نام میزبان یا نشانی IP یکی از رابطهای ماشین محلی (اغلب 127.0.0.1) است، یا نام DNS که به یکی از آن نشانیهای IP ترجمه میشود، یا '0.0.0.0' برای گوش فرا دادن روی تمامی رابطهای IPv4 به طور همزمان، یا '::' برای گوش دادن همزمان روی تمام رابطهای IPv4 و IPv6 (در صورت پشتیبانی سیستمعامل). در صورت عدم تعیین، مقدار پیشفرض همان مقدار "host" خواهد بود.
مثال: <listen>tcp:host=localhost,bind=0.0.0.0,port=0</listen>
فهرست سازوکارهای مجاز برای احراز هویت. اگر این عنصر وجود نداشته باشد، تمامی سازوکارهای شناختهشده مجاز خواهند بود. در صورت وجود چندین عنصر <auth>، تمامی سازوکارهای فهرستشده مجاز شمرده میشوند. ترتیبی که در آن سازوکارها فهرست شدهاند تاثیری ندارد.
در سیستمعاملهای غیر ویندوزی، اکیداً توصیه میشود که تنها سازوکار احراز هویت EXTERNAL مجاز شمرده شود. این گزینه پیشفرض گذرگاه شناختهشده سیستم و گذرگاه نشست است.
مثال: <auth>EXTERNAL</auth>
مثال: <auth>DBUS_COOKIE_SHA1</auth>
افزودن یک پوشه برای جستوجوی پروندههای .service، که به dbus-daemon میگویند چگونه برنامهای را برای ارائه یک نام گذرگاه شناختهشده خاص اجرا کند. برای جزئیات بیشتر درباره محتوای پروندههای .service به مشخصات فنی D-Bus مراجعه کنید.
اگر یک سرویس خاص در بیش از یک <servicedir> یافت شود، نخستین پوشه فهرستشده در پرونده پیکربندی اولویت خواهد داشت. اگر دو پرونده سرویس که یک نام گذرگاه شناختهشده یکسان را فراهم میکنند در همان پوشه یافت شوند، انتخاب میان آنها اختیاری و نامشخص است (این حالت تنها در صورتی رخ میدهد که حداقل یکی از پروندههای سرویس نام توصیهشده، یعنی نام گذرگاه به همراه ".service"، را نداشته باشد).
عنصر <standard_session_servicedirs/> مجموعهای از مسیرهای پیشفرض سرویسهای نشست را درخواست میکند. اثر آن مشابه تعیین مجموعهای از عناصر <servicedir/> برای هر یک از پوشههای داده به همان ترتیب دادهشده در اینجا است. این عمل دقیقاً معادل آن نیست، زیرا در حال حاضر هیچ روشی برای غیرفعال کردن پایش پوشه یا اجبار نامگذاری دقیق پرونده سرویس برای یک <servicedir/> وجود ندارد.
مشابه عناصر <servicedir/>، اگر یک سرویس خاص در بیش از یک پوشه سرویس پیدا شود، نخستین پوشه اولویت دارد. اگر دو پرونده سرویس با یک نام شناختهشده در یک پوشه قرار داشته باشند، انتخاب میان آنها اختیاری خواهد بود (این تنها زمانی رخ میدهد که حداقل یکی از آنها از نام استاندارد پیروی نکرده باشد).
در یونیکس، مسیرهای استاندارد سرویسهای نشست عبارتند از:
برخلاف سایر پوشههای استاندارد سرویسهای نشست، این پوشه نامگذاری سختگیرانهای را برای پروندههای سرویس اعمال میکند: نام پرونده باید دقیقاً برابر نام گذرگاه شناختهشده سرویس، همراه با پسوند ".service" باشد.
همچنین برخلاف سایر پوشههای استاندارد، این پوشه هرگز با inotify(7) یا رابطهای برنامهنویسی مشابه پایش نمیشود. از برنامههایی که در حین اجرای dbus-daemon پروندههای سرویس را در این پوشه میسازند انتظار میرود پس از انجام تغییرات، متد ReloadConfig() دیمن را فراخوانی کنند.
سند "XDG Base Directory Specification" را در صورت عدم تغییر نشانی میتوانید در http://freedesktop.org/wiki/Standards/basedir-spec بیابید، در غیر این صورت در موتور جستوجوی مورد علاقه خود جستوجو کنید.
در ویندوز، پوشههای استاندارد سرویس نشست عبارتند از:
گزینه <standard_session_servicedirs/> تنها برای دیمن گذرگاه نشست تعریفشده در /etc/dbus-1/session.conf معنا دارد. قرار دادن آن در هر پرونده پیکربندی دیگری احتمالاً بیمعنی خواهد بود.
عنصر <standard_system_servicedirs/> مسیرهای فعالسازی استاندارد سراسری سیستم را مشخص میکند که باید برای یافتن پروندههای سرویس جستوجو شوند. همانند سرویسهای نشست، نخستین پوشه فهرستشده بالاترین اولویت را دارد.
در یونیکس، پوشههای استاندارد سرویسهای سیستم عبارتند از:
در ویندوز هیچ گذرگاه سیستم استانداردی وجود ندارد، بنابراین هیچ پوشه استاندارد گذرگاه سیستمی نیز برای آن تعریف نشده است.
گزینه <standard_system_servicedirs/> تنها برای دیمن گذرگاه سیستم تعریفشده در /usr/share/dbus-1/system.conf کاربرد دارد. استفاده از آن در پروندههای دیگر معمولاً نادرست است.
دستورالعمل <servicehelper/> برنامه کمکی setuid را مشخص میکند که برای راهاندازی دیمنهای سیستم تحت یک کاربر جایگزین استفاده میشود. معمولاً این مقدار باید پرونده اجرایی dbus-daemon-launch-helper مستقر در libexec باشد.
گزینه <servicehelper/> تنها برای دیمن گذرگاه سیستم تعریفشده در /usr/share/dbus-1/system.conf کاربرد دارد.
تگ <limit> یک محدودیت بر منابع اعمال میکند. برای نمونه:
<limit name="max_message_size">64</limit> <limit name="max_completed_connections">512</limit>
ویژگی name الزامی است. نامهای محدودیتهای موجود عبارتند از:
"max_incoming_bytes" : حداکثر اندازه کل بایتهای پیامهای
ورودی از یک اتصال واحد
"max_incoming_unix_fds" : حداکثر تعداد توصیفکنندههای پرونده
(fds) یونیکس ورودی از یک اتصال
"max_outgoing_bytes" : حداکثر اندازه کل بایتهای پیامهای
در صف قرار گرفته برای یک اتصال
"max_outgoing_unix_fds" : حداکثر تعداد توصیفکنندههای پرونده
یونیکس در صف قرار گرفته برای یک اتصال
"max_message_size" : حداکثر اندازه یک پیام واحد به بایت
"max_message_unix_fds" : حداکثر توصیفکنندههای یونیکس یک پیام
"service_start_timeout" : مهلت زمانی (میلیثانیه) تا اتصال
یک سرویس آغازشده
"auth_timeout" : مهلت زمانی (میلیثانیه) دادهشده
به یک اتصال برای احراز هویت
"pending_fd_timeout" : مهلت زمانی (میلیثانیه) برای انتقال
fd به dbus-daemon قبل از قطع اتصال
"max_completed_connections" : حداکثر تعداد اتصالات احراز هویت شده
"max_incomplete_connections" : حداکثر تعداد اتصالات احراز هویت نشده
"max_connections_per_user" : حداکثر تعداد اتصالات کامل از طرف
یک کاربر (تنها در یونیکس اعمال میشود)
"max_pending_service_starts" : حداکثر تعداد سرویسهای در حال راهاندازی
به طور همزمان
"max_names_per_connection" : حداکثر تعداد نامهایی که یک اتصال
واحد میتواند مالک آنها باشد
"max_match_rules_per_connection": حداکثر تعداد قواعد تطبیق برای یک اتصال
"max_replies_per_connection" : حداکثر تعداد پاسخهای در انتظار برای متدها
به ازای یک اتصال (تماسهای در حال اجرا)
"reply_timeout" : مهلت زمانی (میلیثانیه) برای پایان
انتظار پاسخ یک متد
حداکثر اندازه صفهای ورودی/خروجی اجازه میدهد در صورتی که حتی یک بایت زیر حد مجاز باقی مانده باشد، یک پیام جدید در صف قرار گیرد. بنابراین شما در واقع میتوانید به اندازه max_message_size از حد بیشینه فراتر بروید.
حاصل تقسیم max_completed_connections بر max_connections_per_user نشاندهنده تعداد کاربرانی است که میتوانند با تبانی و مصرف تمامی اتصالات در گذرگاه سراسری سیستم، موجب ایجاد حمله منع سرویس (DoS) برای تمامی کاربران دیگر شوند.
محدودیتها معمولاً تنها در گذرگاه سراسری سیستم اهمیت دارند، نه گذرگاههای نشست کاربران.
عنصر <policy> یک خطمشی امنیتی را تعریف میکند تا بر روی مجموعه خاصی از اتصالات به گذرگاه اعمال شود. یک خطمشی از عناصر <allow> و <deny> تشکیل میشود. خطمشیها معمولاً همراه با گذرگاه سراسری سیستم به کار میروند؛ آنها مشابه یک دیواره آتش (firewall) عمل میکنند به این صورت که ترافیک مورد انتظار را مجاز ساخته و از ترافیک غیرمنتظره جلوگیری مینمایند.
در حال حاضر، گذرگاه سیستم دارای یک خطمشی «عدم پذیرش پیشفرض» (default-deny) برای ارسال فراخوانی متدها و مالکیت نامهای گذرگاه است، و دارای یک خطمشی «پذیرش پیشفرض» (default-allow) برای دریافت پیامها، ارسال سیگنالها، و ارسال یک پاسخ موفقیت یا خطای منفرد برای هر فراخوانی متدی است که پرچم NO_REPLY نداشته باشد. ارسال بیش از تعداد پاسخهای مورد انتظار مجاز نیست.
به طور کلی، بهتر است سرویسهای سیستم به صورت برنامههای کوچک و هدفمند نوشته شوند که در فرآیند اختصاصی خود اجرا شده و یک نام گذرگاه واحد را ارائه میدهند. سپس، تنها چیزی که نیاز است یک قاعده <allow> برای مجوز "own" است تا به فرآیند اجازه داده شود نام گذرگاه را تصاحب کند، و یک قاعده "send_destination" برای مجاز کردن ارسال ترافیک از برخی یا تمامی شناسههای کاربری (uidها) به سرویس شما.
عنصر <policy> یکی از چهار ویژگی زیر را میپذیرد:
context="(default|mandatory)" at_console="(true|false)" user="username or userid" group="group name or gid"
خطمشیها به صورت زیر بر روی یک اتصال اعمال میشوند:
- تمامی خطمشیهای context="default" اعمال میشوند - تمامی خطمشیهای group="گروه کاربر اتصال" با ترتیبی نامشخص اعمال میشوند - تمامی خطمشیهای user="کاربر احراز هویت شده اتصال" با ترتیبی نامشخص اعمال میشوند - تمامی خطمشیهای at_console="true" اعمال میشوند - تمامی خطمشیهای at_console="false" اعمال میشوند - تمامی خطمشیهای context="mandatory" اعمال میشوند
در صورت همپوشانی خطمشیها، خطمشیهایی که دیرتر اعمال میشوند بر خطمشیهای قبلی ارجحیت خواهند داشت. اگر چندین خطمشی با کاربر/گروه/زمینه (context) یکسان وجود داشته باشد، به همان ترتیبی که در پرونده پیکربندی آمدهاند اعمال میگردند.
<deny>
یک عنصر <deny> در زیر یک عنصر <policy> ظاهر شده و اقدام خاصی را ممنوع میکند. عنصر <allow> یک استثنا برای دستورات <deny> قبلی ایجاد کرده و دقیقاً مانند <deny> ولی با مفهوم معکوس عمل میکند.
ویژگیهای ممکن برای این عناصر عبارتند از:
send_interface="interface_name" | "*" send_member="method_or_signal_name" | "*" send_error="error_name" | "*" send_broadcast="true" | "false" send_destination="name" | "*" send_destination_prefix="name" send_type="method_call" | "method_return" | "signal" | "error" | "*" send_path="/path/name" | "*" receive_interface="interface_name" | "*" receive_member="method_or_signal_name" | "*" receive_error="error_name" | "*" receive_sender="name" | "*" receive_type="method_call" | "method_return" | "signal" | "error" | "*" receive_path="/path/name" | "*" send_requested_reply="true" | "false" receive_requested_reply="true" | "false" eavesdrop="true" | "false" own="name" | "*" own_prefix="name" user="username" | "*" group="groupname" | "*"
مثالها:
<deny send_destination="org.freedesktop.Service" send_interface="org.freedesktop.System" send_member="Reboot"/> <deny send_destination="org.freedesktop.System"/> <deny receive_sender="org.freedesktop.System"/> <deny user="john"/> <deny group="enemies"/>
ویژگیهای عنصر <deny> تعیین میکنند که آیا این ممانعت با یک اقدام مشخص «تطبیق» دارد یا خیر. اگر تطبیق داشته باشد، آن اقدام مسدود میشود (مگر اینکه قواعد بعدی در پرونده پیکربندی اجازه آن را صادر کنند).
قواعد دارای یک یا چند ویژگی از خانواده send_* به هنگام تلاش یک اتصال برای ارسال پیام، به ترتیب بررسی میشوند. آخرین قاعدهای که با پیام تطبیق یابد تعیین میکند آیا پیام مجاز به ارسال هست یا خیر. گذرگاه نشست به طور عادی اجازه ارسال هر پیامی را میدهد. گذرگاه شناختهشده سیستم معمولاً اجازه ارسال هر سیگنالی، فراخوانیهای متد انتخابشده به dbus-daemon، و دقیقاً یک پاسخ به هر متد ارسالشده پیشین (موفقیت یا خطا) را میدهد. هر یک از این موارد را میتوان با پیکربندی بازنویسی کرد؛ در گذرگاه سیستم، سرویسهایی که قرار است فراخوانی متدها را دریافت کنند باید پیکربندیهایی نصب کنند که اجازه این کار را بدهد، معمولاً از طریق قواعدی به شکل <policy context="default"><allow send_destination="..."/></policy>.
قواعد دارای یک یا چند ویژگی از خانواده receive_* یا با ویژگی eavesdrop و بدون ویژگیهای دیگر، به ازای هر دریافتکننده یک پیام بررسی میشوند (چنانچه پیام به صورت همگانی باشد یا یک اتصال در حال شنود پنهانی باشد، ممکن است بیش از یک دریافتکننده وجود داشته باشد). آخرین قاعدهای که با پیام تطبیق یابد تعیین میکند آیا پیام مجاز به دریافت هست یا خیر. گذرگاه نشست به طور معمول اجازه دریافت هر پیامی، از جمله شنود پنهانی را میدهد. گذرگاه سیستم معمولاً اجازه دریافت هر پیامی را که استراق سمع نشده باشد میدهد (هر پیام تکپخشی ارسالشده به مقصد، و هر پیام همگانی).
ویژگیهای eavesdrop، min_fds و max_fds تعدیلکنندههایی هستند که میتوانند بر قواعد send_* یا receive_* اعمال شوند و در ادامه مستند شدهاند.
قواعد send_destination و receive_sender به این معنا هستند که پیامها ممکن است به/از «مالک» (owner) نام دادهشده ارسال یا دریافت نشوند، نه اینکه نتوان آنها را «به آن نام» فرستاد. به این معنی که اگر اتصالی مالک سرویسهای A و B و C باشد، و ارسال به A مسدود شود، ارسال به B یا C نیز کار نخواهد کرد. به عنوان یک حالت خاص، send_destination="*" با هر پیامی تطبیق مییابد (چه مقصدی برای آن تعیین شده باشد و چه نشده باشد)، و به همین صورت receive_sender="*" نیز با هر پیامی تطبیق مییابد.
یک قاعده send_destination_prefix کل فضای نام را برای ارسال باز یا بسته میکند. بدین معنا که پیامها ممکن است به مالک هر نامی که پیشوند آن تطبیق داشته باشد (صرفنظر از اینکه مالک اصلی باشد یا مالک در صف) فرستاده شوند یا نشوند. به بیان دیگر، برای قاعده <allow send_destination_prefix="a.b"/> و وجود نامهای "a.b"، "a.b.c" و "a.b.c.d" روی گذرگاه، رفتار آن دقیقاً مانند آن است که سه قاعده مجزا تعریف شده باشند: <allow send_destination="a.b"/>، <allow send_destination="a.b.c"/> و <allow send_destination="a.b.c.d"/>. قواعد تطبیق نامها همانند own_prefix هستند (به زیر مراجعه کنید): پیشوند "a.b" با نامهای "a.b" یا "a.b.c" یا "a.b.c.d" تطبیق مییابد، اما با "a.bc" یا "a.c" تطبیق ندارد. ویژگی send_destination_prefix نمیتواند با ویژگی send_destination در یک قاعده ترکیب شود.
قواعد با send_broadcast="true" با پیامهای سیگنال بدون مقصد (انتشار همگانی) تطبیق دارند. قواعد با send_broadcast="false" معکوس آن هستند: آنها با هر مقصد تکپخشی (سیگنالهای تکپخشی همراه با تمام فراخوانیهای متد، پاسخها و خطاها) تطبیق مییابند اما با پیامهای بدون مقصد (پخش همگانی) تطبیق ندارند. این متفاوت از send_destination="*" است که با هر پیام ارسالی، فارغ از داشتن یا نداشتن مقصد، تطبیق دارد.
سایر ویژگیهای send_* و receive_* تطبیقهای متنی/مقداری صرف با فیلد مورد نظر در سرآیند پیام هستند، به جز اینکه برای ویژگیهایی که در آنها مجاز است، نویسه * با هر پیامی (خواه فیلد سرآیند مربوطه را داشته باشد یا خیر) تطبیق پیدا میکند. برای نمونه، send_interface="*" با هر پیام ارسالی تطبیق مییابد، حتی اگر سرآیند interface نداشته باشد. الگوهای پیچیدهتر مانند foo.bar.* مجاز نیستند.
«شنود پنهانی» (Eavesdropping) زمانی رخ میدهد که برنامهای پیامی را دریافت کند که صراحتاً به نامی خطاب شده که برنامه مالک آن نیست، یا پاسخی به چنین پیامی باشد. بنابراین شنود پنهانی تنها در مورد پیامهایی اعمال میشود که خطاب به سرویسها هستند و پاسخهای مربوط به آنها (یعنی شامل سیگنالها نمیشود).
برای عنصر <allow>، مقدار eavesdrop="true" نشان میدهد که قاعده حتی در هنگام شنود پنهانی نیز تطبیق دارد. مقدار پیشفرض eavesdrop="false" است و بدان معناست که قاعده تنها اجازه ارسال پیام به دریافتکننده مشخصشده آن را میدهد. برای <deny>، مقدار eavesdrop="true" مشخص میکند که قاعده تنها در زمان شنود پنهانی تطبیق مییابد. مقدار پیشفرض برای <deny> نیز eavesdrop="false" است، اما در اینجا بدین معناست که قاعده همواره، حتی در صورت عدم شنود پنهانی، اعمال میشود. ویژگی eavesdrop تنها میتواند با قواعد send و receive (با ویژگیهای send_* و receive_*) ترکیب شود.
ویژگی [send|receive]_requested_reply مشابه ویژگی eavesdrop کار میکند. این ویژگی کنترل میکند که آیا <deny> یا <allow> با پاسخی که مورد انتظار است (متناظر با پیام فراخوانی متد قبلی) تطبیق دارد یا خیر. این ویژگی تنها برای پیامهای پاسخ (خطاها و بازگشتهای متد) مفهوم دارد و برای سایر انواع پیام نادیده گرفته میشود.
برای عنصر <allow>، مقدار [send|receive]_requested_reply="true" حالت پیشفرض است و مشخص میکند که تنها پاسخهای درخواستشده توسط قاعده مجاز هستند. مقدار [send|receive]_requested_reply="false" به این معناست که قاعده هر پاسخی را مجاز میداند، حتی اگر غیرمنتظره باشد.
برای عنصر <deny>، مقدار [send|receive]_requested_reply="false" حالت پیشفرض است اما نشان میدهد قاعده تنها زمانی تطبیق مییابد که پاسخ درخواست نشده باشد. مقدار [send|receive]_requested_reply="true" بیانگر آن است که قاعده همواره، بدون در نظر گرفتن وضعیت پاسخهای در انتظار، اعمال میشود.
ویژگیهای min_fds و max_fds قواعد send_* یا receive_* را تعدیل میکنند. قاعدهای با ویژگی min_fds تنها زمانی با پیام تطبیق مییابد که حداقل آن تعداد توصیفکننده پرونده (FD) یونیکس پیوست شده باشد. برعکس، قاعدهای با ویژگی max_fds تنها با پیامهایی تطبیق دارد که حداکثر آن تعداد توصیفکننده پرونده پیوست شده باشد. در عمل، قواعد با این ویژگیها بیشتر به شکلهای زیر دیده میشوند: <allow send_destination="..." max_fds="0"/>، <deny send_destination="..." min_fds="1"/> یا <deny receive_sender="*" min_fds="1"/>.
قواعد دارای ویژگی user یا group در هنگام برقراری یک اتصال جدید به گذرگاه پیام بررسی میشوند و ادامه یافتن یا قطع اتصال را کنترل میکنند. هر یک از این ویژگیها نمیتوانند با هیچ ویژگی دیگری ترکیب شوند. به عنوان یک حالت خاص، هم user="*" و هم group="*" با هر اتصالی تطبیق مییابند. در صورت نبود چنین قواعدی، رفتار پیشفرض مجاز دانستن اتصالات از سوی همان شناسه کاربری (UID) است که مالک فرایند dbus-daemon است. گذرگاه شناختهشده نشست معمولاً از این رفتار پیشفرض استفاده میکند، در حالی که گذرگاه شناختهشده سیستم معمولاً به هر اتصالی اجازه ورود میدهد.
قواعد با ویژگی own یا own_prefix هنگام تلاش یک اتصال برای مالکیت یک نام گذرگاه شناختهشده بررسی میشوند. به عنوان یک حالت خاص، own="*" با هر نام گذرگاه شناختهشدهای تطبیق مییابد. گذرگاه نشست معمولاً به هر اتصالی اجازه مالکیت هر نامی را میدهد، در حالی که گذرگاه سیستم معمولاً به هیچ اتصالی اجازه مالکیت نامی را نمیدهد، مگر آنکه با پیکربندیهای بیشتر مجاز شده باشد. سرویسهای سیستمی که میخواهند مالکیتی بر نامی داشته باشند باید پیکربندیای نصب کنند که به آنها اجازه دهد، معمولاً از طریق قواعدی به شکل <policy user="some-system-user"><allow own="..."/></policy>.
دستور <allow own_prefix="a.b"/> به شما اجازه میدهد مالک نام "a.b" یا هر نامی شوید که بخشهای نخست جداشده با نقطه آن "a.b" باشد: به ویژه، شما میتوانید مالک "a.b.c" یا "a.b.c.d" شوید، اما نمیتوانید مالک "a.bc" یا "a.c" باشید. این قابلیت زمانی مفید است که سرویسهایی مانند Telepathy و ReserveDevice معنای خاصی برای زیردرختهای نامهای شناختهشده تعریف میکنند، مانند org.freedesktop.Telepathy.ConnectionManager.(anything) و org.freedesktop.ReserveDevice1.(anything).
رد کردن یک کاربر یا گروه درون یک <policy> برای یک کاربر یا گروه بیمعنی است؛ رد کردن کاربر/گروه تنها میتواند درون خطمشیهای context="default" یا context="mandatory" قرار گیرد.
یک قاعده <deny> منفرد ممکن است ترکیبی از ویژگیها مانند send_destination و send_interface و send_type را تعیین کند. در این حالت، مسدودسازی تنها در صورتی اعمال میشود که هر دو ویژگی با پیام تطبیق داشته باشند. برای مثال <deny send_interface="foo.bar" send_destination="foo.blah"/> پیامهای دارای رابط دادهشده و نام گذرگاه دادهشده را مسدود میکند. برای به دست آوردن اثر OR (یا)، باید چندین قاعده <deny> مجزا تعیین کنید.
شما نمیتوانید ویژگیهای send_ و receive_ را در یک قاعده ترکیب کنید، زیرا «امکان ارسال پیام» و «امکان دریافت پیام» به طور جداگانه ارزیابی میشوند.
در استفاده از send_interface/receive_interface دقت کنید، زیرا فیلد رابط در پیامها اختیاری است. به ویژه، هرگز از <deny send_interface="org.foo.Bar"/> استفاده نکنید! این کار باعث میشود پیامهای بدون رابط برای تمامی سرویسها مسدود شوند، که قطعاً مقصود شما نیست. همیشه از قواعدی به این شکل استفاده کنید: <deny send_interface="org.foo.Bar" send_destination="org.foo.Service"/>
عنصر <selinux> شامل تنظیمات مرتبط با سامانه امنیت لینوکس (Security Enhanced Linux) است. جزئیات بیشتر در ادامه آمده است.
یک عنصر <associate> زیر یک عنصر <selinux> قرار گرفته و یک نگاشت ایجاد میکند. در حال حاضر تنها یک نوع وابستگی امکانپذیر است:
<associate own="org.freedesktop.Foobar" context="foo_t"/>
این بدان معناست که اگر اتصالی درخواست مالکیت نام "org.freedesktop.Foobar" را داشته باشد، بافت مبدأ (source context) برابر با بافت اتصال و بافت مقصد (target context) برابر "foo_t" خواهد بود - به بحث کوتاه درباره SELinux در ادامه مراجعه کنید.
توجه داشته باشید که بافت در اینجا، بافت هدف در هنگام درخواست یک نام است، نه بافت اتصالی که مالک نام است.
در حال حاضر روشی برای تعیین مقدار پیشفرض برای مالکیت هر نامی وجود ندارد؛ در صورت اضافه شدن این نحو، به این شکل خواهد بود:
<associate own="*" context="foo_t"/>
اگر دلیلی برای کاربردی بودن این مورد یافتید، توسعهدهندگان را مطلع سازید. در حال حاضر، مقدار پیشفرض برابر با بافت امنیتی خودِ گذرگاه خواهد بود.
اگر دو عنصر <associate> نام یکسانی را تعیین کنند، عنصری که در پرونده پیکربندی دیرتر آمده باشد استفاده خواهد شد.
عنصر <apparmor> برای پیکربندی میانجیگری AppArmor در گذرگاه استفاده میشود. این عنصر میتواند یک ویژگی برای تعیین حالت میانجیگری داشته باشد:
<apparmor mode="(enabled|disabled|required)"/>
حالت پیشفرض "enabled" است. در حالت "enabled"، اگر پشتیبانی AppArmor در هسته موجود باشد، میانجیگری انجام میشود. اگر پشتیبانی موجود نباشد، dbus-daemon اجرا میشود اما میانجیگری AppArmor صورت نخواهد گرفت. در حالت "disabled"، میانجیگری AppArmor غیرفعال است. در حالت "required"، در صورت وجود پشتیبانی در هسته، میانجیگری فعال میشود و در غیر این صورت، dbus-daemon از اجرا خودداری میکند.
حالت میانجیگری AppArmor گذرگاه پس از آغاز به کار گذرگاه قابل تغییر نیست. تغییر این حالت در پرونده پیکربندی و ارسال سیگنال SIGHUP به دیمن هیچ اثری بر حالت میانجیگری نخواهد داشت.
یکپارچهسازی سرویسهای نشست (INTEGRATING SESSION SERVICES)
پروندههای یکپارچهسازی برای سرویسهای نشست اجباری نیستند: هر برنامهای که به گذرگاه نشست دسترسی داشته باشد میتواند یک نام شناختهشده را درخواست کرده و رابطهای D-Bus را ارائه دهد.
بسیاری از سرویسهای نشست D-Bus از «فعالسازی سرویس» (service activation) پشتیبانی میکنند؛ سازوکاری که در آن dbus-daemon میتواند سرویس را بنا به تقاضا، یا از طریق اجرای خود سرویس نشست یا از راه ارتباط با systemd --user راهاندازی نماید. این سازوکار با ایجاد یک پرونده سرویس (service file) در پوشه ${datadir}/dbus-1/services تنظیم میشود، برای نمونه:
[D-BUS Service] Name=com.example.SessionService1 Exec=/usr/bin/example-session-service # اختیاری SystemdService=example-session-service
برای جزئیات بیشتر درباره محتوا و تفسیر پروندههای سرویس، به مشخصات فنی D-Bus مراجعه کنید.
اگر یک پرونده سرویس برای com.example.SessionService1 وجود داشته باشد، باید نام آن com.example.SessionService1.service باشد، اگرچه برای سازگاری با سرویسهای قدیمی این مورد اجباری نیست.
سرویسهای نشستی که گزینه اختیاری SystemdService را اعلام میکنند باید یک پرونده واحد سرویس کاربر systemd را نیز ارائه دهند که نام یا نام مستعار (Alias) آن با SystemdService همخوانی داشته باشد (برای جزئیات بیشتر در مورد واحدهای سرویس systemd به systemd.unit(5) و systemd.service(5) مراجعه کنید)، برای نمونه:
[Unit] Description=Example session service [Service] Type=dbus BusName=com.example.SessionService1 ExecStart=/usr/bin/example-session-service
یکپارچهسازی سرویسهای سیستم (INTEGRATING SYSTEM SERVICES)
گذرگاه استاندارد سیستم به طور پیشفرض اجازه فراخوانی متدها یا مالکیت نامهای شناختهشده گذرگاه را نمیدهد؛ بنابراین یک سرویس مفید سیستم D-Bus معمولاً باید یک خطمشی امنیتی پیشفرض پیکربندی کند تا بتواند کار کند. سرویسهای سیستم D-Bus باید یک پرونده خطمشی پیشفرض را در پوشه ${datadir}/dbus-1/system.d نصب نمایند که شامل قواعد خطمشی لازم برای عملکرد آن سرویس سیستم باشد. یک پرونده خطمشی مطابق با بهترین شیوهها اغلب شبیه به این خواهد بود:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy user="_example">
<allow own="com.example.Example1"/>
</policy>
<policy context="default">
<allow send_destination="com.example.Example1"/>
</policy>
</busconfig>
که در آن _example نام کاربری شناسه کاربری (uid) سیستم است که فرایند دیمن سرویس سیستم را اجرا خواهد کرد، و com.example.Example1 نام گذرگاه شناختهشده آن است.
پرونده خطمشی برای com.example.Example1 معمولاً باید com.example.Example1.conf نامگذاری شود.
برخی از سرویسهای موجود سیستم به قواعد پیچیدهتر <policy> تکیه میکنند تا پیامهایی را که سرویس میتواند دریافت کند کنترل نمایند. با این حال، زبان خطمشی dbus-daemon برای خطمشیهای بسیار دقیق و جزئی مناسب نیست: هر خطمشی باید بر حسب رابطها و نامهای متدهای D-Bus بیان شود، نه بر اساس مفاهیم سطح بالاتری چون دستگاههای جداشدنی یا توکار. توصیه میشود که سرویسهای جدید معمولاً پیامهای فراخوانی متد را از تمامی فراخوانندهها بپذیرند، و سپس از یک خطمشی قابل کنترل توسط مدیر سیستم برای تصمیمگیری در مورد اطاعت از درخواستهای موجود در آن پیامهای متد استفاده کنند، برای مثال با مشورت با polkit.
مانند سرویسهای نشست، بسیاری از سرویسهای سیستم D-Bus از سازوکار فعالسازی سرویس پشتیبانی میکنند که در آن dbus-daemon میتواند سرویس را در صورت تقاضا، یا با اجرای مستقیم سرویس سیستم یا با ارتباط با systemd راهاندازی کند. این کار با ایجاد یک پرونده سرویس در پوشه ${datadir}/dbus-1/system-services تنظیم میشود، برای نمونه:
[D-BUS Service] Name=com.example.Example1 Exec=/usr/sbin/example-service User=_example # اختیاری SystemdService=dbus-com.example.Example1.service
برای جزئیات بیشتر درباره محتوا و تفسیر پروندههای سرویس، به مشخصات فنی D-Bus مراجعه کنید.
اگر یک پرونده سرویس برای com.example.Example1 وجود داشته باشد، حتماً باید com.example.Example1.service نامگذاری شود.
سرویسهای سیستمی که گزینه اختیاری SystemdService را اعلام میکنند باید یک پرونده واحد سرویس systemd را نیز فراهم کنند که نام یا نام مستعار (Alias) آن با SystemdService همخوانی داشته باشد (برای جزئیات بیشتر به systemd.unit(5) و systemd.service(5) مراجعه کنید)، برای نمونه:
[Unit] Description=Example service [Service] Type=dbus BusName=com.example.Example1 ExecStart=/usr/sbin/example-service [Install] WantedBy=multi-user.target Alias=dbus-com.example.Example1.service
سامانه SELINUX (SELINUX)
برای جزئیات کامل در مورد SELinux به نشانی http://www.nsa.gov/selinux مراجعه کنید. گزیدهای از نکات مفید:
به هر فاعل (فرایند) و مفعول (مانند پرونده، سوکت، شیء ارتباط بینفرایندی IPC و غیره) در سیستم مجموعهای از ویژگیهای امنیتی به نام «بافت امنیتی» (security context) اختصاص داده میشود. یک بافت امنیتی شامل تمامی ویژگیهای امنیتی مرتبط با یک فاعل یا مفعول خاص است که به خطمشی امنیتی مربوط میشوند.
به منظور کپسولهسازی بهتر بافتهای امنیتی و فراهم کردن کارایی بیشتر، کد اعمال خطمشی در SELinux معمولاً با شناسههای امنیتی (SID) کار میکند تا بافتهای امنیتی. شناسه امنیتی یک عدد صحیح است که توسط سرور امنیتی در زمان اجرا به یک بافت امنیتی نگاشت میشود.
هنگامی که یک تصمیم امنیتی مورد نیاز باشد، کد اعمال خطمشی یک جفت SID (معمولاً SID یک فاعل و SID یک مفعول، اما گاهی یک جفت SID فاعل یا یک جفت SID مفعول) و یک رده امنیتی مفعول را به سرور امنیتی ارسال میکند. رده امنیتی مفعول نوع شیء را نشان میدهد، برای نمونه یک فرایند، یک پرونده معمولی، یک پوشه، یک سوکت TCP و غیره.
تصمیمات دسترسی مشخص میکنند که آیا مجوزی برای یک جفت SID و رده مشخص اعطا میشود یا خیر. هر رده شیء دارای مجموعهای از مجوزهای مرتبط است که برای کنترل عملیات روی اشیاء با آن رده تعریف شدهاند.
سامانه D-Bus بررسیهای امنیتی SELinux را در دو نقطه انجام میدهد:
نخست، هر زمانی که پیامی از یک اتصال به اتصال دیگر هدایت میشود، دیمن گذرگاه مجوزها را با بافت امنیتی اتصال اول به عنوان مبدأ، بافت امنیتی اتصال دوم به عنوان مقصد، رده شیء "dbus" و مجوز درخواستی "send_msg" بررسی میکند.
اگر یک بافت امنیتی برای یک اتصال در دسترس نباشد (که در صورت استفاده از سوکتهای دامنه یونیکس غیرممکن است)، بافت مقصد مورد استفاده، بافت خودِ دیمن گذرگاه خواهد بود. در حال حاضر روشی برای تغییر این پیشفرض وجود ندارد، زیرا ما فرض میکنیم که تنها از سوکتهای دامنه یونیکس برای اتصال به گذرگاه سراسری سیستم استفاده میشود. در صورت تغییر این موضوع، روشی برای تعیین بافت پیشفرض اتصال افزوده خواهد شد.
دوم، هر زمان که یک اتصال درخواست مالکیت یک نام را داشته باشد، دیمن گذرگاه مجوزها را با بافت امنیتی اتصال به عنوان مبدأ، بافت امنیتی تعیینشده برای نام در پرونده پیکربندی به عنوان مقصد، رده شیء "dbus" و مجوز درخواستی "acquire_svc" بررسی مینماید.
بافت امنیتی برای نام یک گذرگاه توسط عنصر <associate> که پیشتر در این سند شرح داده شد تعیین میگردد. اگر نامی دارای هیچ بافت امنیتی پیوستشدهای در پرونده پیکربندی نباشد، از بافت امنیتی خودِ دیمن گذرگاه استفاده خواهد شد.
سامانه APPARMOR (APPARMOR)
هنگام اتصال برنامهها به گذرگاه، بافت محدودسازی (confinement context) مربوط به AppArmor ذخیره میشود. این بافت شامل یک برچسب (label) و یک حالت محدودسازی است. هنگامی که یک تصمیم امنیتی لازم باشد، دیمن از بافت محدودسازی برای پرسوجو از خطمشی AppArmor استفاده میکند تا مشخص کند آیا اقدام باید مجاز شود یا رد گردد و آیا باید حسابرسی (audit) شود یا خیر.
دیمن بررسیهای امنیتی AppArmor را در سه نقطه انجام میدهد:
نخست، هر زمانی که پیامی از یک اتصال به اتصال دیگر هدایت میشود، دیمن گذرگاه مجوزها را با برچسب اتصال نخست به عنوان مبدأ، برچسب یا نام اتصال دوم به عنوان مقصد، به همراه نام گذرگاه، نام مسیر، نام رابط، و نام عضو بررسی میکند. پیامهای پاسخ، مانند method_return و پیامهای خطا، در صورتی که در پاسخ به پیامی باشند که پیشتر مجاز دانسته شده است، به صورت ضمنی مجاز خواهند بود.
دوم، هر زمانی که یک اتصال درخواست مالکیت یک نام را دارد، دیمن گذرگاه مجوزها را با برچسب اتصال به عنوان مبدأ، نام درخواستی به عنوان مقصد، به همراه نام گذرگاه بررسی میکند.
سوم، هر زمانی که یک اتصال تلاش برای شنود پنهانی (eavesdropping) داشته باشد، دیمن گذرگاه مجوزها را با برچسب اتصال به عنوان مبدأ، به همراه نام گذرگاه بررسی میکند.
قواعد AppArmor برای میانجیگری گذرگاه درون پروندههای پیکربندی گذرگاه ذخیره نمیشوند؛ بلکه در نمایه AppArmor برنامه نگهداری میگردند. برای جزئیات بیشتر به apparmor.d(5) مراجعه کنید.
اشکالزدایی (DEBUGGING)
اگر تلاش میکنید دریابید پیامهای شما به کجا میروند یا چرا پیامی دریافت نمیکنید، چندین کار هست که میتوانید امتحان کنید.
به یاد داشته باشید که گذرگاه سیستم بسیار محدود و قفلشده است و اگر پرونده خطمشی امنیتی برای عبور پیام خود نصب نکرده باشید، کار نخواهد کرد. برای گذرگاه نشست، این نگرانی وجود ندارد.
سادهترین راه برای درک آنچه روی گذرگاه رخ میدهد، اجرای برنامه dbus-monitor است که همراه با بسته D-Bus ارائه میشود. همچنین میتوانید پیامهای آزمایشی را با dbus-send ارسال کنید. این برنامهها دارای صفحات راهنمای اختصاصی خود هستند.
اگر میخواهید بدانید خودِ دیمن چه میکند، میتوانید یک نسخه جداگانه از دیمن را برای آزمودن اجرا کنید. این کار به شما امکان میدهد دیمن را تحت یک اشکالزدا (debugger) قرار دهید، یا آن را با خروجی پرحجم (verbose) اجرا کنید، بدون اینکه دیمنهای واقعی نشست و سیستم خود را به هم بریزید.
برای اجرای یک نسخه آزمایشی جداگانه از دیمن، برای نمونه میتوانید یک ترمینال باز کرده و تایپ کنید:
DBUS_VERBOSE=1 dbus-daemon --session --print-address
آدرس دیمن آزمایشی با راهاندازی دیمن چاپ خواهد شد. شما باید این نشانی را رونوشت کرده و هنگام اجرای برنامههایی که مایلید آزمایش کنید، به عنوان مقدار متغیر محیطی DBUS_SESSION_BUS_ADDRESS قرار دهید. این امر سبب میشود آن برنامهها به جای DBUS_SESSION_BUS_ADDRESS گذرگاه نشست واقعی شما، به گذرگاه آزمایشی شما متصل شوند.
متغیر محیطی DBUS_VERBOSE=1 هیچ اثری نخواهد داشت مگر آنکه نسخه D-Bus شما با فعال بودن حالت پرحجم کامپایل شده باشد. به دلیل تاثیر بر کارایی، این کار در ساختهای تجاری توصیه نمیشود. اگر نسخه شما برای اهداف اشکالزدایی ساخته نشده باشد، ممکن است نیاز به کامپایل مجدد D-Bus داشته باشید. (متغیر DBUS_VERBOSE همچنین بر کتابخانه D-Bus و بنابراین بر برنامههای استفادهکننده از آن تاثیر میگذارد؛ مشاهده خروجی مفصل هم در سمت کلاینت و هم از سوی دیمن میتواند سودمند باشد.)
اگر میخواهید کارهای پیشرفتهتری انجام دهید، میتوانید یک پیکربندی گذرگاه سفارشی برای گذرگاه آزمایشی خود ایجاد نمایید (برای نمونه به پروندههای session.conf و system.conf که دو پیکربندی پیشفرض را تعریف میکنند نگاه کنید). این کار به شما اجازه میدهد برای مثال شاخه متفاوتی را برای پروندههای .service تعیین کنید.
نویسندگان (AUTHOR)
نگاه کنید به:
گزارش باگها (BUGS)
لطفاً گزارشهای اشکال را به فهرست پستی D-Bus یا سامانه ردیابی اشکالات ارسال کنید؛ نگاه کنید به:
یادداشتها (NOTES)
- 1.
- رله کردن اتصالات از طریق Secure Shell یا پروتکلی مشابه:
- 2.
- مشخصات فنی D-Bus:
- 3.
- سامانه polkit:
همچنین ببینید (SEE ALSO)
dbus-send(1), dbus-monitor(1), dbus-launch(1), dbus-run-session(1), systemd(1)
| 03/02/2025 | D-Bus 1.16.2 |