احراز هویت PAM بهصورت دستی کار میکند اما بهعنوان سرویس OpenVPN شکست میخورد
ورود PAM که از پوسته root کار میکند و زیر systemd شکست میخورد به برنامه کمکی اشاره دارد، نه به گذرواژه. امتیازات، دسترسی فایل و SELinux را جدا کنید.
احراز هویت از طریق PAM میتواند وقتی کلاینت را دستی اجرا میکنید موفق شود و با AUTH_FAILED شکست بخورد وقتی systemd همان پروفایل را راه میاندازد. گذرواژه بین این اجراها تغییر نمیکند؛ آنچه تغییر میکند مجموعه محدودیتهای پیرامون فرآیندی است که از PAM میپرسد. PAM از طریق یک برنامه کمکی پاسخ میدهد که توانایی تغییر اعتبارنامههای خودش دقیقاً همان چیزی است که یک unit سختشده حذف میکند. آن برنامه کمکی و مرزی که لازم دارد را قبل از دست زدن به فهرست توانمندیها پیدا کنید.
unix_chkpwd همان فایل دودویی است که به پرسش PAM پاسخ میدهد
با احراز هویت محلی گذرواژه، pam_unix بهندرت خودِ فایل هش را میخواند. این unix_chkpwd را اجرا میکند، که توزیعها آن را بهصورت setuid root یا setgid shadow نصب میکنند تا یک گذرواژه به نمایندگی از فرآیندی بررسی شود که کاری با خواندن /etc/shadow ندارد. توانایی کسب آن هویت را بردارید و برنامه کمکی نمیتواند بررسی را کامل کند، بنابراین ماژول یک شکست احراز هویت ساده برمیگرداند.
سپس شکست در هر گزارشی که کلاینت میبیند مانند یک مشکل اعتبارنامه به نظر میرسد. این همان تله است: کلاینت آنچه PAM به آن گفته را گزارش میکند و PAM فقط گزارش میکند که پشته «نه» گفته است. اجرای دستی برنامه کمکی بهعنوان root هم چیزی را ثابت نمیکند، چون مسیر امتیازی را تمرین میکند که سرویس هرگز استفاده نمیکند. unitی را که systemd واقعاً بارگذاری کرده بخوانید، سپس گزارش سیستم را برای تلاشی که انجام داده بخوانید. این دو دیدگاه مشکل سندباکس را از مشکل گذرواژه نادرست جدا میکنند.
قبل از خواندن گزارش گذرواژه، unit را بخوانید
یک unit بستهبندیشده میتواند یک drop-in داشته باشد که شما ننوشتهاید، و پیکربندی مؤثر نتیجه ادغامشده است. unit را همانطور که systemd میبیند چاپ کنید، همراه با تنظیمات سندباکس که تعیین میکنند آیا برنامه کمکی میتواند خودش را بالا ببرد. بازرسی فقطخواندنی در این مرحله کافی است.
systemctl cat [email protected]
systemctl show [email protected] -p User -p Group -p CapabilityBoundingSet -p AmbientCapabilities -p NoNewPrivileges
journalctl -u [email protected] -b
فرمان نخست نشان میدهد unit و drop-inهایش از کجا میآیند، که مهم است زیرا یک بازنویسی که ماهها پیش افزوده شده از حافظه درباره دلیل وجودش بیشتر عمر میکند. فرمان دوم مقادیر سندباکسی را چاپ میکند که دو بخش بعدی به آنها وابستهاند.
آنچه میبینید را با یک میزبان سالم از همان توزیع و نسخه مقایسه کنید. تفاوت در User، CapabilityBoundingSet یا NoNewPrivileges یک سرنخ مشخص است؛ تفاوت در توضیحات متنی نیست. مقادیر را قبل از هر تغییری بنویسید، چون مقایسه بعدی با هدفی متحرک چیزی را ثابت نمیکند. اگر سرویس با حساب بدون امتیاز و مجموعه bounding خالی اجرا میشود، برنامه کمکی تقریباً چیزی برای کار کردن ندارد.
تبدیل اعتبارنامه، دسترسی فایل و سیاست سه مرز هستند
با آنچه در هنگام exec رخ میدهد شروع کنید. یک فایل دودویی setuid یا فایلی که توانمندیهای فایل دارد تبدیل اعتبارنامه را تحریک میکند، بنابراین هویت حاصل ادامه فراخواننده نیست. مجموعه bounding محدود میکند چنین فایلی چه چیزی میتواند به دست آورد، و NoNewPrivileges کسب setuid، setgid و توانمندیهای فایل را کاملاً مسدود میکند. هر یک از این سه میتواند برنامه کمکی را متوقف کند در حالی که هر کارکرد دیگر سرویس دستنخورده میماند.
سپس دور زدن اختیاری گسترده را از دسترسی خواندن محدود جدا کنید. CAP_DAC_OVERRIDE تقریباً همهجا بررسیهای اختیاری را رد میکند، در حالی که CAP_DAC_READ_SEARCH خواندن و پیمایش پوشهها را با اختیارات افزوده خودش پوشش میدهد. آنها ابزارهای متفاوتی با شعاع اثر متفاوت هستند و هیچکدام املای جمله «بگذار PAM فایل shadow را بخواند» نیستند.
در پایان بپرسید آیا سیاست اجباری اصلاً این کار را مجاز میداند. یک توانمندی لینوکس SELinux را نقض نمیکند و داشتن یکی چیزی درباره قاعده type enforcement ثابت نمیکند. رد شدن دسترسی فایل و رد شدن توانمندی را شواهد متفاوت بدانید، چون اصلاحهای متفاوت و اغلب مالکان متفاوت را نام میبرند. هر فیلد رکورد را بخوانید نه فقط واژه denied را. کدام فایل اجرایی کار را انجام داد، در کدام دامنه اجرا شد، هدف از چه نوعی بود، کدام کلاس شیء درگیر بود و سیاست کدام اجازه را رد کرد — هرکدام پاسخ را به شیوهای متفاوت محدود میکند.
رد شدن را از گزارش ممیزی بیرون بکشید
روی میزبان در حالت اعمال، ردپای ممیزی تنها جایی است که یک رد شدن را ثبت میکند. رویدادهای اخیر را جویا شوید و آنها را بر حسب زمان ورود ناموفق بخوانید، نه بر حسب زمانی که تحقیق را آغاز کردید.
ausearch -m AVC,USER_AVC -ts recent
نتیجه خالی دلیل بیگناهی نیست. یعنی یا ممیزی جمعآوری نمیکند، یا پنجره شما آن تلاش را از دست داده است، و هر دو احتمال باید پیش از کنار گذاشتن سیاست کنار گذاشته شوند.
راهنمای عیبیابی SELinux از Red Hat بررسی برچسب و پیکربندی را پیش از تولید قواعد allow قرار میدهد، که ترتیب درست برای این مشکل هم هست. یک فایل کمکی با برچسب اشتباه و یک شکاف در سیاست رد شدنهای مشابه تولید میکنند اما اصلاحهای متفاوت میخواهند. تولید قاعده allow برای یک خطای برچسبگذاری نقص را پنهان میکند و میگذارد بهروزرسانی بعدی بسته آن را دوباره وارد کند. برچسب برنامه کمکی نصبشده را پیش از نوشتن هر سیاستی تأیید کنید.
تغییر را با یک ورود پذیرفتهشده و یک ورود ردشده ثابت کنید
فقط همان مرزی را که نشان دادهاید تغییر دهید، سپس هر دو نتیجه را بیازمایید. حسابی که باید احراز هویت شود باید موفق شود و حسابی با گذرواژه نادرست باید همچنان شکست بخورد. تغییری که هر تلاشی را موفق میکند احراز هویت را حذف کرده است نه اینکه آن را تعمیر کرده باشد.
یک تلاش اتصال واقعی انجام دهید و بلافاصله پس از آن گزارش را بخوانید. خطی که تعمیر را ثابت میکند ورودی pam_unix(openvpn:auth) برای آن تلاش است: باید احراز هویت موفق را نشان دهد و هیچ رکورد AVC نباید همان ثانیه را داشته باشد.
journalctl -u [email protected] -n 30 --no-pager
ss -tnp | grep openvpn
یک تونل سالم به اتصال مجدد هم نیاز دارد، چون تغییرات سندباکس اتصال دوم را بیشتر از اولی میشکنند. پس از اتصال مجدد سوکت برقرارشده را بررسی کنید و تأیید کنید که همان unit هنوز به آن سرویس میدهد.