محتوای آموزشی وبلاگ نتآرام
یک برنامه در ترمینال میتواند در پوشه خودش بنویسد، اما وقتی همان برنامه را به شکل سرویس systemd اجرا میکنید، خطای
Read-only file system میگیرد. یکی از علتهای ممکن، محدودیت ایزولهسازی سرویس است: گزینهای مانند ProtectSystem=strict میتواند بخش بزرگی از فایلسیستم را برای همان سرویس فقطخواندنی کند.این پیام همیشه از systemd نیست. خود فایلسیستم ممکن است به دلیل خطا یا تنظیم نصب فقطخواندنی شده باشد. ابتدا این دو حالت را جدا میکنیم، بعد در صورت لزوم فقط مسیر داده موردنیاز سرویس را مجاز میکنیم. مثالها برای مدیر سرور لینوکس دارای systemd و دسترسی
sudo هستند؛ نام سرویس و مسیرها را باید با مقادیر واقعی جایگزین کنید.۱. نام سرویس و مسیر خطا را پیدا کنید
در ترمینال سرور، وضعیت سرویس فرضی
کد / دستورmyapp.service را بخوانید:sudo systemctl status myapp.service --no-pager
sudo journalctl -u myapp.service -b -n 100 --no-pager
در خروجی، مسیر دقیق فایلی را که برنامه نتوانسته بسازد یا تغییر دهد، همراه با زمان خطا یادداشت کنید. برای نمونه ممکن است برنامه بخواهد در
/var/lib/myapp/cache فایل بسازد. اگر خطای شما Permission denied است، مجوز کاربر و سیاستهای امنیتی نیز باید بررسی شوند؛ هر خطای دسترسی به معنی فقطخواندنی بودن systemd نیست. گزارش را قبل از اشتراکگذاری از رمزها و اطلاعات مشتری پاک کنید.۲. ببینید خود فایلسیستم قابل نوشتن است یا نه
مسیر نمونه را با پوشه واقعی و موجود جایگزین کنید:
کد / دستورfindmnt -T /var/lib/myapp
در ستون گزینهها،
ro نشاندهنده نصب فقطخواندنی و rw نشاندهنده نصب خواندن و نوشتن برای همان نمایی است که فرمان میبیند. اگر خود فایلسیستم ro شده است، نباید بدون بررسی دیسک و دلیل آن را صرفاً با تنظیم systemd نادیده گرفت. راهنمای تشخیص فایلسیستم فقطخواندنی برای این حالت مفید است.اگر فایلسیستم در ترمینال
rw است اما سرویس همچنان خطای فقطخواندنی میدهد، تنظیمات ایزوله سرویس یک احتمال است. دقت کنید سرویس ممکن است نمای متفاوتی از فایلسیستم داشته باشد؛ خروجی ترمینال بهتنهایی همه وضعیت داخل محیط سرویس را نشان نمیدهد.۳. تنظیمات مؤثر سرویس را ببینید
این فرمانها تعریف و چند ویژگی مربوط را نمایش میدهند:
کد / دستورsudo systemctl cat myapp.service
sudo systemctl show myapp.service -p User -p Group -p ProtectSystem -p ProtectHome -p ReadOnlyPaths -p ReadWritePaths -p StateDirectory
اگر
ProtectSystem=strict یا مسیری در ReadOnlyPaths فعال است، آن را با محل خطای برنامه مقایسه کنید. ProtectSystem حالتهای مختلفی دارد؛ اثر strict با مقدارهای دیگر یکسان نیست. نسخه systemd و قابلیتهای سیستم بر رفتار دقیق تأثیر دارند. خروجی تعریف سرویس ممکن است داده حساس داشته باشد، پس پیش از ارسال آن را بازبینی کنید.حساب اجرا و اجازه معمول فایل را نیز بررسی کنید:
کد / دستورls -ld /var/lib/myapp
id myappuser
نام
کد / دستورmyappuser نمونه است و باید حساب واقعی سرویس باشد. اجازه نوشتن systemd جای مجوز مالک، گروه، ACL یا سیاست SELinux را نمیگیرد. اگر خواستید دسترسی معمول حساب را از بیرون محیط سرویس بدون تغییر فایل بیازمایید:sudo -u myappuser test -w /var/lib/myapp && echo writable || echo not-writable
این نتیجه فقط دسترسی آن حساب در محیط همان فرمان را نشان میدهد، نه اینکه تمام محدودیتهای sandbox سرویس برطرف شدهاند. برای علت ACL، راهنمای مجوز مؤثر و mask را ببینید.
۴. فقط مسیر موردنیاز را انتخاب کنید
اگر مشخص شد برنامه واقعاً به نوشتن در
/var/lib/myapp نیاز دارد، آن مسیر برای داده برنامه مناسب است و فایلسیستم اصلی قابل نوشتن است، میتوانید با بررسی مدیر سرور استثنای محدودی برای همان مسیر تعریف کنید. مسیر انتخابی باید موجود باشد و به فایلهای متعلق به سرویسهای دیگر دسترسی اضافه نکند. بازکردن همه / یا غیرفعالکردن کامل ProtectSystem راهحل کمخطر و دقیقی نیست.در بعضی برنامهها
StateDirectory= روش مناسب ساخت پوشه پایدار برای همان سرویس است؛ این گزینه میتواند مسیر اختصاصی را با مالکیت مناسب ایجاد کند، اما فقط وقتی مفید است که برنامه واقعاً برای استفاده از همان مسیر تنظیم شود. تغییر آن بدون شناخت مسیر فعلی ممکن است باعث شود برنامه داده قدیمی خود را نبیند. برای سرویس نصبشده از بسته، راهنمای همان بسته را هم بخوانید.۵. یک تغییر قابل بازگشت در واحد ایجاد کنید
پیش از ویرایش، خروجی
کد / دستورsystemctl cat و محل فایلهای تکمیلی موجود را نگه دارید. با ویرایشگر systemd یک drop-in برای همین سرویس باز کنید:sudo systemctl edit myapp.service
اگر تنظیم تکمیلی از قبل دارید، آن را بیدلیل پاک نکنید. فقط در صورتی که مسیر نمونه همان مسیر تأییدشده شماست، این بخش را اضافه کنید:
کد / دستور[Service]
ReadWritePaths=/var/lib/myapp
در صورت نیاز از ویرایشگر خارج و فایل را ذخیره کنید.
ReadWritePaths مسیر را از برخی محدودیتهای فقطخواندنی systemd مستثنا میکند، اما نمیتواند یک فایلسیستم واقعاً فقطخواندنی یا مجوز ناکافی کاربر را بهتنهایی اصلاح کند. وجود مسیر، نحوه اعمال تنظیمات تکراری و جزئیات نسخه systemd را طبق مستندات همان سیستم بررسی کنید.پس از ثبت تغییر، در زمان مناسب و با دانستن اثر قطع کوتاه سرویس، تعریف و اجرا را بازخوانی و آزمایش کنید:
کد / دستورsudo systemctl daemon-reload
sudo systemctl restart myapp.service
sudo systemctl status myapp.service --no-pager
sudo journalctl -u myapp.service -b -n 60 --no-pager
اگر سرویس فعال است، یک عملیات واقعی و بیخطر انجام دهید که لازم است در همان پوشه بنویسد؛ سپس گزارش جدید و مالک فایل ایجادشده را ببینید. تنها
active شدن ثابت نمیکند نوشتن موفق بوده است.اگر خطا باقی ماند یا تغییر مناسب نبود
به مسیر دقیق خطای جدید دقت کنید؛ برنامه ممکن است علاوه بر پوشه داده، جای دیگری برای فایل موقت بخواهد. برای هر مسیر دلیل جداگانه و حداقل دسترسی را مشخص کنید. اگر خطا
Permission denied شده، مجوز حساب، ACL و گزارش سیاست امنیتی را بررسی کنید. اگر Read-only file system در ترمینال هم دیده میشود، وضعیت نصب و سلامت فایلسیستم را دنبال کنید.برای بازگشت، همان drop-in را باز کنید و فقط خطی را که در این تغییر اضافه کردهاید بردارید یا نسخه قبلی را بازگردانید؛ سپس
daemon-reload و در زمان مناسب Restart کنید. دستورهایی که همه تنظیمات تکمیلی سرویس را یکجا حذف میکنند ممکن است تغییرات ارزشمند دیگر را هم از بین ببرند. جزئیات گزینهها در مستندات systemd.exec آمده است. برای رسیدگی مداوم به چنین تنظیماتی میتوانید صفحه مدیریت سرور نتآرام را ببینید.اشتراکگذاری:
لینکدینتلگرامایکس
مقاله قبلی
مقاله قبلی وجود ندارد.
مقاله بعدی
دیدگاهها (۰)
دیدگاههای تاییدشده و پاسخهای تیم نتآرام
