۳. کاربران، گروهها و مجوزها¶
کنترل دسترسی پایهٔ امنیت لینوکس است. اصل راهنما: حداقل دسترسی لازم (Least Privilege) برای هر کاربر و هر سرویس.
راهنمای سریع¶
| فرمان | کاربرد | ریسک |
|---|---|---|
id / whoami / getent passwd USER |
شناسایی کاربر | بدون تغییر |
last / lastlog / sudo lastb |
تاریخچهٔ ورود | بدون تغییر |
sudo -l -U USER |
مجوزهای sudo یک کاربر | بدون تغییر |
useradd / adduser / usermod |
ساخت و تغییر حساب | تغییر |
passwd -l / usermod -L / chage -E 0 |
قفل / منقضیکردن حساب | تغییر |
visudo |
ویرایش sudoers با اعتبارسنجی | تغییر (اشتباه = قفل شدن از sudo) |
userdel -r |
حذف حساب و پوشهٔ خانگی | مخرب |
setfacl / chown -R / chmod -R |
ACL و مجوز بازگشتی | تغییر |
شناسایی کاربران¶
whoami
id USER
getent passwd USER
getent group sudo # RHEL: getent group wheel
getent passwd | less
last -n 20
lastlog | head
loginctl list-sessions # نشستهای فعال (systemd)
getent از پایگاههای پیکربندیشده سیستم (از جمله LDAP/SSSD در صورت تنظیم) پرسوجو میکند؛ معمولاً از خواندن مستقیم /etc/passwd جامعتر است.
ایجاد و مدیریت حساب¶
# Debian/Ubuntu (تعاملی)
sudo adduser appuser
# هر توزیع (غیرتعاملی)
sudo useradd -m -s /bin/bash -c "نام کامل" appuser
sudo passwd appuser
sudo usermod -aG GROUP appuser # افزودن به گروه (بدون -a گروههای دیگر پاک میشود!)
sudo gpasswd -d appuser GROUP # حذف از یک گروه
sudo usermod -s /bin/bash appuser
sudo chage -l appuser # سیاست انقضای رمز
usermod -aG: افزودن به گروه بدون حذف گروههای فعلی؛ حذف-aعضویتهای دیگر را از بین میبرد.- گروه مدیران: Debian/Ubuntu →
sudo؛ RHEL/Rocky →wheel. - اعمال عضویت جدید گروه نیاز به ورود دوباره کاربر دارد (
idدر نشست جاری عوض نمیشود).
عضویت در گروه docker = دسترسی root
هر کسی که عضو گروه docker باشد میتواند با docker run -v /:/host ... کل سیستم را بخواند و بنویسد؛ این معادل root بدون sudo و بدون لاگ sudo است. این گروه را مثل sudo مدیریت کنید (Docker).
حساب سرویس (Service account)¶
# بدون شل ورودی، بدون پوشهٔ خانگی، UID سیستمی
sudo useradd --system --no-create-home --shell /usr/sbin/nologin svc-myapp
sudo install -d -o svc-myapp -g svc-myapp -m 750 /var/lib/myapp
- هر سرویس حساب جدا داشته باشد؛ هیچ سرویسی بهعنوان root اجرا نشود مگر دلیل مستند.
- حساب سرویس رمز ندارد و نباید ورود SSH داشته باشد (
nologin+ نبودauthorized_keys).
غیرفعالسازی و حذف¶
sudo passwd -l appuser # قفل رمز (SSH با کلید همچنان ممکن است!)
sudo usermod -L -e 1 appuser # قفل رمز + منقضیکردن حساب (امنتر)
sudo chage -E 0 appuser # منقضی فوری
sudo pkill -KILL -u appuser # قطع همهٔ پردازشهای او (با احتیاط)
sudo loginctl terminate-user appuser
# قبل از حذف: بکاپ و فایلهای متعلق به او
sudo tar -czf /root/appuser-home-$(date +%F).tgz -C /home appuser
sudo find / -xdev -user appuser -ls 2>/dev/null | head
sudo userdel appuser # حساب را حذف میکند، پوشه را نگه میدارد
sudo userdel -r appuser # حساب + پوشهٔ خانگی (مخرب)
قفلکردن گذرواژه الزاماً حساب را از تمام روشهای ورود غیرفعال نمیکند؛ کلید SSH (~/.ssh/authorized_keys)، توکنها و cron/at باقی میمانند. هنگام خروج کارمند: حساب را منقضی کنید، authorized_keys را بررسی/حذف کنید، cron او را ببینید، سپس بعد از دورهٔ نگهداری حذف کنید.
مجوزهای فایل¶
مجوزهای rwx برای مالک (u)، گروه (g) و دیگران (o) تعریف میشوند.
| عدد | نماد | کاربرد معمول |
|---|---|---|
600 |
rw------- |
کلید خصوصی، فایل رمز، .env |
640 |
rw-r----- |
فایل پیکربندی قابلخواندن برای گروه سرویس |
644 |
rw-r--r-- |
فایل عمومی خواندنی |
700 |
rwx------ |
پوشهٔ خصوصی (~/.ssh) |
750 |
rwxr-x--- |
پوشهٔ سرویس با دسترسی گروه |
755 |
rwxr-xr-x |
مسیر قابلپیمایش / اسکریپت عمومی |
ls -l
chmod 600 ~/.ssh/id_ed25519
chmod 700 ~/.ssh
chmod 640 /etc/myapp/app.conf
chown root:root /etc/myapp/app.conf
namei -l /var/www/html/index.php # مجوز همهٔ اجزای مسیر (علت رایج Permission denied)
برای پوشهها x یعنی «اجازهٔ عبور». بدون x روی همهٔ پوشههای والد، فایلی که خودش 644 است هم خوانده نمیشود.
بیتهای ویژه و umask¶
| بیت | عدد | اثر | مثال |
|---|---|---|---|
| setuid | 4000 |
فایل با مجوز مالک اجرا میشود | /usr/bin/passwd |
| setgid | 2000 |
روی پوشه: فایلهای جدید گروه پوشه را میگیرند | پوشهٔ مشترک تیم |
| sticky | 1000 |
روی پوشه: فقط مالک فایل میتواند حذفش کند | /tmp (1777) |
sudo chmod 2775 /srv/shared # setgid: گروه پوشه به فایلهای جدید ارث میرسد
sudo chmod +t /srv/dropbox
umask # پیشفرض ساخت: 022 → فایل 644، پوشه 755
umask 027 # برای این نشست؛ فایل 640، پوشه 750
ACL¶
وقتی «مالک/گروه/دیگران» کافی نیست (مثلاً یک کاربر مشخص فقط یک فایل را بخواند):
getfacl /srv/shared
sudo setfacl -m u:reporter:r-- /srv/shared/report.csv
sudo setfacl -m u:reporter:rwx /srv/shared/reports
sudo setfacl -d -m g:team:rwX /srv/shared/reports # پیشفرض برای فایلهای جدید آینده
sudo setfacl -x u:reporter /srv/shared/report.csv # حذف یک ورودی
sudo setfacl -b /srv/shared/report.csv # حذف همهٔ ACL ها
getfacl -R /srv/shared | less
برای عبور از مسیر، دایرکتوریهای والد نیز باید مجوز x مناسب داشته باشند. وجود ACL با + انتهای ls -l (مثل -rw-r--r--+) دیده میشود؛ آن را نادیده نگیرید.
sudo و امنیت حساب¶
sudo visudo # ویرایش اصلی با اعتبارسنجی
sudo visudo -f /etc/sudoers.d/90-appteam # ترجیحاً فایل جدا (drop-in)
sudo visudo -c # فقط بررسی نحو همهٔ فایلها
sudo -l -U appuser
نمونهٔ drop-in حداقلی (فقط restart یک سرویس، بدون رمز):
# /etc/sudoers.d/90-appteam (مجوز باید 0440 و مالک root باشد)
%appteam ALL=(root) NOPASSWD: /usr/bin/systemctl restart myapp, /usr/bin/systemctl status myapp
- فرمانها را با مسیر کامل و آرگومان دقیق مجاز کنید؛
NOPASSWD: ALLیا مجوز shell/editor (vim،less،find،docker) معادل root است. - فایلهای
/etc/sudoers.dبا نام دارای.یا~نادیده گرفته میشوند (نگاه کنیدsudo -lواقعاً آن را میبیند). - هرگز
/etc/sudoersرا با ویرایشگر معمولی باز نکنید؛ یک خطای نحوی کل sudo را از کار میاندازد. - لاگ sudo:
/var/log/auth.log(Debian) //var/log/secure(RHEL) /journalctl _COMM=sudo.
سیاست رمز و قفل خودکار¶
sudo chage -M 90 -m 1 -W 14 appuser # حداکثر 90 روز، هشدار 14 روز قبل
sudo chage -l appuser
# قفل بعد از تلاش ناموفق (RHEL / pam_faillock)
sudo faillock --user appuser
sudo faillock --user appuser --reset
ممیزی حسابها (دورهای)¶
# فقط یک حساب باید UID 0 داشته باشد
awk -F: '$3 == 0 {print $1}' /etc/passwd
# حسابهای بدون رمز
sudo awk -F: '($2 == "") {print $1}' /etc/shadow
# حسابهای دارای شل ورودی
grep -vE '(nologin|false)$' /etc/passwd
# اعضای گروههای قدرتمند
getent group sudo wheel docker adm 2>/dev/null
# کلیدهای SSH مجاز همهٔ کاربران (شناسایی کلید ناشناس)
sudo find /home /root -name authorized_keys -exec sh -c 'echo "== $1"; cat "$1"' _ {} \;
# فایلهای یتیم
sudo find / -xdev \( -nouser -o -nogroup \) -ls 2>/dev/null | head
خطاهای رایج¶
| نشانه | علت احتمالی | روش بررسی |
|---|---|---|
| عضویت گروه جدید اثر ندارد | نشست قدیمی است | خروج و ورود دوباره؛ id |
sudo: unable to resolve host |
نام میزبان در /etc/hosts نیست |
hostnamectl و /etc/hosts |
| بعد از ویرایش sudoers، sudo کار نمیکند | خطای نحو | pkexec visudo یا کنسول/ریکاوری؛ دفعهٔ بعد visudo -c |
| کاربر قفل است ولی هنوز SSH میزند | ورود با کلید | authorized_keys و chage -E 0 |
Permission denied با chmod 777 هم حل نشد |
SELinux/AppArmor یا ACL | ls -Z ، getfacl ، ausearch -m avc |
su: Authentication failure |
رمز اشتباه یا حساب root قفل است | sudo -i یا حساب مدیر |
نکات امنیتی و عملیاتی¶
- فقط یک نفر/حساب برای هر هویت؛ حساب مشترک (
admin) ردپا را از بین میبرد. - ورود مستقیم root را غیرفعال کنید (SSH) و از
sudoاستفاده کنید تا هر کار به یک انسان برسد. - مجوز اجرا برای فایلهای داده و
755برای فایلهای معمولی نگذارید. - تغییرات کاربران و sudoers را در تیکت ثبت کنید.
خلاصهٔ اجرایی¶
- حساب سرویس:
--system،nologin، بدون رمز. - گروه
dockerو مجوزهای shell در sudoers = root؛ محدود کنید. - حساب خروجی: قفل رمز و
chage -E 0و بررسیauthorized_keys. - فقط با
visudo(ترجیحاً drop-in) و با فرمانهای دقیق. - ماهانه ممیزی: UID 0، رمز خالی، کلیدهای SSH، اعضای گروههای ویژه.