熱門分類
載入中…
目錄0%

🐧 Linux 檔案系統權限完整指南:ACL、setuid、setgid、sticky bit 全解析

    🐧 Linux 檔案系統權限完整指南:ACL、setuid、setgid、sticky bit 全解析

    在 Linux 伺服器實務中,檔案系統權限設計絕對不是只有 chmod 755 這麼簡單。 當你開始面對多人專案目錄、共享資料夾、Web 服務帳號、Log 檔保護與安全稽核需求時, 就會接觸到 ACL(Access Control List)setuidsetgidsticky bit 等進階機制。 本文從基礎權限復習開始,一路實作到 ACL 與特殊權限設計,協助你建立一套「安全、好維護、可稽核」的檔案權限架構。

    一、先快速複習:基本權限與數字表示法

    在看 ACL 與特殊位元之前,先用最短的篇幅把基礎觀念對齊:

    • 三種身分:檔案擁有者(user)、群組(group)、其他人(others)。
    • 三種權限:讀(r)、寫(w)、執行(x)。
    • 數字表示:r=4、w=2、x=1,相加得到每一組權限數值。
    # 範例:-rwxr-x---
    #           u   g   o
    # user:  r+w+x = 4+2+1 = 7
    # group: r+ x  = 4+0+1 = 5
    # other: -+ -+ -       = 0
    chmod 750 somefile
    
    # 查看詳細權限與擁有者
    ls -l somefile
    

    這個模型簡單好懂,但只支援 「一個擁有者 + 一個群組 + 其他人」 三層角色。 當你需要「多個特定使用者」對同一目錄有不同權限時,就會開始感到吃力,這時就是 ACL 登場的時機。

    二、什麼是 ACL?為什麼需要它?

    ACL(Access Control List) 可以想成是「更細顆粒度的檔案權限表」,它允許你針對每個使用者或群組,分別設定讀寫執行權限,而不再只能依賴單一群組。

    典型使用場景:

    • 多人專案目錄:開發者 A、B、C 都能寫入,但其餘人只能讀取。
    • 維運帳號:某些維運使用者需要讀取特定 Log,但無法直接變更檔案 owner/group。
    • 共用資料夾:特定群組有完整存取權,另外再開放少數人只讀。

    要使用 ACL,需要檔案系統支援並啟用對應掛載選項(多數現代 ext4xfs 預設已支援)。 可以先確認是否有掛載 acl 選項:

    # 檢查掛載選項
    mount | grep -E 'ext4|xfs'
    
    # 也可看 /etc/fstab 中是否有 acl
    grep acl /etc/fstab
    

    三、ACL 基本指令:getfacl / setfacl

    常見指令有兩個:

    • getfacl:查看檔案或目錄的 ACL 設定。
    • setfacl:設定或修改 ACL。

    以安裝與使用為例:

    # Debian / Ubuntu
    sudo apt install acl
    
    # CentOS / RHEL / Rocky / AlmaLinux
    sudo dnf install acl
    
    # 檢查看看目前 ACL 情況
    getfacl /var/log/messages
    

    3-1. 對單一使用者新增 ACL 權限

    假設有一個目錄 /data/share,owner 與 group 已設定好,但你想額外給 user alice 寫入權限:

    # 對 user alice 新增 rwx 權限
    sudo setfacl -m u:alice:rwx /data/share
    
    # 檢查看看
    getfacl /data/share
    

    輸出會類似:

    # file: data/share
    # owner: root
    # group: project
    user::rwx
    user:alice:rwx
    group::r-x
    mask::rwx
    other::r-x
    

    3-2. 對群組新增 ACL 權限

    若你有一個群組 auditor 專門用來稽核 Log,希望他們能讀特定 Log 目錄:

    sudo setfacl -m g:auditor:rx /var/log/app
    getfacl /var/log/app
    

    3-3. Default ACL:讓新建立的檔案自動繼承

    若只在目錄本身設 ACL,之後新建立的檔案預設仍會依照 umask 與擁有者決定權限。 如果你希望「未來在此目錄底下新增的檔案,都自動繼承 ACL 模式」,就要使用 default ACL

    # 讓 /data/project 中「未來新檔案」自動給 group project rw 權限
    sudo setfacl -m d:g:project:rwx /data/project
    
    # 一次設定 user 與 group 的 default ACL
    sudo setfacl -m d:u:alice:rwx,d:g:project:rwx /data/project
    
    # 查看 default ACL
    getfacl /data/project
    

    你會看到類似:

    default:user::rwx
    default:user:alice:rwx
    default:group::rwx
    default:group:project:rwx
    default:mask::rwx
    default:other::r-x
    

    3-4. 遞迴套用 ACL

    若目錄底下已經有很多檔案,想一次調整所有檔案的 ACL,可以加上 -R

    # 對整個目錄結構套用
    sudo setfacl -R -m g:project:rwX /data/project
    

    rwX 中的大寫 X 代表「只對目錄與原本有 x 的檔案加執行權限」,對大批檔案時非常好用。

    3-5. 移除 ACL

    若要移除特定規則或全部 ACL:

    # 移除指定 user 的 ACL
    sudo setfacl -x u:alice /data/project
    
    # 移除全部 ACL(包含預設 ACL)
    sudo setfacl -b /data/project
    

    四、ACL 常見踩雷與排錯技巧

    • Mask 權限限制:ACL 中的 mask:: 會限制實際有效權限, 即使你給 user:alice:rwx,但 mask 只有 r-x,實際生效仍是 r-x
    • 工具只顯示基本權限:ls -l 只會顯示「三組傳統權限」,若字尾有加號 + 代表有 ACL:
      ls -l /data/project
      drwxrwxr-x+ 2 root project 4096 Nov 24 10:00 project
    • 備份與還原:某些備份工具預設不保留 ACL,若需要完整還原權限,請確認有支援 ACL 選項(例如 rsync -A)。
    # 使用 rsync 保留 ACL (-A) 與 extended attributes (-X)
    rsync -aAX /data/project /backup/project
    

    五、setuid / setgid / sticky bit 概念總覽

    在傳統 Unix 世界裡,除了 rwx 以外,還有三個「特殊位元」:

    • setuid(Set User ID):執行檔在被執行時,以檔案擁有者的身分執行。
    • setgid(Set Group ID):可用於執行檔與目錄,讓程序或新檔案繼承特定群組。
    • sticky bit:常用在共享目錄,如 /tmp,避免使用者刪除他人檔案。

    ls -l 的顯示中,這三個特殊位元會取代原本的 x

    • rwsr-xr-x → user 的 x 被替換成 s,代表 setuid。
    • rwxr-sr-x → group 的 x 被替換成 s,代表 setgid。
    • rwxrwxrwt → others 的 x 被替換成 t,代表 sticky bit。

    六、setuid:以檔案擁有者身分執行

    setuid 最常見的例子是 /usr/bin/passwd

    ls -l /usr/bin/passwd
    -rwsr-xr-x 1 root root 68208 Oct 30 12:34 /usr/bin/passwd
    

    前面的 s 表示:passwd 這個程式在執行時,會以 root 身分運作, 如此一來一般使用者就能修改自己的密碼,而不需要直接給 root 權限。

    6-1. 如何設定 / 取消 setuid

    可以用數字或符號方式設定:

    # 用數字表示:4xxx → setuid
    chmod 4755 some_binary       # 等價於:rwsr-xr-x
    
    # 用符號表示
    chmod u+s some_binary        # 設定 setuid
    chmod u-s some_binary        # 取消 setuid
    

    6-2. setuid 的風險與建議

    • 風險:若 setuid 程式有漏洞,攻擊者可藉此取得高權限(甚至 root)。
    • 建議:
      • 避免自寫程式隨意加上 setuid,尤其是解譯型語言(如 Python、Shell)。
      • 定期掃描系統上所有 setuid 檔案,確認是否為預期清單。
    # 找出系統上所有 setuid 檔案
    sudo find / -perm -4000 -type f -xdev -print
    

    七、setgid:程式群組與目錄專案模式

    setgid 在「檔案」與「目錄」上的行為不同:

    • 對執行檔:程序在執行時會以檔案群組身分執行。
    • 對目錄:在該目錄內建立的新檔案,其 group 會繼承目錄的群組,而不是使用者主要群組。

    7-1. 專案目錄常見設計範本

    假設你有一個專案群組 project,所有專案成員都在這個群組裡:

    # 建立專案目錄與群組
    sudo groupadd project
    sudo mkdir -p /srv/project
    sudo chown root:project /srv/project
    
    # 設定目錄群組為 project,並啟用 setgid
    sudo chmod 2775 /srv/project
    

    2 代表 setgid,775 則是 rwxrwxr-x。 之後所有在 /srv/project 裡新建的檔案,都會自動帶上 project 群組, 避免出現 某些檔案是 user 的主要群組、造成權限不一致 的情況。

    # 驗證 setgid 目錄行為
    sudo -u alice touch /srv/project/alice.txt
    sudo -u bob   touch /srv/project/bob.txt
    
    ls -l /srv/project
    # 兩個檔案的 group 都應該是 project
    

    7-2. 設定 / 取消目錄 setgid

    # 設定目錄 setgid
    chmod g+s /srv/project          # 在權限顯示會看到 rwsrwsr-x 或 rwxr-sr-x
    
    # 取消目錄 setgid
    chmod g-s /srv/project
    

    八、sticky bit:/tmp 為什麼不會被彼此亂刪?

    sticky bit 最常碰到的例子是 /tmp

    ls -ld /tmp
    drwxrwxrwt 10 root root 4096 Nov 24 10:00 /tmp
    

    最後一個字元是 t,代表 sticky bit。它的作用是: 在此目錄中,只有檔案的擁有者、目錄擁有者或 root 可以刪除檔案, 即使大家對目錄都有寫入權限,也不能隨意刪除他人的檔案。

    8-1. 建立共享暫存目錄的範例

    如果你想建立一個類似 /tmp 的共享暫存空間:

    sudo mkdir /srv/tmp
    sudo chmod 1777 /srv/tmp    # 1 代表 sticky bit,777 是 rwxrwxrwx
    
    # 或用符號表示
    sudo chmod a+rwx,+t /srv/tmp
    

    九、特殊位元數字總整理:4 / 2 / 1 與 7xxx 模式

    在使用 chmod 的四位數模式時,最前面一位是「特殊位元」:

    • 4xxx:setuid
    • 2xxx:setgid
    • 1xxx:sticky bit
    • 7xxx:setuid + setgid + sticky bit 全開(實務上很少用到)。
    # 常見組合範例
    chmod 4755 file   # setuid + 755
    chmod 2755 dir    # setgid + 755(常用在專案目錄)
    chmod 1777 /tmp   # sticky + 777(共享暫存空間)
    

    十、實務範例:如何設計一個「好維護」的權限架構?

    10-1. Web 服務檔案與部署流程

    假設你有一個 Web App 放在 /var/www/myapp,由 www-data 執行:

    # 建立群組與目錄
    sudo groupadd webdev
    sudo mkdir -p /var/www/myapp
    
    # 專案成員加入 webdev 群組
    sudo usermod -aG webdev alice
    sudo usermod -aG webdev bob
    
    # 設定目錄擁有者與群組
    sudo chown -R www-data:webdev /var/www/myapp
    
    # 設定 setgid,確保新檔案群組一致
    sudo chmod 2775 /var/www/myapp
    
    # 若有 CI/CD 帳號,也加入 webdev 群組
    sudo usermod -aG webdev gitlab-runner
    

    如此一來:

    • Web 程式以 www-data 身分運作。
    • 專案成員透過 webdev 群組共同維護檔案。
    • setgid 讓所有新檔案的群組都保持為 webdev,權限清楚且好管理。

    10-2. 專案共用目錄 + ACL 精細控制

    若你有一個敏感專案目錄,只開放指定人員讀寫:

    # 建立群組與目錄
    sudo groupadd finance
    sudo mkdir -p /srv/finance
    sudo chown root:finance /srv/finance
    
    # 目錄基本權限:群組可讀寫,others 無權
    sudo chmod 2770 /srv/finance
    
    # 若有兩位外部稽核者只需讀取權限
    sudo setfacl -m u:auditor1:rx,u:auditor2:rx /srv/finance
    sudo setfacl -m d:u:auditor1:rx,d:u:auditor2:rx /srv/finance
    

    這樣可以:

    • 避免為了稽核者建立新群組 / 調整主要群組。
    • 清楚分離「專案成員(可寫)」與「稽核者(只能讀)」。

    10-3. Log 檔讀取權限控管

    很多維運情境只需要讓某些人「看 log」而不需要 root 權限:

    # 建立 logreader 群組
    sudo groupadd logreader
    
    # 指定 log 目錄群組與權限
    sudo chown -R root:logreader /var/log/myapp
    sudo chmod -R 2750 /var/log/myapp
    
    # 若應用程式本身需要寫入,可搭配 setgid 或 ACL
    sudo setfacl -m u:myapp:rwX /var/log/myapp
    

    十一、安全檢查清單:上線前先自問這幾件事

    • 是否有不必要的 setuid 標記?有沒有定期掃描?
    • 共享目錄(尤其是 /tmp 類型)是否都有設定 sticky bit?
    • 專案目錄是否使用 setgid 確保群組一致,避免「部分檔案權限怪怪的」?
    • ACL 是否真的有需要?如果基本 user/group 模型就能滿足,優先使用傳統權限較易維護。
    • 備份與還原流程是否有保留 ACL 與 extended attributes?

    🧭 行動清單(可以直接照做)

    ✅ 在測試環境中練習 getfacl / setfacl(單一檔案 + 目錄 + default ACL)
    ✅ 為你的專案目錄設計一個「群組 + setgid」模式,確保權限一致
    ✅ 建立一個類似 /tmp 的共享暫存空間,實作 sticky bit
    ✅ 使用 find 掃描系統上的所有 setuid / setgid 執行檔,整理出「允許清單」
    ✅ 檢查備份工具設定,確認是否有保留 ACL / xattr(如 rsync -aAX)

    🔗 延伸閱讀

    — WWFandy・Linux 權限與安全筆記

    🔗 分享這篇 LINE Facebook X

    沒有留言:

    字級