رفتن به محتوا
LoopX

دسترسی‌ها: خواندن، نوشتن، اجرا

توی این درس یاد می‌گیری هر فایل و پوشه‌ی لینوکس سه دسته دسترسی دارد: برای مالک (user)، برای گروه (group) و برای بقیه (others)؛ و هر دسته سه حق: خواندن (r)، نوشتن (w) و اجرا (x). خروجی ls -l (مثل -rwxr-xr-x) را می‌خوانی، با chmod در دو شکل عددی (755) و نمادین (u+x) دسترسی را عوض می‌کنی، با chown مالک و گروه را تغییر می‌دهی، و با umask پیش‌فرض فایل‌های تازه را می‌فهمی. همه را روی چند کاربر واقعی امتحان می‌کنی تا ببینی «چه کسی چه کاری می‌تواند». تمرین: یک اسکریپت را فقط برای خودت اجرایی می‌کنی.

مسئله: همه نباید به همه‌چیز دسترسی داشته باشند

Section titled “مسئله: همه نباید به همه‌چیز دسترسی داشته باشند”

روی یک سرور مشترک، فایل رمزهای دیتابیس نباید برای همه خواندنی باشد، اسکریپت دیپلوی فقط باید توسط تیم اجرا شود و فایل‌های سایت را فقط وب‌سرور بخواند. دسترسی‌ها این قواعد را در خود فایل ثبت می‌کنند. اگر درست تنظیم نشوند، یا کسی که نباید می‌خواند/می‌نویسد (خطر امنیتی)، یا کسی که باید نمی‌تواند (خطای Permission denied که همه‌ی تازه‌کارها می‌بینند).

هر اتاق (فایل) سه نوع آدم دارد: صاحب اتاق، اعضای یک تیم مشخص و بقیه‌ی ساختمان. برای هر دسته جدا تعیین می‌کنی: «می‌تواند وارد شود و ببیند (r)، چیزی بگذارد/عوض کند (w)، یا اتاق را اجرا کند / از آن عبور کند (x)». برای پوشه‌ها (که «اتاق» هستند) این سه حق معنی کمی متفاوت دارند (در مثال ۳).

رشته‌ی ده‌کاراکتری ls -l: اولی نوع فایل، سه تا سه‌تا برای مالک، گروه و بقیه. هر r برابر ۴، w برابر ۲ و x برابر ۱ است؛ جمعشان یک رقم می‌دهد (مثلاً rwx = 7).

برای آزمایش واقعی چند کاربر لازم است. دو کاربر (bob و carol) و یک گروه (team) می‌سازیم که bob عضو آن است و carol نیست (ساختن کاربر را در درس قبل دیدی):

Terminal window
sudo useradd -m -s /bin/bash bob
sudo useradd -m -s /bin/bash carol
sudo groupadd team
sudo usermod -aG team ali
sudo usermod -aG team bob
echo "bob: $(id -Gn bob)"
echo "carol: $(id -Gn carol)"
mkdir -p /tmp/permdemo && chmod 755 /tmp/permdemo
خروجی
bob: bob team
carol: carol

یک تابع کوچک برای اجرای دستور به‌جای کاربر دیگر (sudo -u) هم می‌نویسیم تا نتیجه‌ی هر کاربر را ببینیم:

Terminal window
as() { sudo -u "$1" "${@:2}" 2>&1; }
cd /tmp/permdemo
echo "من: $(whoami)"; as bob whoami; as carol whoami
خروجی
من: ali
bob
carol
Terminal window
cd /tmp/permdemo
echo "محتوای گزارش" > report.txt
ls -l report.txt
echo "--- بخش‌ها:"
stat -c 'نوع و دسترسی: %A | عددی: %a | مالک: %U | گروه: %G | نام: %n' report.txt
خروجی
-rw-r--r-- 1 ali ali 24 Oct 3 20:29 report.txt
--- بخش‌ها:
نوع و دسترسی: -rw-r--r-- | عددی: 644 | مالک: ali | گروه: ali | نام: report.txt

رشته‌ی -rw-r--r-- ده کاراکتر است: اولی نوع (- فایل، d پوشه، l لینک)، بعد سه‌تا‌سه‌تا: مالک (rw-: بخواند و بنویسد)، گروه (r--: فقط بخواند) و بقیه (r--: فقط بخواند). بعدش مالک (ali) و گروه (ali). حالا ببین کاربرهای دیگر چه می‌توانند (فایل جدید با 644 ساخته شد، یعنی همه می‌خوانند ولی فقط مالک می‌نویسد):

Terminal window
cd /tmp/permdemo
echo "--- bob می‌خواند:"; as bob cat report.txt
echo "--- carol می‌خواند:"; as carol cat report.txt
echo "--- bob می‌نویسد:"; as bob sh -c 'echo hack >> report.txt'
خروجی
--- bob می‌خواند:
محتوای گزارش
--- carol می‌خواند:
محتوای گزارش
--- bob می‌نویسد:
sh: 1: cannot create report.txt: Permission denied

خواندن برای همه آزاد است (r برای others) ولی نوشتن فقط برای مالک: bob و carol خطای Permission denied می‌گیرند.

هر دسته یک رقم است: r=4، w=2، x=1 و جمعشان:

رقم معنی حروف
7 ۴+۲+۱ rwx
6 ۴+۲ rw-
5 ۴+۱ r-x
4 ۴ r--
0 هیچ ---

سه رقم برای (مالک، گروه، بقیه). رایج‌ترین‌ها: 644 (فایل عادی)، 755 (برنامه یا پوشه)، 600 (خصوصی)، 700 (پوشه‌ی خصوصی):

Terminal window
cd /tmp/permdemo
for m in 644 600 640 755 700; do
touch "f-$m"; chmod $m "f-$m"
done
stat -c '%a %A %n' f-* | sort
خروجی
600 -rw------- f-600
640 -rw-r----- f-640
644 -rw-r--r-- f-644
700 -rwx------ f-700
755 -rwxr-xr-x f-755

مثلاً 640 یعنی مالک rw- (۶)، گروه r-- (۴)، بقیه --- (۰): مالک می‌خواند و می‌نویسد، گروه فقط می‌خواند و بقیه هیچ. و 755: مالک همه‌چیز (۷)، گروه و بقیه بخوانند و اجرا کنند (۵).

⚡ بررسی سریع

دسترسی rw-r----- با کدام عدد نوشته می‌شود؟

مثال ۳: دسترسی روی فایل در برابر پوشه

Section titled “مثال ۳: دسترسی روی فایل در برابر پوشه”

معنی r و w و x برای دو نوع متفاوت است:

فایل پوشه
r خواندن محتوا فهرست کردن اسم‌ها (ls)
w تغییر محتوا ساختن، حذف و تغییر نام آیتم‌های داخل (به شرط x)
x اجرا به‌عنوان برنامه وارد شدن (cd) و دسترسی به آیتم‌های داخل با نام

اهمیت x روی پوشه را ببین:

Terminal window
cd /tmp/permdemo
mkdir secret && echo "داخل" > secret/file.txt
chmod 755 secret
echo "--- 755: bob فهرست و فایل را می‌بیند:"
as bob ls secret; as bob cat secret/file.txt
chmod 644 secret # r بدون x
echo "--- 644 (r بدون x): فهرست می‌شود ولی فایل قابل‌دسترسی نیست:"
as bob ls secret; as bob cat secret/file.txt
chmod 711 secret # x بدون r
echo "--- 711 (x بدون r): فهرست نه، ولی با اسم دقیق می‌شود رسید:"
as bob ls secret; as bob cat secret/file.txt
chmod 700 secret
echo "--- 700: هیچ‌چیز برای bob:"
as bob ls secret
خروجی
--- 755: bob فهرست و فایل را می‌بیند:
file.txt
داخل
--- 644 (r بدون x): فهرست می‌شود ولی فایل قابل‌دسترسی نیست:
file.txt
cat: secret/file.txt: Permission denied
--- 711 (x بدون r): فهرست نه، ولی با اسم دقیق می‌شود رسید:
ls: cannot open directory 'secret': Permission denied
داخل
--- 700: هیچ‌چیز برای bob:
ls: cannot open directory 'secret': Permission denied

r بدون x: اسم‌ها دیده می‌شوند (لیست) ولی نمی‌شود به محتوا رسید. x بدون r: نمی‌توانی فهرست بگیری ولی اگر اسم را دقیق بدانی، فایل قابل‌خواندن است (برای «پوشه‌ی تحویل» جالب است). برای کار عادی با پوشه‌ها معمولاً rx با هم لازم‌اند (755).

به‌جای عدد می‌توانی بگویی چه کسی (u/g/o/a) چه چیزی (+ اضافه، - حذف، = دقیقاً) چه حقی (r/w/x):

Terminal window
cd /tmp/permdemo
touch sym.txt; chmod 644 sym.txt
echo "شروع: $(stat -c %A sym.txt)"
chmod u+x sym.txt; echo "u+x: $(stat -c %A sym.txt)"
chmod g+w sym.txt; echo "g+w: $(stat -c %A sym.txt)"
chmod o-r sym.txt; echo "o-r: $(stat -c %A sym.txt)"
chmod a+r sym.txt; echo "a+r: $(stat -c %A sym.txt)"
chmod u=rw,g=r,o= sym.txt; echo "u=rw,g=r,o=: $(stat -c %A sym.txt)"
chmod go-rwx sym.txt; echo "go-rwx: $(stat -c %A sym.txt)"
خروجی
شروع: -rw-r--r--
u+x: -rwxr--r--
g+w: -rwxrw-r--
o-r: -rwxrw----
a+r: -rwxrw-r--
u=rw,g=r,o=: -rw-r-----
go-rwx: -rw-------

u=user، g=group، o=others، a=all (همه). + اضافه، - حذف، = مقدار دقیق (بقیه‌ی حقوق آن دسته پاک می‌شود). نمادین وقتی خوب است که فقط یک حق را عوض کنی و بقیه را دست‌نخورده بخواهی؛ عددی وقتی همه را یکجا تعیین می‌کنی.

مثال ۵: اسکریپت اجرایی (تمرین اصلی)

Section titled “مثال ۵: اسکریپت اجرایی (تمرین اصلی)”

برای اجرای یک اسکریپت با ./script.sh باید x داشته باشد:

Terminal window
cd /tmp/permdemo
printf '#!/bin/bash\necho "سلام از اسکریپت"\n' > hello.sh
ls -l hello.sh | cut -c1-10
./hello.sh
echo "--- اجرایی کردن فقط برای خودم (700):"
chmod 700 hello.sh
ls -l hello.sh | cut -c1-10
./hello.sh
echo "--- bob (دیگران) نمی‌تواند:"
as bob sh -c '/tmp/permdemo/hello.sh'
خروجی
-rw-r--r--
bash: ./hello.sh: Permission denied
--- اجرایی کردن فقط برای خودم (700):
-rwx------
سلام از اسکریپت
--- bob (دیگران) نمی‌تواند:
sh: 1: /tmp/permdemo/hello.sh: Permission denied

بدون x خطای Permission denied و بعد از chmod 700 فقط من (مالک) اجرا می‌کنم. (با bash hello.sh می‌شود بدون x هم اجرا کرد، چون آن‌جا bash فایل را می‌خواند و x لازم نیست؛ ولی r لازم است.) خط اول اسکریپت (#!/bin/bash، shebang) می‌گوید با چه مفسری اجرا شود.

مثال ۶: گروه، فایلی که فقط تیم می‌بیند

Section titled “مثال ۶: گروه، فایلی که فقط تیم می‌بیند”

سناریوی واقعی: گزارش را به گروه team بده و دسترسی 640 بگذار؛ اعضای تیم بخوانند، بقیه نه:

Terminal window
cd /tmp/permdemo
echo "گزارش محرمانه" > team-report.txt
sudo chgrp team team-report.txt
chmod 640 team-report.txt
ls -l team-report.txt
echo "--- bob (عضو team):"; as bob cat team-report.txt
echo "--- carol (غیر عضو):"; as carol cat team-report.txt
echo "--- bob می‌نویسد (گروه فقط r):"; as bob sh -c 'echo x >> /tmp/permdemo/team-report.txt'
خروجی
-rw-r----- 1 ali team 26 Oct 3 20:29 team-report.txt
--- bob (عضو team):
گزارش محرمانه
--- carol (غیر عضو):
cat: team-report.txt: Permission denied
--- bob می‌نویسد (گروه فقط r):
sh: 1: cannot create /tmp/permdemo/team-report.txt: Permission denied

bob (عضو گروه) می‌خواند ولی نمی‌نویسد، و carol هیچ‌چیز ندارد. برای اینکه تیم هم بنویسد: chmod 660 (rw-rw----).

مثال ۷: ترتیب بررسی، مالک اول است!

Section titled “مثال ۷: ترتیب بررسی، مالک اول است!”

لینوکس دسترسی را به‌ترتیب مالک ← گروه ← بقیه بررسی می‌کند و اولین دسته‌ای که تو در آن هستی را اعمال می‌کند؛ به بقیه نگاه نمی‌کند. نتیجه‌ی عجیب:

Terminal window
cd /tmp/permdemo
echo "عجیب" > odd.txt
chmod 077 odd.txt # مالک هیچ، گروه و بقیه همه‌چیز
ls -l odd.txt | cut -c1-10
echo "--- مالک (من):"; cat odd.txt
echo "--- carol (بقیه):"; as carol cat odd.txt
chmod u+rw odd.txt # برگرداندن
خروجی
----rwxrwx
--- مالک (من):
cat: odd.txt: Permission denied
--- carol (بقیه):
عجیب

مالک (من) نمی‌تواند فایل خودش را بخواند، ولی carol می‌تواند! چون سیستم مرا «مالک» می‌بیند و فقط --- مالک را اعمال می‌کند. (مالک همیشه می‌تواند با chmod دسترسی را برگرداند.) و root این قواعد را دور می‌زند و به همه‌چیز دسترسی دارد (درس root و sudo).

مثال ۸: مالکیت، chown و chgrp

Section titled “مثال ۸: مالکیت، chown و chgrp”

مالک و گروه را با chown عوض می‌کنی (به دسترسی مدیر نیاز دارد؛ کاربر عادی نمی‌تواند فایل خودش را به دیگری بدهد):

Terminal window
cd /tmp/permdemo
touch owned.txt
ls -l owned.txt | awk '{print "قبل:", $3, $4}'
sudo chown bob owned.txt; ls -l owned.txt | awk '{print "chown bob:", $3, $4}'
sudo chown bob:team owned.txt; ls -l owned.txt | awk '{print "chown bob:team:", $3, $4}'
sudo chown :ali owned.txt; ls -l owned.txt | awk '{print "chown :ali (فقط گروه):", $3, $4}'
echo "--- بدون sudo (کاربر عادی):"
chown ali owned.txt
echo "--- بازگشتی روی پوشه (-R):"
mkdir -p tree/sub && touch tree/a tree/sub/b
sudo chown -R bob:team tree
find tree | sort | while read -r f; do stat -c '%U:%G %n' "$f"; done
خروجی
قبل: ali ali
chown bob: bob ali
chown bob:team: bob team
chown :ali (فقط گروه): bob ali
--- بدون sudo (کاربر عادی):
chown: changing ownership of 'owned.txt': Operation not permitted
--- بازگشتی روی پوشه (-R):
bob:team tree
bob:team tree/a
bob:team tree/sub
bob:team tree/sub/b

شکل‌ها: chown کاربر فایل، chown کاربر:گروه فایل، chown :گروه فایل (فقط گروه، مثل chgrp). -R بازگشتی روی پوشه و همه‌ی داخلش.

مثال ۹: umask، پیش‌فرض فایل‌های جدید

Section titled “مثال ۹: umask، پیش‌فرض فایل‌های جدید”

فایل جدید با چه دسترسی‌ای ساخته می‌شود؟ umask یک «ماسک» است که از دسترسی کامل (فایل‌ها ۶۶۶، پوشه‌ها ۷۷۷) کم می‌کند:

Terminal window
cd /tmp/permdemo
echo "umask فعلی: $(umask) (نمادین: $(umask -S))"
touch u-file; mkdir u-dir
stat -c '%a %n' u-file u-dir
echo "--- umask 077 (خصوصی):"
umask 077
touch p-file; mkdir p-dir
stat -c '%a %n' p-file p-dir
echo "--- umask 002 (گروه هم بنویسد):"
umask 002
touch g-file; mkdir g-dir
stat -c '%a %n' g-file g-dir
umask 022
خروجی
umask فعلی: 0022 (نمادین: u=rwx,g=rx,o=rx)
644 u-file
755 u-dir
--- umask 077 (خصوصی):
600 p-file
700 p-dir
--- umask 002 (گروه هم بنویسد):
664 g-file
775 g-dir

با 022: فایل 666-022=644 و پوشه 777-022=755. با 077: 600 و 700 (فقط مالک)؛ با 002: 664 و 775 (گروه هم می‌نویسد، برای پروژه‌های تیمی). فایل جدید هرگز خودکار x نمی‌گیرد (برای همین ۶۶۶ پایه است). umask فقط برای همین shell و فرزندانش است؛ برای ماندگاری در ~/.bashrc بنویس.

مثال ۱۰: دیدن دسترسی‌ها در طول مسیر، namei

Section titled “مثال ۱۰: دیدن دسترسی‌ها در طول مسیر، namei”

برای رسیدن به یک فایل باید به همه‌ی پوشه‌های مسیر x داشته باشی. namei -l دسترسی هر جزء مسیر را نشان می‌دهد:

Terminal window
cd /tmp/permdemo
mkdir -p deep/dir && echo hi > deep/dir/file.txt
chmod 700 deep # بقیه حق عبور ندارند
namei -l /tmp/permdemo/deep/dir/file.txt
echo "--- carol با اینکه فایل 644 است:"
as carol cat /tmp/permdemo/deep/dir/file.txt
chmod 755 deep
echo "--- بعد از 755 روی deep:"
as carol cat /tmp/permdemo/deep/dir/file.txt
خروجی
f: /tmp/permdemo/deep/dir/file.txt
drwxr-xr-x root root /
drwxrwxrwt root root tmp
drwxr-xr-x ali ali permdemo
drwx------ ali ali deep
drwxr-xr-x ali ali dir
-rw-r--r-- ali ali file.txt
--- carol با اینکه فایل 644 است:
cat: /tmp/permdemo/deep/dir/file.txt: Permission denied
--- بعد از 755 روی deep:
hi

namei نشان می‌دهد deep (با drwx------) مسیر را می‌بندد؛ حتی با فایل خواندنی، carol نمی‌تواند عبور کند. وقتی «Permission denied» می‌بینی و فایل خودش دسترسی دارد، namei -l را بزن: معمولاً یکی از پوشه‌های بالا x ندارد.

Terminal window
sudo rm -rf /tmp/permdemo
sudo userdel -r bob 2>/dev/null; sudo userdel -r carol 2>/dev/null; sudo groupdel team
echo "پاکسازی شد"
خروجی
پاکسازی شد

پشت پرده: دسترسی کجا ذخیره می‌شود و چطور بررسی می‌شود؟

Section titled “پشت پرده: دسترسی کجا ذخیره می‌شود و چطور بررسی می‌شود؟”

دسترسی‌ها داخل inode (درس لینک‌ها) فایل ذخیره می‌شوند: ۹ بیت rwx (سه گروه سه‌تایی)، به‌همراه UID مالک و GID گروه. هر بار که یک پروسه فایلی را باز می‌کند، هسته UID/GID های پروسه (درس کاربرها) را با مالک/گروه فایل مقایسه می‌کند: اگر UID پروسه با مالک برابر بود، فقط بیت‌های مالک را می‌سنجد؛ وگرنه اگر گروه پروسه (اصلی یا اضافی) با گروه فایل برابر بود، بیت‌های گروه؛ و در غیر این صورت بیت‌های others. root (UID 0) این بررسی را دور می‌زند (با capability ها، درس‌های بعد).

برای تغییر دسترسی باید مالک فایل (یا root) باشی؛ مالک بودن یعنی اختیار تغییر دسترسی، نه لزوماً داشتن دسترسی خواندن. chmod فقط inode را عوض می‌کند، پس همه‌ی لینک‌های سخت (hard link) به آن inode هم فوراً دسترسی جدید را می‌بینند؛ و chmod روی symlink روی مقصد اثر می‌گذارد. دسترسی‌های پیچیده‌تر (برای کاربران خاص بدون گروه‌سازی) را ACL (setfacl/getfacl) فراهم می‌کند که فراتر از این درس است.

دستور کار
ls -l نمایش دسترسی‌ها
ls -ld پوشه دسترسی خود پوشه
stat -c '%a %A %U:%G %n' f دسترسی عددی/نمادین و مالک
chmod 644 f عددی
chmod u+x f نمادین (افزودن اجرا برای مالک)
chmod -R 755 dir بازگشتی
chmod u=rw,g=r,o= f تعیین دقیق
chown user:group f مالک و گروه (نیاز به sudo)
chgrp group f فقط گروه
umask / umask 077 دیدن/تعیین ماسک
namei -l مسیر دسترسی همه‌ی اجزای مسیر
عدد نماد کاربرد رایج
644 rw-r–r– فایل عادی
600 rw—–– فایل خصوصی (.env، کلید)
755 rwxr-xr-x برنامه، پوشه‌ی عمومی
700 rwx—— پوشه‌ی خصوصی (~/.ssh)
640 rw-r—– خواندنی برای گروه
664 / 775 rw-rw-r– / rwxrwxr-x پروژه‌ی تیمی (با umask 002)
777 rwxrwxrwx هرگز (همه‌چیز برای همه)

۱) chmod 777 برای رفع «Permission denied»

Section titled “۱) chmod 777 برای رفع «Permission denied»”

دسترسی ۷۷۷ مشکل را «حل» می‌کند ولی هر کاربر یا برنامه‌ی دیگری (حتی مهاجم) می‌تواند فایل را بخواند، بنویسد و اجرا کند. راه‌حل: علت واقعی را پیدا کن (مالک/گروه اشتباه، x روی پوشه)، و حداقل دسترسی لازم را بده.

۲) فراموش کردن x روی پوشه

Section titled “۲) فراموش کردن x روی پوشه”

مثال ۳ و ۱۰: بدون x روی پوشه‌ها به محتوا نمی‌رسی. راه‌حل: namei -l، و برای پوشه‌ها 755 یا 750.

۳) chmod -R 644 که پوشه‌ها را بی‌x می‌کند

Section titled “۳) chmod -R 644 که پوشه‌ها را بی‌x می‌کند”
Terminal window
mkdir -p /tmp/m3/sub && echo hi > /tmp/m3/sub/f
chmod -R 644 /tmp/m3
ls /tmp/m3/sub 2>&1 | head -1
cat /tmp/m3/sub/f 2>&1 | head -1
chmod -R u+rwX /tmp/m3 && rm -rf /tmp/m3
خروجی
chmod: cannot access '/tmp/m3/sub': Permission denied
ls: cannot access '/tmp/m3/sub': Permission denied
cat: /tmp/m3/sub/f: Permission denied

-R 644 به پوشه‌ها هم x را برداشت و دیگر نمی‌توانی داخلشان بروی (حتی مالک). راه‌حل: chmod -R u=rwX,go=rX (X بزرگ: x را فقط به پوشه‌ها و فایل‌های از قبل اجرایی می‌دهد)، یا جدا برای فایل‌ها و پوشه‌ها با find -type f -exec chmod 644 {} +.

۴) ذخیره‌ی رمز در فایل با دسترسی باز

Section titled “۴) ذخیره‌ی رمز در فایل با دسترسی باز”

فایل .env یا کلید خصوصی با 644 برای همه خواندنی است. راه‌حل: chmod 600 (و ssh اصلاً کلید خصوصی بازتر از 600 را قبول نمی‌کند: درس SSH).

۵) ساختن فایل با sudo در پوشه‌ی خودت

Section titled “۵) ساختن فایل با sudo در پوشه‌ی خودت”

وقتی با sudo فایلی در پوشه‌ی خودت می‌سازی (یا sudo git clone، sudo npm install می‌زنی)، مالک آن root می‌شود و بعد خودت نمی‌توانی ویرایشش کنی:

Terminal window
mkdir -p /tmp/m5 && cd /tmp/m5
sudo touch config.txt
ls -l config.txt
echo "تنظیم جدید" >> config.txt
echo "--- راه‌حل: برگرداندن مالکیت به خودم"
sudo chown "$(id -un):$(id -gn)" config.txt
ls -l config.txt
echo "تنظیم جدید" >> config.txt && echo "حالا می‌نویسم"
cd / && rm -rf /tmp/m5
خروجی
-rw-r--r-- 1 root root 0 Oct 3 20:29 config.txt
bash: config.txt: Permission denied
--- راه‌حل: برگرداندن مالکیت به خودم
-rw-r--r-- 1 ali ali 0 Oct 3 20:29 config.txt
حالا می‌نویسم

راه‌حل: sudo chown "$(id -un):$(id -gn)" فایل (یا با -R برای پوشه) و از این به بعد فقط دستورهایی را با sudo بزن که واقعاً لازم‌اند. و برعکس: chown -R یا chmod -R را هرگز روی /، ~ یا /etc بی‌دقت نزن؛ مسیر را قبلش با pwd و ls ببین، چون سیستم را خراب می‌کند.

✎ تمرینآسان

یک فایل بساز و دسترسی‌اش را به 640 تغییر بده؛ با ls -l و stat نشان بده مالک چه می‌تواند، گروه چه و بقیه چه.

دیدن جواب
Terminal window
touch mine.txt && chmod 640 mine.txt
ls -l mine.txt
stat -c 'عددی=%a نمادین=%A' mine.txt
echo "مالک: rw (خواندن و نوشتن) | گروه: r (فقط خواندن) | بقیه: هیچ"
خروجی
-rw-r----- 1 ali ali 0 Oct 3 20:29 mine.txt
عددی=640 نمادین=-rw-r-----
مالک: rw (خواندن و نوشتن) | گروه: r (فقط خواندن) | بقیه: هیچ
✎ تمرینمتوسط

تمرین اصلی: یک اسکریپت را فقط برای خودت قابل اجرا کن. اسکریپت backup.sh را بساز که یک پیام چاپ کند، ابتدا ثابت کن بدون x اجرا نمی‌شود، بعد با chmod طوری تنظیمش کن که فقط مالک بتواند بخواند، بنویسد و اجرا کند (و دیگران هیچ حقی نداشته باشند)، و اجرایش کن.

دیدن جواب
Terminal window
printf '#!/bin/bash\necho "بکاپ انجام شد"\n' > backup.sh
./backup.sh
chmod 700 backup.sh
ls -l backup.sh | cut -c1-10
./backup.sh
خروجی
bash: ./backup.sh: Permission denied
-rwx------
بکاپ انجام شد

700 یعنی rwx------: فقط مالک. (معادل نمادین: chmod u=rwx,go= backup.sh.)

✎ تمرینسخت

یک پوشه‌ی مشترک تیمی بساز که اعضای گروه team بتوانند فایل بسازند و بخوانند ولی «بقیه» هیچ دسترسی نداشته باشند: پوشه را به گروه بده، chmod 770 بگذار، و با دو کاربر (یکی عضو، یکی غیر عضو) آزمایش کن. (کاربرها را بساز و در پایان پاک کن. نکته‌ی فایل‌های جدید: فعلاً گروه فایل‌ها گروه اصلی سازنده است؛ در درس دسترسی‌های ویژه (setgid) درست می‌شود.)

دیدن جواب
Terminal window
sudo useradd -m -s /bin/bash bob; sudo useradd -m -s /bin/bash carol
sudo groupadd team; sudo usermod -aG team bob
sudo mkdir /srv/teamdir && sudo chgrp team /srv/teamdir && sudo chmod 770 /srv/teamdir
stat -c '%A %U:%G %n' /srv/teamdir
echo "--- bob (عضو) می‌نویسد:"; sudo -u bob sh -c 'echo "یادداشت bob" > /srv/teamdir/note.txt && echo موفق' 2>&1
echo "--- carol (غیر عضو) می‌خواهد ببیند:"; sudo -u carol ls /srv/teamdir 2>&1
sudo rm -rf /srv/teamdir; sudo userdel -r bob 2>/dev/null; sudo userdel -r carol 2>/dev/null; sudo groupdel team
خروجی
drwxrwx--- root:team /srv/teamdir
--- bob (عضو) می‌نویسد:
موفق
--- carol (غیر عضو) می‌خواهد ببیند:
ls: cannot open directory '/srv/teamdir': Permission denied
؟ آزمونک
  1. دسترسی rw-r----- چه عددی است؟

  2. x روی یک پوشه چه معنی دارد؟

  3. برای اضافه کردن حق اجرا فقط برای مالک؟

  4. umask 022 به فایل جدید چه دسترسی‌ای می‌دهد؟

  5. اگر مالک فایل دسترسی --- و بقیه rwx داشته باشند، مالک می‌تواند فایل را بخواند؟

  6. کدام دستور مالک و گروه را تغییر می‌دهد؟

  • دسترسی هر فایل: مالک (u)، گروه (g)، بقیه (o) × r (۴)، w (۲)، x (۱)؛ -rwxr-xr-x = 755.
  • برای پوشه‌ها: r فهرست، w ساختن/حذف آیتم‌ها، x ورود و عبور (برای رسیدن به فایل، x روی همه‌ی پوشه‌های مسیر لازم است؛ namei -l).
  • chmod 644/755/600/700 (عددی) یا u+x، go-rwx، u=rw,g=r,o= (نمادین)؛ -R را با دقت (و X بزرگ) به کار ببر.
  • chown user:group و chgrp (نیاز به sudo)؛ بررسی دسترسی به ترتیب مالک ← گروه ← بقیه و اولین دسته‌ی منطبق اعمال می‌شود؛ root دور می‌زند.
  • umask از ۶۶۶ (فایل) و ۷۷۷ (پوشه) کم می‌کند؛ 022 → 644/755.
  • chmod 777 راه‌حل نیست؛ حداقل دسترسی لازم را بده (اصل کمترین دسترسی).
برگه‌ی تقلب این درس
دستورکاری که می‌کند
ls -l / ls -ld dirدیدن دسترسی‌ها
stat -c "%a %A %U:%G %n" fدسترسی عددی، نمادین و مالک
chmod 644 f / chmod 755 fفایل عادی / برنامه
chmod 600 f / chmod 700 dخصوصی
chmod u+x fاجرایی کردن برای مالک
chmod go-rwx fگرفتن همه‌ی حق‌ها از گروه و بقیه
chmod -R u=rwX,go=rX dirبازگشتی بدون خراب کردن x پوشه‌ها
sudo chown user:group fتغییر مالک و گروه
sudo chown -R user:group dirبازگشتی
umask / umask 077دیدن / تعیین ماسک
namei -l /path/to/fileدسترسی همه‌ی اجزای مسیر
sudo -u user cmdاجرا با هویت کاربر دیگر (برای آزمایش)