Linux File Permissions Và ACL Trong Production: Kiểm Soát Truy Cập Không Làm Gãy Dịch Vụ

Linux file permissions ACL là kỹ năng rất căn bản nhưng lại gây nhiều sự cố production nhất: ứng dụng không ghi được log, web server trả 403, backup job đọc thiếu file, hoặc tệ hơn là cả thư mục được chmod 777 chỉ để “chạy cho xong”. Bài này đi theo hướng thực chiến cho sysadmin: hiểu quyền Linux, dùng ACL đúng chỗ, kiểm tra lỗi, rollback an toàn và có checklist nghiệm thu trước khi áp dụng lên máy chủ thật.

Bối cảnh lab trong bài: một máy chủ Ubuntu/RHEL chạy dịch vụ web tên appsvc, web server thuộc user www-data hoặc nginx, thư mục ứng dụng nằm ở /srv/app, log nằm ở /var/log/app. Bạn có thể đổi tên user/group cho phù hợp môi trường của mình.

1. Vì sao Linux file permissions ACL quan trọng trong production?

Quyền file trên Linux quyết định tiến trình nào được đọc, ghi, thực thi file. Trong production, quyền sai thường tạo ra hai nhóm rủi ro trái ngược:

  • Quá chặt: dịch vụ không đọc được config, không ghi được log, deploy thất bại.
  • Quá rộng: user không liên quan có thể sửa code, đọc secret, ghi file độc hại.

Mục tiêu không phải là đặt quyền “càng ít càng tốt” một cách máy móc, mà là cấp đúng quyền cho đúng danh tính vận hành: owner, group, service account và automation account.

2. Nền tảng: owner, group và ba bit rwx

Mỗi file/thư mục Linux có owner, group và ba nhóm quyền: user, group, other. Dùng ls -l để xem:

ls -ld /srv/app /srv/app/config.php
# output mẫu
drwxr-x---  6 deploy app     4096 Jul  9 18:10 /srv/app
-rw-r-----  1 deploy app      820 Jul  9 18:11 /srv/app/config.php

Giải thích nhanh:

  • d: đây là thư mục.
  • r: đọc nội dung file hoặc liệt kê thư mục.
  • w: ghi file hoặc tạo/xóa entry trong thư mục.
  • x: thực thi file hoặc đi xuyên qua thư mục.

Với thư mục, thiếu x sẽ gây lỗi khó hiểu: user có thể thấy tên thư mục cha nhưng không truy cập được file bên trong.

3. Thiết kế quyền chuẩn cho thư mục ứng dụng

3.1. Tạo group vận hành

sudo groupadd --system app 2>/dev/null || true
sudo usermod -aG app deploy
sudo usermod -aG app www-data   # Debian/Ubuntu Apache
# hoặc: sudo usermod -aG app nginx

Sau khi thêm user vào group, session đăng nhập cũ có thể chưa nhận group mới. Kiểm tra bằng:

id deploy
id www-data
# output mẫu
uid=33(www-data) gid=33(www-data) groups=33(www-data),998(app)

3.2. Set owner/group và quyền cơ bản

sudo chown -R deploy:app /srv/app
sudo find /srv/app -type d -exec chmod 2750 {} \;
sudo find /srv/app -type f -exec chmod 0640 {} \;

2750 trên thư mục gồm 2setgid bit. File/thư mục mới tạo bên trong sẽ kế thừa group app, giúp deploy và service account làm việc nhất quán hơn.

3.3. File cần thực thi

Không phải file nào cũng nên executable. Chỉ cấp x cho script thật sự cần chạy:

sudo chmod 0750 /srv/app/bin/deploy-healthcheck.sh
sudo -u deploy /srv/app/bin/deploy-healthcheck.sh

Nếu script bị lỗi Permission denied, kiểm tra cả quyền file lẫn quyền x trên toàn bộ đường dẫn:

namei -l /srv/app/bin/deploy-healthcheck.sh

4. Umask: ngăn file mới sinh ra bị quá rộng quyền

umask là mặt nạ quyền mặc định khi process tạo file mới. Ví dụ umask 027 thường phù hợp hơn 022 với production vì chặn “other” đọc file.

umask
# tạm thời trong shell
umask 027
# test
touch /srv/app/test-permission
ls -l /srv/app/test-permission
# output: -rw-r----- deploy app ... test-permission

Với systemd service, đặt umask trong unit:

sudo systemctl edit myapp.service
[Service]
UMask=0027

Sau đó reload và restart:

sudo systemctl daemon-reload
sudo systemctl restart myapp.service
systemctl show myapp.service -p UMask

5. ACL: khi quyền owner/group/other không đủ

ACL hữu ích khi bạn cần cấp quyền cho một user hoặc group phụ mà không muốn đổi owner/group chính. Ví dụ đội backup cần đọc /srv/app, còn đội deploy vẫn giữ group app.

5.1. Cài và kiểm tra ACL

# Ubuntu/Debian
sudo apt-get update && sudo apt-get install -y acl
# RHEL/Rocky
sudo dnf install -y acl
getfacl /srv/app

5.2. Cấp quyền đọc cho backup agent

sudo useradd --system --no-create-home backupagent 2>/dev/null || true
sudo setfacl -R -m u:backupagent:rx /srv/app
sudo setfacl -R -m d:u:backupagent:rx /srv/app
getfacl /srv/app | sed -n '1,20p'

Dòng d:u:backupagent:rx là default ACL cho file/thư mục mới tạo bên trong. Nếu quên default ACL, file hiện tại có thể đọc được nhưng file mới sau deploy lại lỗi backup.

5.3. Cấp quyền ghi có kiểm soát cho thư mục upload

sudo mkdir -p /srv/app/storage/uploads
sudo chown deploy:app /srv/app/storage/uploads
sudo chmod 2770 /srv/app/storage/uploads
sudo setfacl -m u:www-data:rwx /srv/app/storage/uploads
sudo setfacl -m d:u:www-data:rwx /srv/app/storage/uploads

Không nên cấp ghi toàn bộ /srv/app cho web server. Chỉ những thư mục runtime như upload, cache, session hoặc temporary files mới cần write.

6. Audit lỗi Permission denied theo quy trình

Khi ứng dụng báo lỗi permission, đừng vội chmod -R 777. Đi theo thứ tự sau:

6.1. Xác định process chạy bằng user nào

ps -eo user,group,comm,args | grep -E 'nginx|apache|php-fpm|node|python' | grep -v grep
systemctl status nginx --no-pager
systemctl show nginx -p User -p Group

6.2. Test quyền bằng đúng service account

sudo -u www-data test -r /srv/app/config.php && echo READ_OK || echo READ_FAIL
sudo -u www-data test -w /srv/app/storage/uploads && echo WRITE_OK || echo WRITE_FAIL
sudo -u www-data bash -lc 'echo test > /srv/app/storage/uploads/perm-test.txt'

Cách này loại bỏ phỏng đoán. Nếu command fail, lỗi nằm ở quyền filesystem, ACL, SELinux/AppArmor hoặc mount option.

6.3. Dùng namei để kiểm tra từng cấp thư mục

namei -l /srv/app/storage/uploads/perm-test.txt

Nếu một thư mục cha thiếu x, service account không thể đi xuyên qua dù file cuối có quyền đúng.

7. SELinux/AppArmor: không phải lỗi nào cũng do chmod

Trên RHEL/Rocky/AlmaLinux, SELinux có thể chặn truy cập dù Linux permission nhìn đúng. Kiểm tra nhanh:

getenforce
sudo ausearch -m avc -ts recent | tail -30
ls -Z /srv/app

Ví dụ với web content custom path, bạn có thể cần label phù hợp:

sudo semanage fcontext -a -t httpd_sys_content_t '/srv/app(/.*)?'
sudo restorecon -Rv /srv/app

Nếu cần write cho upload:

sudo semanage fcontext -a -t httpd_sys_rw_content_t '/srv/app/storage/uploads(/.*)?'
sudo restorecon -Rv /srv/app/storage/uploads

Đừng tắt SELinux vĩnh viễn chỉ vì một lỗi permission. Hãy đọc audit log và sửa context đúng.

8. Rollback an toàn khi chỉnh quyền hàng loạt

Trước khi chạy chown -R hoặc chmod -R trên thư mục lớn, lưu lại trạng thái:

sudo getfacl -R /srv/app > /root/srv-app-acl-$(date +%F-%H%M%S).backup
sudo find /srv/app -printf '%m %u %g %p
' > /root/srv-app-mode-owner-$(date +%F-%H%M%S).txt

Khôi phục ACL bằng:

sudo setfacl --restore=/root/srv-app-acl-2026-07-09-185500.backup

File find giúp đối chiếu owner/mode nếu cần điều tra sau sự cố.

9. Lỗi thường gặp và cách xử lý

9.1. Web server trả 403 Forbidden

  • Kiểm tra user chạy web server.
  • Kiểm tra x trên tất cả thư mục cha bằng namei -l.
  • Kiểm tra SELinux/AppArmor nếu permission thường đã đúng.

9.2. Deploy xong file mới sai group

  • Đặt setgid bit trên thư mục: chmod 2750 /srv/app.
  • Kiểm tra user deploy có thuộc group ứng dụng không.
  • Kiểm tra umask của CI/CD runner.

9.3. ACL đã cấp nhưng file mới vẫn không có quyền

  • Thiếu default ACL: dùng setfacl -m d:u:backupagent:rx /srv/app.
  • Ứng dụng tạo file bằng cơ chế atomic rename từ thư mục khác.
  • Mount filesystem không hỗ trợ ACL hoặc bị cấu hình khác thường.

9.4. Ai đó chmod 777 để chữa cháy

Ghi nhận incident, khôi phục quyền chuẩn, tìm nguyên nhân gốc và bổ sung runbook. 777 có thể là dấu hiệu quy trình deploy/ownership chưa rõ ràng.

10. Checklist nghiệm thu trước khi lên production

  • Đã xác định owner, group, service account và automation account.
  • Thư mục code không writable bởi web server nếu không cần.
  • Chỉ thư mục runtime/upload/cache có quyền ghi cần thiết.
  • Setgid bit được bật trên thư mục cần kế thừa group.
  • Umask của shell, systemd service và CI/CD runner đã thống nhất.
  • ACL có default ACL nếu cần áp dụng cho file mới.
  • Đã test bằng sudo -u service-user, không test bằng root.
  • Đã kiểm tra SELinux/AppArmor nếu hệ thống bật mandatory access control.
  • Đã backup ACL trước khi thay đổi hàng loạt.
  • Monitoring/log có cảnh báo lỗi permission sau deploy.

11. Lab thực hành 30 phút

  1. Tạo thư mục /srv/app-lab, group app-lab, user deploylabweblab.
  2. Thiết kế quyền sao cho deploylab deploy code, weblab chỉ đọc code và ghi vào storage/uploads.
  3. Thêm user backuplab chỉ có quyền đọc bằng ACL.
  4. Tạo file mới bằng deploylab và kiểm tra group/ACL có kế thừa đúng không.
  5. Cố tình bỏ x trên một thư mục cha, quan sát lỗi, rồi dùng namei -l để tìm nguyên nhân.

Kết luận

Linux file permissions ACL không chỉ là vài lệnh chmod. Trong production, nó là thiết kế kiểm soát truy cập: ai sở hữu file, tiến trình nào được đọc/ghi, file mới kế thừa quyền ra sao, và làm thế nào để điều tra khi lỗi xảy ra. Nếu bạn tránh được phản xạ chmod 777 và thay bằng quy trình kiểm tra có bằng chứng, hệ thống sẽ an toàn hơn mà vẫn vận hành mượt.

Tác giả: Mạnh Hoàng

Tôi là Hoàng Mạnh, người sáng lập blog SysadminSkills.com. Tôi viết về quản trị hệ thống, bảo mật máy chủ, DevOps và cách ứng dụng AI để tự động hóa công việc IT. Blog này là nơi tôi chia sẻ những gì đã học được từ thực tế – đơn giản, ngắn gọn và áp dụng được ngay.