Linux File Permissions: Hướng dẫn toàn diện từ cơ bản đến nâng cao
Mục lục bài viết
1. Hiểu về file permissions trên Linux
Mỗi file và thư mục trên Linux có 3 loại quyền cho 3 nhóm: owner (chủ sở hữu), group (nhóm), và others (người khác).
Ba quyền cơ bản:
r(read): Đọc nội dung file / Liệt kê thư mục.w(write): Ghi/sửa file / Tạo/xoá file trong thư mục.x(execute): Chạy file / Truy cập thư mục (cd vào).
Xem permissions:
ls -l cho output: -rwxr-xr-- 1 user group 1024 Jul 24 10:00 file.txt
- Ký tự đầu:
-(file),d(directory),l(symlink). - 9 ký tự tiếp: 3 nhóm (owner, group, others) x 3 quyền.
rwx= read, write, execute.r-x= read, execute (no write).r--= read only.
stat file.txt để xem chi tiết permissions ở cả dạng symbolic và numeric.2. Chmod: Thay đổi permissions
Symbolic mode (dễ hiểu):
chmod u+x file- Thêm execute cho owner.chmod g-w file- Bỏ write cho group.chmod o=r file- Set others chỉ đọc.chmod a+rx file- Thêm read+execute cho all.chmod -R g+w dir/- Đệ quy: thêm write cho group vào thư mục.
Numeric mode (nhanh):
- r=4, w=2, x=1.
Cộng lại: rwx=7, rw-=6, r-x=5, r--=4.
chmod 755 file- Owner: rwx (7), Group: r-x (5), Others: r-x (5).chmod 644 file- Owner: rw- (6), Group: r-- (4), Others: r-- (4).chmod 700 ~/.ssh- Owner full, nobody else.
3. Chown và Chgrp: Đổi chủ sở hữu
Chown (change owner):
chown username file - Đổi owner.
chown username:groupname file - Đổi cả owner và group.
chown :groupname file - Chỉ đổi group (tương đương chgrp).
chown -R username:groupname dir/ - Đệ quy.
Chgrp (change group):
chgrp groupname file - Đổi group.
Ví dụ thực tế:
Khi deploy web app:
sudo chown -R www-data:www-data /var/www/myapp- Web server sở hữu.sudo chown -R $USER:www-data /var/www/myapp- Dev sở hữu, www-data group.sudo chmod 775 /var/www/myapp- Owner full, group đọc+ghi+execute.
chown cần sudo. Chỉ user root mới được đổi owner của file không phải của mình.4. Umask: Default permissions
Umask định nghĩa quyền mặc định khi tạo file mới. Nó là mặt nạ (mask) trừ đi từ 666 (file) hoặc 777 (directory).
Cách tính:
- Umask mặc định: 022.
- File mới: 666 - 022 = 644 (owner rw-, group r--, others r--).
- Thư mục mới: 777 - 022 = 755.
Các umask phổ biến:
022: Default. File 644, dir 755. An toàn.002: File 664, dir 775. Cho shared project.077: File 600, dir 700. Maximum security.007: File 660, dir 770. Chỉ owner và group.
Thiết lập:
umask 022 trong ~/.bashrc hoặc ~/.zshrc.
5. Special Permissions: SUID, SGID, Sticky Bit
SUID (Set User ID) - 4xxx:
Khi set trên executable, nó chạy với quyền của owner, không phải người chạy.
chmod u+s /usr/bin/passwd
Ví dụ: passwd có SUID: user thường chạy nhưng được ghi vào /etc/shadow (root owned).
SGID (Set Group ID) - 2xxx:
- Trên file: chạy với quyền group của file.
- Trên thư mục: file mới tạo trong thư mục kế thừa group của thư mục.
chmod g+s shared_dir/
Sticky Bit - 1xxx:
Chỉ owner (hoặc root) mới xoá được file trong thư mục.
chmod +t /tmp
Ví dụ: /tmp: ai cũng ghi được, nhưng chỉ xoá được file của mình.
6. ACL (Access Control Lists): Permissions chi tiết hơn
ACL cho phép set permissions cho nhiều user/group khác nhau, vượt quá giới hạn owner/group/others.
Cài đặt:
sudo apt install acl
Xem ACL:
getfacl file.txt
Set ACL:
setfacl -m u:alice:rwx file.txt- Cho alice quyền rwx.setfacl -m g:devteam:rw file.txt- Cho group devteam quyền rw.setfacl -m o::--- file.txt- Others không quyền gì.setfacl -R -m u:bob:rx shared_dir/- Đệ quy.setfacl -x u:alice file.txt- Xoá ACL entry.
Default ACL:
setfacl -d -m g:devteam:rwx shared_dir/
File mới tạo trong thư mục tự động kế thừa ACL này.
🙋 Câu hỏi thường gặp
Sự khác nhau giữa chmod 777 và 755?
777 là full permission cho tất cả: rất nguy hiểm vì ai cũng có thể ghi và execute. 755 là owner full, group và others chỉ đọc và execute: an toàn hơn.
Tại sao chmod u+s không hoạt động trên script?
Linux kernel bỏ qua SUID/SGID trên script (shebang script) vì lý do bảo mật (dễ exploit). SUID chỉ hoạt động trên binary (compiled).
Permission denied nhưng là owner?
Kiểm tra: (1) lsattr file xem immutable flag (i).
(2) ls -ld $(dirname file) xem thư mục có write permission không.
(3) File system có mounted read-only? mount | grep /mount_point.