傳統 rwx (User/Group/Other) 無法表達「讓用戶 A 讀寫目錄 X,但不能讀目錄 Y」這類精細需求。**ACL (Access Control List)** 以**條目式**擴充權限模型,支援針對**任意用戶/群組**設定獨立權限,是多開發者協作、代碼隔離、最小權限原則落地的利器。
# 1. 檔案系統支援 ACL (現代 ext4/xfs/btrfs 預設開啟)
tune2fs -l /dev/sda1 | grep acl
# 或 mount | grep acl
# 2. 安裝工具
apt-get install acl # Debian/Ubuntu
yum install acl # RHEL/CentOS
| 指令 | 用途 | 常用參數 |
|---|---|---|
setfacl -m u:user:perm path | 設定/修改用戶 ACL | -R 遞迴、-d 預設 ACL、-x 刪除條目 |
setfacl -m g:group:perm path | 設定/修改群組 ACL | 同上 |
setfacl -m m::perm path | 設定**有效權限遮罩** (限制所有非 owner/user/group@ 的最大權限) | 關鍵! |
getfacl path | 檢視完整 ACL | -R 遞迴、--tabular 表格輸出 |
setfacl -b path | 移除所有 ACL (保留基本 rwx) | |
setfacl -k path | 移除預設 ACL |
perm 格式r 讀、w 寫、x 執行/進入目錄rw、rx、rwx、- (無權限)假設專案結構:
/www/web/develop/
├── erp/
│ └── myapp/code/core/Erp/
│ ├── Sales/ # 開發者 A 負責
│ ├── System/ # 開發者 B 負責
│ ├── Dashboard/ # 開發者 C 負責
│ └── Adminlogin/ # 敏感,僅核心組可讀
├── e_commerce/ # 開發者 A
├── yii-market/ # 開發者 B
└── phpmyadmin/ # 所有人可讀
useradd -m -s /bin/bash dev_a
useradd -m -s /bin/bash dev_b
useradd -m -s /bin/bash dev_c
groupadd dev_team
usermod -aG dev_team dev_a dev_b dev_c
chown -R root:dev_team /www/web/develop
chmod -R 770 /www/web/develop
setfacl -R -m g:dev_team:rwx /www/web/develop
setfacl -R -d -m g:dev_team:rwx /www/web/develop # 預設 ACL:新建檔案繼承群組 rwx
# A 只能進入 e_commerce + erp/Sales
setfacl -R -m u:dev_a:rx /www/web/develop/e_commerce
setfacl -R -m u:dev_a:rx /www/web/develop/erp/myapp/code/core/Erp/Sales
setfacl -R -m u:dev_a:- /www/web/develop/erp/myapp/code/core/Erp/{System,Dashboard,Adminlogin}
setfacl -R -m u:dev_a:- /www/web/develop/{yii-market,yii2-huangdi,yii2,phpmyadmin,onfancy.com,market.onfancy.com,magento,magento2,YiiSpace-master,yourls,dwz-ria,e_commerce_huang_di,yii-market_copy_2014-11-12}
# B 只能進入 yii-market + erp/System
setfacl -R -m u:dev_b:rx /www/web/develop/yii-market
setfacl -R -m u:dev_b:rx /www/web/develop/erp/myapp/code/core/Erp/System
setfacl -R -m u:dev_b:- /www/web/develop/erp/myapp/code/core/Erp/{Sales,Dashboard,Adminlogin}
# ... 其他目錄同理拒絕
# C 只能進入 erp/Dashboard
setfacl -R -m u:dev_c:rx /www/web/develop/erp/myapp/code/core/Erp/Dashboard
setfacl -R -m u:dev_c:- /www/web/develop/erp/myapp/code/core/Erp/{Sales,System,Adminlogin}
# ... 其他目錄同理拒絕
groupadd core_team
usermod -aG core_team lead_dev
setfacl -R -m g:core_team:rx /www/web/develop/erp/myapp/code/core/Erp/Adminlogin
setfacl -R -m m::rx /www/web/develop/erp/myapp/code/core/Erp/Adminlogin # 遮罩限制最大權限
setfacl -R -m u:dev_a:- /www/web/develop/erp/myapp/code/core/Erp/Adminlogin
setfacl -R -m u:dev_b:- /www/web/develop/erp/myapp/code/core/Erp/Adminlogin
setfacl -R -m u:dev_c:- /www/web/develop/erp/myapp/code/core/Erp/Adminlogin
# 以 dev_a 身分測試
su - dev_a
ls -l /www/web/develop/erp/myapp/code/core/Erp/ # 只看到 Sales
cat /www/web/develop/erp/myapp/code/core/Erp/Sales/some.php # 可讀
cat /www/web/develop/erp/myapp/code/core/Erp/System/config.php # Permission denied
getfacl 輸出中的 mask::rwx **限制所有「命名用戶」、「命名群組」、「擁有群組」的最大實際權限**。
setfacl -m m::rx → 即使某用戶 ACL 給 rwx,實際也只有 rx。setfacl -m u:user:rwx 會自動擴大 mask 至 rwx;但手動縮小 mask 可**一次收回多個用戶/群組的寫入權**,極適合「緊急凍結」場景。
# 備份
getfacl -R /www/web/develop > develop.acl.bak
# 還原 (覆蓋)
setfacl --restore=develop.acl.bak
# 遷移至其他機器 (需相同 UID/GID)
scp develop.acl.bak remote:/tmp/
ssh remote "setfacl --restore=/tmp/develop.acl.bak"
ACL 將 Linux 權限模型從「三元組」升級為「任意條目列表」,配合**預設 ACL 繼承**、**Mask 統一遮罩**、**遞迴操作**,即可實現企業級精細授權:**開發者只見自己模組、敏感代碼僅核心組可讀、新檔自動繼承正確權限、一鍵備份還原**。這是取代「777 濫權」與「群組爆炸」的正規軍方案,強烈建議納入基礎設施標準化流程。