
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) | 符號表示 | 權限 |
|---|---|---|---|
| 7 | 111 | rwx | 讀取、寫入、執行/搜尋 |
| 6 | 110 | rw- | 讀取及寫入 |
| 5 | 101 | r-x | 讀取及執行/搜尋 |
| 4 | 100 | r-- | 讀取 |
| 3 | 011 | -wx | 寫入及執行/搜尋 |
| 2 | 010 | -w- | 寫入 |
| 1 | 001 | --x | 執行/搜尋 |
| 0 | 000 | --- | 此類別沒有權限 |
755、644、600、700 的常見用途
下表是常見設定例子,並非每個環境的必要值。選擇前,應先確認哪些帳戶需要甚麼存取權限。
如表格未能完整顯示,可左右捲動。
| 八進位 | 符號表示 | 用途例子 |
|---|---|---|
| 755 | rwxr-xr-x | 執行檔或目錄:擁有者有 rwx,群組及其他用戶可讀取和執行/搜尋 |
| 644 | rw-r--r-- | 一般檔案:擁有者可讀寫,群組及其他用戶可讀取 |
| 600 | rw------- | 只供擁有者使用的檔案,例如 SSH 私鑰、API 金鑰檔案或 .env |
| 700 | rwx------ | 只供擁有者使用的目錄,例如 ~/.ssh 或 GnuPG 主目錄 |
| 444 | r--r--r-- | 沒有寫入位元;擁有者或具特權的帳戶仍可更改模式,因此不等於不可修改的鎖定 |
| 777 | rwxrwxrwx | 所有類別都有 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 檢查結果。
如表格未能完整顯示,可左右捲動。
| 八進位 | 符號表示 | 例子 |
|---|---|---|
| 4755 | rwsr-xr-x | 由 root 擁有的 setuid 執行檔;部分系統的 passwd 使用此設定,但路徑、模式及驗證方式會因環境而異 |
| 2770 | rwxrws--- | 可供群組寫入、並繼承群組的目錄;2755 沒有群組寫入權限,不足以供一般群組共同寫入 |
| 1777 | rwxrwxrwt | 例如 /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 當成通用解決方法。
參考資料及來源
- Git - core.fileMode ↗
- GNU coreutils - chmod(1) ↗
- Linux man-pages - execve(2) ↗
- Linux man-pages - path_resolution(7) ↗
- OpenSSH portable - authfile.c, sshkey_perm_ok ↗
- Git - git-update-index ↗
- The Open Group - POSIX.1-2024 chmod ↗
- GNU coreutils - chmod invocation ↗
- GNU coreutils - Setting Permissions ↗
- GNU coreutils - Directory Setuid and Setgid ↗
- Linux man-pages - chmod(2) ↗
- Linux man-pages - capabilities(7) ↗
- The Open Group - POSIX.1-2024 open() ↗
- Filesystem Hierarchy Standard 3.0 - /tmp ↗
- OpenSSH ssh(1) - FILES ↗
- OpenSSH sshd_config(5) - StrictModes ↗
編輯說明
本文使用 AI 協助編輯,並在發布前由編輯核對。內容仍可能包含事實、理解或時效上的錯誤;作出重要決定前,請查閱所列的一手資料或官方文件。

