chmod 權限解說:755、644、600 與 setuid、setgid、sticky bit
DDEVELOPER
開發發布: 12 分鐘閱讀

chmod 權限解說:755、644、600 與 setuid、setgid、sticky bit

chmod 755 script.sh 和 chmod 600 ~/.ssh/id_rsa 並非只能靠背誦。理解各位數的意思,便能判斷誰可以讀取、寫入或執行檔案,以及目錄的權限有何不同。本文由一般權限及特殊位元入手,再以共用目錄、OpenSSH 私鑰和 Git 說明實際用途。基本介面以 POSIX 為依據;涉及 GNU、Linux 或 OpenSSH 特有行為時,會交代適用範圍。

日文原文發布: 2026-05-30

三位八進位數字,分別代表誰的權限?

一般權限分為三組,每組三個位元:u 代表檔案擁有者、g 代表檔案所屬群組、o 代表其他用戶。擁有者是擁有該檔案的帳戶,不一定是目前操作的用戶。

按一般模式位元判斷時,擁有者使用 u;非擁有者若所屬群組符合檔案的群組,便使用 g;其餘使用 o。某一類別缺少的權限,不能從另一類別補上。存取控制清單(ACL)、特權及安全政策等亦可能影響結果。解析路徑時,沿途的目錄還需要搜尋權限。

  • r = 4(讀取):對檔案而言,可讀取內容;對目錄而言,可列出項目名稱。要取得項目的詳細資料,通常亦需要 x。
  • w = 2(寫入):對檔案而言,可修改內容;對目錄而言,涉及新增及刪除項目,通常要配合搜尋權限。這與目錄內各檔案本身的權限是兩回事。
  • x = 1(執行/搜尋):對檔案而言,可執行;對目錄而言,可搜尋及通過,包括以 cd 進入。若要列出目錄內的名稱,仍須有 r。

將所需權限的數值相加,便會得到 0 至 7 的一位數。依擁有者、群組、其他用戶的次序排列,就成為 755 這類模式。

如表格未能完整顯示,可左右捲動。

數字二進位(rwx)符號表示權限
7111rwx讀取、寫入、執行/搜尋
6110rw-讀取及寫入
5101r-x讀取及執行/搜尋
4100r--讀取
3011-wx寫入及執行/搜尋
2010-w-寫入
1001--x執行/搜尋
0000---此類別沒有權限

755、644、600、700 的常見用途

下表是常見設定例子,並非每個環境的必要值。選擇前,應先確認哪些帳戶需要甚麼存取權限。

如表格未能完整顯示,可左右捲動。

八進位符號表示用途例子
755rwxr-xr-x執行檔或目錄:擁有者有 rwx,群組及其他用戶可讀取和執行/搜尋
644rw-r--r--一般檔案:擁有者可讀寫,群組及其他用戶可讀取
600rw-------只供擁有者使用的檔案,例如 SSH 私鑰、API 金鑰檔案或 .env
700rwx------只供擁有者使用的目錄,例如 ~/.ssh 或 GnuPG 主目錄
444r--r--r--沒有寫入位元;擁有者或具特權的帳戶仍可更改模式,因此不等於不可修改的鎖定
777rwxrwxrwx所有類別都有 rwx;共用目錄仍需安排擁有者及刪除限制

建立檔案時,程式先要求一個模式,再由程序的 umask 限制權限。例如,程式對一般檔案要求 0666、對目錄要求 0777,umask 為 0022 時,通常會得到 0644 和 0755。這裏的 0666/0777 是建立時要求的模式例子,不是 chmod 運算的起點;ACL 等機制亦可能影響最終結果。

# umask 為 022;以下全部是八進位數值
檔案:666 & ~022 = 644 (rw-r--r--)
目錄:777 & ~022 = 755 (rwxr-xr-x)

# umask 為 002
檔案:666 & ~002 = 664 (rw-rw-r--)
目錄:777 & ~002 = 775 (rwxrwxr-x)

這是位元遮罩運算,並非十進位減法。

符號模式:只改動指定的權限

POSIX 亦定義 chmod 的符號模式。寫法是對象 u/g/o/a、運算子 +/-/= 及權限字元,多項操作以逗號分隔。GNU chmod 支援 r/w/x/X/s/t,亦可用 u/g/o 複製另一類別的權限。

chmod u=rwx,g=rx,o=rx,u-s,g-s,o-t file  # 要求 0755,並明確清除特殊位元
chmod u+x script.sh                    # 只加入擁有者的執行權限
chmod -R go-w /path                    # 遞迴移除群組及其他用戶的寫入權限
chmod a+r file                         # 為所有類別加入讀取權限

請將例子中的路徑換成實際目標。執行遞迴操作前,先確認影響範圍,以及所用 chmod 實作如何處理符號連結。

  • 對象:u 是擁有者、g 是群組、o 是其他用戶,a 包括三者。
  • 運算子:+ 加入位元、- 移除位元、= 替換所選類別的權限;但要留意 GNU 保留目錄 set-ID 位元的規則。
  • 權限:r/w/x 是一般權限;s 選取 setuid/setgid,t 選取 sticky bit。X 代表有條件的執行/搜尋:例如 +X 只在目標是目錄,或原本已有某類別的 x 時,才加入 x。

對象可以省略,但此時 umask 遮罩涵蓋的位元不會被改動。因此,chmod +x 與 chmod a+x 未必有相同效果。

符號模式適合表達局部修改,例如 chmod go-w file 只移除群組及其他用戶的寫入權限。數值模式可簡潔地指定一般權限,但 GNU chmod 對目錄可能保留原有 setuid/setgid,除非明確要求清除。完成後應連同特殊位元一起檢查。

最前面的特殊位數:setuid、setgid 及 sticky bit

4755 這類四位數模式,最前面的數字是 setuid = 4、setgid = 2、sticky = 1 的總和,意思與後三位的讀取、寫入、執行不同。

  • setuid(4000):對執行檔而言,執行時可將程序的有效用戶 ID 設為檔案擁有者的 ID。
  • setgid(2000):對執行檔而言,可將有效群組 ID 設為檔案所屬群組;對目錄而言,在其中建立的新項目會繼承目錄的群組。
  • sticky bit(1000):對目錄而言,會額外限制刪除及重新命名,只有項目擁有者、目錄擁有者或具足夠特權的程序可以進行。

符號表示中,原本 x 的位置可能出現 s/S 或 t/T。小寫表示相應的 x 亦已設定;大寫表示沒有設定 x。

要求的模式不保證就是實際套用結果。例如,一般檔案所屬群組若不符合呼叫者的有效群組或附加群組,而呼叫者又沒有所需特權,GNU chmod 可能清除 setgid。作業系統及檔案系統亦可能限制 set-ID 的設定。請用 stat 或 ls -l 檢查結果。

如表格未能完整顯示,可左右捲動。

八進位符號表示例子
4755rwsr-xr-x由 root 擁有的 setuid 執行檔;部分系統的 passwd 使用此設定,但路徑、模式及驗證方式會因環境而異
2770rwxrws---可供群組寫入、並繼承群組的目錄;2755 沒有群組寫入權限,不足以供一般群組共同寫入
1777rwxrwxrwt例如 /tmp 的共用暫存目錄,另有刪除及重新命名限制

目錄的 setgid 不保證新檔案可供群組寫入,仍須檢查建立模式、umask 及 ACL。sticky bit 不會阻止讀取或寫入檔案內容,也不會額外授予目錄的 w/x;它是在原有權限之上增加刪除及重新命名限制。在 Linux 上,nosuid、no_new_privs 或受 ptrace 追蹤等條件,會抑制執行時的 set-ID 身分變更。

為甚麼 /tmp 常用 1777?

檔案系統階層標準(FHS)要求 /tmp 可供需要暫存檔案的程式使用,並沒有指定必須設為 1777。許多 UNIX 類環境以此模式建立共用暫存目錄。若只讓所有人都有 rwx,其他用戶亦可能刪除或重新命名項目;加入 sticky bit 後,這些操作便受上述擁有者及特權條件限制。

把需要特權的範圍收窄

由 root 擁有的 setuid 執行檔若有漏洞,可能成為提升權限的途徑。setuid 並非一概不應使用,但須審視程式實作、擁有者,以及哪些帳戶可以修改程式及其相依項目。

  • 移除不必要的 setuid 執行檔,檢查誰能修改程式及相依項目。
  • 在 Linux 上,評估是否只需要特定 capability,例如用於綁定低號碼通訊埠的 CAP_NET_BIND_SERVICE;實際需要及設定方式應按服務判斷。
  • 按用途考慮透過 sudo 或 polkit,只授權個別操作。
  • 不要依賴 shell 指令碼的 setuid 作特權設計;Linux 會忽略指令碼上的 setuid 及 setgid 位元。

實際排查:SSH 私鑰、服務及 Git

OpenSSH 拒絕權限過寬的私鑰

載入私鑰時,可能看到以下英文警告。這裏保留關鍵訊息原文,方便與程式輸出對照:

$ ssh -i ~/.ssh/id_rsa user@host
WARNING: UNPROTECTED PRIVATE KEY FILE!
Permissions 0644 for '/home/user/.ssh/id_rsa' are too open.

常見處理例子是 chmod 600 ~/.ssh/id_rsa。400 會再移除擁有者的寫入位元,但不會阻止擁有者重新更改模式。

在 UNIX 類系統上,OpenSSH portable 會檢查私鑰是否由執行 ssh 的用戶擁有;若是,而群組/其他用戶的任何權限位元已設定,就會拒絕載入該私鑰。這不代表整個用戶端必定停止,仍可能嘗試其他金鑰或驗證方式。這亦不是建議使用他人擁有的私鑰;Windows 以 ACL 檢查的情況應另行區分。

~/.ssh 建議設為 700,但不是唯一可能值

OpenSSH 文件建議 .ssh 目錄只供擁有者存取。亦應檢查擁有者、群組/其他用戶的寫入權限,以及伺服器端的 StrictModes。用戶端載入私鑰,與伺服器端檢查,是不同機制。

服務無法執行程式

由作業系統直接啟動的 CGI 指令碼或執行檔,需要讓實際執行帳戶具備 x 權限。若把指令碼作為引數交給直譯器,則需要讀取權限,而不是依賴指令碼本身的 x。先找出 CGI 或後端服務的帳戶,例如 www-data,再判斷它使用擁有者、群組還是其他用戶的權限。755 只是例子,並非每次部署都必須使用。

Git checkout 後,指令碼無法執行

對一般檔案而言,Git 記錄的是是否可執行,不會完整保存擁有者、群組及所有權限。檔案系統的支援程度及 core.fileMode 會影響執行位元的處理。在 UNIX 類工作目錄中,chmod u+x script.sh 會為實際檔案加入擁有者的執行權限。

git update-index --chmod=+x script.sh 則是更改索引(index)內的可執行旗標,不會直接修正工作目錄內檔案的模式。若要透過 Git 分享這項變更,仍須建立提交(commit)。

讀懂權限值,再確認實際環境

以下兩種計法要分開理解:

後三位各自計算:讀取 (4) + 寫入 (2) + 執行/搜尋 (1)
最前面的特殊位數:setuid (4) + setgid (2) + sticky (1)

755 讓擁有者有 rwx,其餘類別可讀取及執行/搜尋;644 讓擁有者可讀寫,其餘可讀取;600 的一般權限只讓擁有者讀寫。這些數字描述的是模式位元,並未涵蓋所有影響存取的機制。

權限計算機可協助在八進位與符號表示之間轉換,但使用前仍須確認目標路徑、作業系統規則及實際套用結果。按工作需要選擇最小必要權限,不要把 777 當成通用解決方法。

參考資料及來源

編輯說明

本文使用 AI 協助編輯,並在發布前由編輯核對。內容仍可能包含事實、理解或時效上的錯誤;作出重要決定前,請查閱所列的一手資料或官方文件。

相關工具

相關文章