مجوزهای فایل در لینوکس؛ خواندن، نوشتن و اجرا
مدل مجوز یونیکسی: بیتهای rwx برای owner/group/others، معنی روی فایل و دایرکتوری، umask، و اشتباههای Permission denied — با man inode و credentials.
بنیانگذار و مهندس محصول

وقتی لینوکس میگوید Permission denied، معمولاً یکی از اینها را رد کرده: هویت شما (کاربر/گروه)، بیتهای مجوز فایل یا دایرکتوری، یا لایهٔ MAC مثل SELinux/AppArmor. این مقاله روی مدل کلاسیک یونیکسی تمرکز میکند: برای هر فایل، مالک (owner)، گروه (group) و دیگران (others) هر کدام سه بیت خواندن، نوشتن و اجرا دارند. بدون فهم فرق این بیتها روی فایل در برابر دایرکتوری، اعداد chmod مثل ورد جادویی میمانند.
صفحات man مربوط به inode(7) و credentials(7) مدل را دقیق توضیح میدهند. chmod و chown ابزار تغییرند و در مقالات ۱۴۸ و ۱۴۹ جدا میآیند؛ اینجا اول معنی را میسازیم تا آن ابزارها را درست به کار ببرید.
مدل ساده است ولی گوشههایش — بیتهای خاص، umask، دایرکتوری بدون x — منبع بیشتر خطاهای روزمرهٔ استقرار وب و CI است.

پاسخ کوتاه
هر فایل و دایرکتوری یک مالک و یک گروه دارد و نه بیت مجوز رایج: rwx برای مالک، rwx برای گروه، rwx برای دیگران. روی فایل، r خواندن محتوا، w تغییر محتوا، x اجرا بهعنوان برنامه/اسکریپت است. روی دایرکتوری، r لیست نامها، w ایجاد/حذف ورودی، x اجازهٔ عبور (traverse) و دسترسی به inode داخلی است. بدون x روی دایرکتوری، حتی اگر فایل داخل قابلخواندن باشد، ممکن است نتوانید به آن برسید. حداقل دسترسی لازم را بدهید؛ ۷۷۷ راه فرار است نه طراحی.
Permission denied اول یک پیام آموزشی است: بپرسید «کدام کاربر، کدام مسیر، کدام بیت؟» نه اینکه فوراً sudo و ۷۷۷ بزنید.
دیدن مجوزها
bash
ls -l /etc/passwd # مثال: -rw-r--r-- 1 root root ... namei -l /var/www/myapp/index.html
خروجی ls -l نوع فایل را در کاراکتر اول نشان میدهد (- فایل عادی، d دایرکتوری، l لینک). نه کاراکتر بعدی همان rwx سه三段 است. namei مسیر را قطعه به قطعه نشان میدهد — برای فهم اینکه کدام پوشهٔ والد x ندارد طلایی است.
معنی rwx روی فایل
- r: خواندن بایتهای فایل (دیدن محتوا).
- w: تغییر محتوا یا کوتاه کردن فایل.
- x: اجازهٔ اجرا؛ برای اسکریپت معمولاً همراه با shebang و خواندن لازم است.
فایل تنظیمات معمولاً به اجرا نیاز ندارد. کلید خصوصی SSH باید برای دیگران غیرقابلخواندن باشد؛ در غیر این صورت OpenSSH ممکن است کلید را رد کند.
معنی rwx روی دایرکتوری
- r: دیدن فهرست نام ورودیها (ls).
- w: ایجاد، حذف، یا تغییر نام ورودیها داخل آن دایرکتوری.
- x: ورود به دایرکتوری و دسترسی به متادیتای فایلهای داخل با دانستن نام.
الگوی رایج اشتباه: به فایل داخل ۶۴۴ میدهید ولی پوشهٔ والد برای کاربر سرویس x ندارد. یا برعکس، پوشه ۷۷۷ است و هر کسی میتواند فایل شما را پاک کند چون w روی دایرکتوری مال حذف نام است نه فقط نوشتن محتوا.
مالک، گروه، others و ترتیب تصمیم
هسته معمولاً اینطور تصمیم میگیرد: اگر uid شما مالک است، بیتهای owner اعمال میشود؛ وگرنه اگر یکی از گروههای مؤثر شما با گروه فایل یکی است، بیتهای group؛ وگرنه others. جزئیات credentials و گروههای مکمل در man آمده است. عضو گروه بودن بدون بیت گروه مناسب کافی نیست؛ و مالک بودن یعنی بیت others برای شما ملاک نیست.
سرویسها را با کاربر جدا اجرا کنید و مالکیت درخت داده را به همان کاربر بدهید. اجرای همه چیز با root «برای رد شدن از مجوز» مدل امنیت را نابود میکند.
umask: مجوز پیشفرض فایل جدید
وقتی فایل میسازید، umask بیتهایی را از مجوز پیشفرض کم میکند. مقدار رایج ۰۲۲ باعث میشود فایلها معمولاً ۶۴۴ و دایرکتوریها ۷۵۵ شوند. در محیطهای اشتراکی گاهی umask سختگیرانهتر میخواهید. umask را در اسکریپتهای حساس صریح کنید تا به محیط تعاملی وابسته نباشید.
bash
umask umask 027 touch /tmp/a && mkdir /tmp/b ls -ld /tmp/a /tmp/b
بیتهای خاص: setuid، setgid، sticky
setuid روی اجراپذیر میتواند فرایند را با مالک فایل بالا بیاورد — قدرتمند و خطرناک. setgid روی دایرکتوری میتواند گروه پیشفرض فایلهای جدید را ثابت نگه دارد؛ برای درخت تیمی مفید است. sticky روی /tmp معروف است: فقط مالک فایل (و root) بتواند فایل را حذف کند حتی اگر دیگران روی دایرکتوری w داشته باشند. قبل از روشن کردن setuid، تهدید را بفهمید.
جدول الگوهای رایج
| موقعیت | الگوی رایج | توضیح |
|---|---|---|
| فایل کانفیگ | 640 یا 600 | بسته به خواندن گروهی |
| اسکریپت | 755 یا 750 | اجرای مالک/گروه |
| کلید خصوصی | 600 | others صفر |
| دایرکتوری اپ | 755 یا 750 | traverse کنترلشده |
| /tmp | 1777 | sticky + باز |
| Secret env | 600 مالک سرویس | نه world-readable |
لایهٔ MAC را فراموش نکنید
اگر بیتها درستاند ولی هنوز denied میبینید، AppArmor یا SELinux را بررسی کنید. خاموش کردن کامل آنها برای «راهافتادن» بدهی امنیتی است؛ سیاست را درست کنید یا در محیط dev مستند انحراف بدهید.
مسیر عیبیابی Permission denied
- کدام کاربر؟ whoami؛ هویت سرویس در واحد systemd.
- کدام مسیر مطلق؟ pwd و readlink -f.
- namei -l روی مسیر برای دیدن قطعهٔ مشکل.
- ls -l روی فایل و همهٔ والدین.
- گروهها: id.
- در صورت نیاز: لاگ MAC.
اشتباههای رایج
- chmod 777 -R روی درخت وب.
- یکیگرفتن نوشتن فایل با نوشتن دایرکتوری.
- اجرای سرویس بهعنوان root برای دور زدن مجوز.
- فراموش کردن x روی دایرکتوریهای میانی.
- کپی فایل از ویندوز و تعجب از نبود بیت اجرا.
سوالات متداول
چرا فایل را میبینم ولی cat خطا میدهد؟
ممکن است r روی فایل نباشد، یا x روی یکی از والدین نباشد، یا MAC دخالت کند.
آیا ACL لازم است؟
برای موارد پیچیده بله (getfacl/setfacl). برای بیشتر اپهای کوچک، مالک/گروه/others کافی است اگر گروهبندی درست باشد.
لینک نمادین چه مجوزی دارد؟
معمولاً دسترسی به هدف مهم است؛ مجوز خود لینک در عمل کمتر تعیینکننده است. هدف و والدین را چک کنید.
۷۵۵ یعنی چه؟
مالک rwx، گروه r-x، others r-x. جزئیات تغییر با chmod در ۱۴۸.
آیا root همیشه عبور میکند؟
برای مجوزهای کلاسیک عملاً بله، ولی MAC و قابلیتهای هسته میتوانند محدودیت بگذارند. باز هم کار روزمره با root توصیه نمیشود.
مجوز در استقرار وب و CI
در استقرار وب، کاربر وبسرور یا کاربر runtime اپ فقط باید به مسیرهایی که لازم دارد دسترسی داشته باشد. پوشهٔ آپلود جدا با مجوز نوشتن محدود، کد فقطخواندنی برای آن کاربر، و Secret خارج از document root. در CI، runner با هویت جدا اجرا میشود؛ فرض نکنید همان مجوز لپتاپ شما را دارد.
کانتینر مجوز را داخل فضای نام خود دارد ولی وقتی volume به میزبان bind میشود، uid عددی روی میزبان مهم میشود. ناهماهنگی uid بین Image و میزبان یکی از دلایل شایع denied روی volume است — در مستند Image کاربر را مشخص کنید یا با chown کنترلشده در entrypoint (با احتیاط) هماهنگ کنید.
تمرین آزمایشگاهی امن
روی یک VM آزمایشی، کاربر دوم بسازید، پوشهای با مالک خودتان درست کنید، بیتها را یکییکی کم کنید و با su - otheruser اثر را ببینید. عمداً x والد را بردارید تا namei را حس کنید. این ۳۰ دقیقه بیشتر از خواندن ۱۰ چیتشیت میارزد.
bash
mkdir -p /tmp/perm-lab/sub echo hi > /tmp/perm-lab/sub/file.txt chmod 644 /tmp/perm-lab/sub/file.txt chmod 711 /tmp/perm-lab chmod 700 /tmp/perm-lab/sub namei -l /tmp/perm-lab/sub/file.txt
چرا مدل یونیکسی هنوز پایه است؟
با وجود قابلیتهای جدیدتر مثل ACLهای غنی، قابلیتهای هسته، و فضاهای نام کانتینر، مدل owner/group/others همچنان زبان مشترک عیبیابی روی تقریباً هر سرور لینوکسی است. وقتی همکار شما در نیمهشب فقط به SSH و ls -l دسترسی دارد، همین نه بیت و دو شناسهٔ مالکیت اولین سیگنال را میدهد. یادگیری عمیق ACL مفید است، ولی جایگزینی برای تسلط روی rwx نیست.
در محیطهای ابری، Image آماده ممکن است کاربر غیرroot پیشفرض داشته باشد. اگر حجم را با مالک root روی میزبان بسازید و به کانتینر mount کنید، همان مدل کلاسیک باعث denied میشود. یعنی حتی در کوبرنتیز، فهم مجوز یونیکسی همچنان روزمره است؛ فقط لایهٔ ارکستراسیون روی آن نشسته است.
سازمانهایی که همه چیز را با root و ۷۷۷ «درست» میکنند، در اولین ممیزی امنیت یا اولین نفوذ از طریق اپ آسیبپذیر، هزینه را یکجا میپردازند. حداقل دسترسی در مجوز فایل ارزانترین کنترل شروع است.
تفکیک مسئولیت: اپ، وبسرور، دپلوی
در پشتهٔ رایج Nginx + اپ + دیتابیس، سه هویت جدا دارید. Nginx باید فایلهای استاتیک را بخواند، اپ باید به سوکت یا پورت و به پوشهٔ آپلود بنویسد، و دیتابیس فقط به دادهٔ خودش. اگر هر سه با یک کاربر و یک درخت ۷۷۷ اجرا شوند، نفوذ به اپ یعنی نفوذ به همه. جداسازی کاربر و مجوز، شعاع انفجار را کم میکند.
کاربر دپلوی (که از CI با SSH میآید) باید حق بهروزرسانی آرتیفکت را داشته باشد، نه لزوماً حق خواندن Secret زمان اجرا یا حق نوشتن در دادهٔ دیتابیس. این تفکیک با گروههای مکمل و بیتهای دقیق روی مسیرها پیاده میشود، نه با یک sudoers باز.
روی سیستمهای کوچک تککاربره آموزشی میتوان سادهتر بود؛ همین مقاله برای زمانی است که سرویس واقعی به اینترنت وصل است یا چند نفر به یک میزبان دسترسی دارند.
چکلیست قبل از باز کردن دسترسی
قبل از گشاد کردن مجوز، این سوالها را جواب دهید: کدام فرایند با کدام uid اجرا میشود؟ آیا مسیر داخل document root است؟ آیا فایل Secret است؟ آیا والدها x دارند؟ آیا umask در واحد systemd تنظیم شده؟ آیا MAC چیزی را بلاک کرده؟ اگر نتوانستید uid را بگویید، هنوز برای chmod آماده نیستید.
بعد از تغییر، با همان کاربر سرویس تست کنید: sudo -u myservice test -r /path && echo ok. تست با root دروغ میگوید چون root معمولاً عبور میکند. این یک خط ساده بسیاری از «روی سرور کار میکند» های دروغین را فاش میکند.
تغییرات مجوز را در Ansible یا اسکریپت deploy ثبت کنید تا سرور بعدی همان حالت را بگیرد. مجوز دستی روی یک VPS بدون IaC، در اولین بازسازی از بین میرود و عیبیابی از نو شروع میشود.
در نهایت، مجوز خوب مثل کد تمیز است: خوانا، حداقلی، و قابل توضیح برای نفر بعدی. اگر نتوانید در یک جمله بگویید چرا others روی این فایل r دارد، احتمالاً باید آن بیت را بردارید.
خلاصه
مجوز لینوکس مدل owner/group/others با rwx است و معنی بیتها روی دایرکتوری با فایل فرق دارد. umask پیشفرض میسازد؛ بیتهای خاص سناریوهای ویژه. عیبیابی را از هویت و مسیر شروع کنید نه از ۷۷۷. قدم بعد: تغییر امن با chmod و مالکیت با chown.
منابع و مراجع
- man7.org — inode(7) — https://man7.org/linux/man-pages/man7/inode.7.html
- man7.org — credentials(7) — https://man7.org/linux/man-pages/man7/credentials.7.html
- man7.org — chmod(1) — https://man7.org/linux/man-pages/man1/chmod.1.html
- man7.org — umask(2) — https://man7.org/linux/man-pages/man2/umask.2.html
- Ubuntu manpages chmod — https://manpages.ubuntu.com/manpages/noble/en/man1/chmod.1.html
نویسنده
سهیل ابراهیمپور بنیانگذار FutureForge است. روی طراحی محصول، معماری و استقرار نرمافزار سفارشی کار میکند.
یادداشتهای مرتبط
اگر در انتخاب معماری یا مسیر توسعه مطمئن نیستید، میتوانید درباره پروژه صحبت کنیم.
مسئله و محدودیت را بنویسید. اگر تطابق داشته باشیم، برای گفتگو هماهنگ میکنیم.




