مدت طولانی کار تنها اثبات میکند که راهاندازی با همان دسترسیهایی موفق شده که سرویس در آن لحظه داشت. خطاهایی که اینجا اهمیت دارند بعداً میآیند: کلاینت تازهای وصل میشود، فهرست ابطال جایگزین میشود، اسکریپت کمکی باید فایلی بنویسد. هر یک از اینها باز کردن تازهای است که حساب بدون دسترسی انجام میدهد، با پرسش مجوز خودش و پیام خطای خودش. سه تصمیم، پیکربندیای را که به کار ادامه میدهد از یکی که در رویداد بعدی شکست میخورد جدا میکند.

آنچه زود بارگذاری شده را از آنچه بعداً باز میشود جدا کنید

توصیفگر دستهای روی یک توصیف فایل باز است و حالت دسترسی هنگام ساخت آن توصیف ثابت شد. تغییر کاربر فرایند در ادامه آن دسته را نمیبندد، از این رو فایل کلیدی که با root خوانده شده پس از کاهش نیز کار میکند. حالت هم تغییر نمیکند: دسته بازشده برای خواندن نوشتنی نمیشود و دسته نوشتنی فقط به این دلیل که حساب حقوق خود بر مسیر را از دست داده پس گرفته نمیشود. این دو واقعیت بیشتر رفتار شگفتانگیز این گزارشها را توضیح میدهد.

نیم دیگر حافظه است. سرویس میتواند یک گواهی را تجزیه کند، مواد تجزیهشده را نگه دارد و فایل را ببندد؛ آنچه در استفاده میماند داده است نه فایل باز. پس ترافیک پیوسته نه اثبات میکند که توصیفگری باز است و نه اینکه نام مسیر قابل دسترسی است. تنها اثبات میکند که مواد لازم برای نشست کنونی پیشتر بهدست آمده است.

باز کردن بعدی تراکنش دیگری است. با اعتبارنامههای کنونی، بستر امنیتی کنونی و نمای سوارکردن کنونی اجرا میشود، پس مسیری که هنگام راهاندازی خواندنی بود میتواند در اتصال بعدی رد شود. چرخش یک تله میافزاید: نوشتن فایل تازه روی همان نام مسیر، توصیفگر موجود را به شیء کهن میچسباند، پس بارگذاری دوباره ممکن است موفق به نظر برسد در حالی که سرویس هنوز محتوای پیشین را به کار میبرد. پیش از باور به چرخش، inode در دست فرایند را با inode روی دیسک بسنجید.

سه خواندن زمان اجرا و زمان رخ دادن هر یک را نام ببرید

سه منبع معمولاً بسیار پس از راهاندازی باز میشوند و در لحظههای متفاوت شکست میخورند. فایل پیکربندی مخصوص یک کلاینت هنگامی خوانده میشود که همان کلاینت وصل شود، پس میتواند برای یک کاربر بشکند در حالی که دیگران ادامه میدهند. داده ابطال هنگام احراز هویت همتا و دوباره هنگام جایگزینی فایل بررسی میشود. پوشه موقت تنها هنگامی لمس میشود که اسکریپت یا افزونهای چیزی بنویسد.

هیچیک از این سه به مسیر راهاندازی تعلق ندارد، از این رو سروری که هفتهها سالم بوده میتواند در اتصال بعدی شکست بخورد. این دسته صاحب اصلاح را هم نام میبرد: دو مورد نخست اجازه خواندن پیکربندی زیر حساب سرویس است و سومی جایی نوشتنی با هدفی تنگ.

Path reopened laterWhat triggers the openFirst sign when it fails
Client configuration fileA connection for that client identityOne client rejected while others connect
Revocation dataPeer authentication, including after replacementRevoked and valid peers both refused
Script or plugin temporary directoryA helper needs to create a fileThe helper exits with a path error

persist-key به پرسشی تنگتر از آنچه بیشتر مردم میپندارند پاسخ میدهد. این گزینه فایل کلید را در بازنشانیهای مستند SIGUSR1 و ping-restart باز نگه میدارد، و برای فایلهای CCD، داده ابطال، برنامههای کمکی یا راهاندازی کامل فرایند کاری نمیکند. آنها همچنان مسیرهای باز کردن خود را دنبال میکنند، زیر هر حسابی که در آن لحظه در حال اجراست.

حساب و نمایی را که واقعاً دارد تأیید کنید

از سرویس در حال اجرا بپرسید کدام حساب را به کار میبرد، به جای اعتماد به فایل unit، سپس پاسخ را با آنچه unit تعیین میکند بسنجید. ناسازگاری نخستین چیزی است که باید حل شود، زیرا هر بررسی مجوز بعدی به همان کسی اجرا میشود که فرایند واقعاً هست. سپس مسیر را جزء به جزء بپیمایید؛ عبور در هر سطح سنجیده میشود، پس فایل خواندنی در پوشهای که عبور از آن ممکن نیست همچنان ناخواندنی میماند. حالت نهایی فایل آخرین پرسش است نه نخستین.

فضاهای نام و جعبههای شن سرویس مرزهایی میافزایند که مالکیت و بیتهای حالت توصیف نمیکنند. مسیری که در پوسته شما دیده میشود میتواند درون chroot، فضای نام سوارکردن یا واحدی که پوشههای خانه را پنهان میکند نباشد یا فقط خواندنی باشد. ماژولهای امنیتی لایه دیگری میافزایند، پس فایلی که خواندنی به نظر میرسد باز هم میتواند هنگام باز شدن رد شود.

ps -o user:12,pid,args -C openvpn
systemctl show -p User -p Group -p ProtectHome -p RootDirectory [email protected]
sudo -u openvpn namei -l /etc/openvpn/ccd/alice

خواندن موفق در پوسته مدیر هیچیک از آن شرطهای ترکیبی را نمیآزماید. بررسی را با حساب سرویس، با همان فضای نام و جعبه شن اجرا کنید، یا بپذیرید که نتیجه پوسته شما را توصیف میکند نه سرور را. فرمان سوم نسخه ارزان همان آزمون است: حالت هر جزء را چاپ میکند و در نخستین جزئی که حساب سرویس نمیتواند از آن بگذرد شکست میخورد.

نوشتن زمان اجرا را در پوشهای از خودش بدهید

خواندن تنها نیمی از فهرست است. اسکریپت کمکی ممکن است به ساختن فایل وضعیت نیاز داشته باشد، افزونه ممکن است به نوشتن وضعیت کنار پیکربندی خود نیاز داشته باشد، و این نوشتنها با نوشتنی کردن درخت پیکربندی پوشش داده نمیشوند. به پوشه مشخص همان اجازه نوشتن را بدهید که کارکردش میخواهد، با مالک و حالتی که بتوانید توضیح دهید. برای هر چیز که تنها خوانده میشود دسترسی فقط خواندنی را ترجیح دهید.

اجازههای کلید خصوصی را از فایلهای سیاست جدا نگه دارید. کلیدی که باید پس از بازنشانی دوباره خوانده شود شرطی متفاوت از فایل کلاینت دارد که در هر اتصال خوانده میشود، و یک حالت سهلگیرانه برای هر دو دسترسی بیشتری از آنچه مشکل میخواهد میدهد. حساب سرویس اختصاصی با مالکیت تنگ آسانتر از گروهی گسترده بازرسی میشود. هنگامی که کلید باید از بازنشانیها جان سالم ببرد، persist-key خواندن دوباره را برمیدارد به جای گستردن پوشه.

از رویدادی که میتوانید بازتولید کنید تصمیم بگیرید

تونل زنده تنها یک مسیر در کد را اثبات میکند. رویدادی که فایل را میخواهد تنها آزمونی است که باز کردن مورد نظر شما را میپوشاند، خواه اتصال تازه کلاینت باشد، خواه فایل ابطال جایگزینشده، خواه بازنشانی نرم مجاز یا راهاندازی دوباره برنامهریزیشده. رویداد را برگزینید، اجرا کنید و نخستین خطا را نگه دارید نه آخرین را.

برای بازنشانی نرم، یک سیگنال و گزارش unit نشان میدهد آیا کلید دوباره خوانده شد. سیگنال را بفرستید و سپس آخرین سطرهایی را که unit نوشته است بخوانید:

systemctl kill -s SIGUSR1 [email protected]
journalctl -u [email protected] -n 40 --no-pager

نتیجه نگیرید که سرویس بهخطرافتاده تنها به این دلیل که دسترسیها کاهش یافته دیگر نمیتواند فایلها را تغییر دهد. آنچه هنوز میتواند بستگی به اعتبارنامههای باقیمانده، تواناییها، پوشههایی که میتواند در آنها بنویسد و هر توصیفگر نوشتنی دارد که هنوز در دست دارد. کاهش دسترسی اقتدار را تنگ میکند و فهرست باز کردنهای زمان اجرا نشان میدهد تا کجا. آن مرز را کنار پیکربندی بنویسید تا شخص بعدی مجبور به کشف دوباره آن نباشد.

مقالات مرتبط