Linux檔案權限看似正確卻開不了:逐層檢查目錄權限

檔案已經是644,網站程序卻讀不到,先看完整路徑上的目錄。Linux要找到檔案,通常得先穿過每一層目錄;檔案可讀,不代表執行帳號有權搜尋它的所有父目錄。

目錄的x代表搜尋或穿越,與普通檔案的執行權限不同。先確認實際使用者與群組,再逐層檢查,不要因看到Permission denied就把整棵網站目錄改成777。

先用發生錯誤的帳號查

你登入的帳號能讀,不代表PHP、Web伺服器或工作程序也能讀。先由有權限的維護者確認服務身分,並在相同身分下重現唯讀存取;不要用root讀成功就結束排查。

id
namei -l /srv/site/private/readme.txt

id列出目前使用者、主要群組與附加群組。namei -l會沿路徑列出各層擁有者、群組與權限,遇到符號連結也能看見解析過程。路徑是例子,換成真正失敗的檔案;沒有namei的環境,按當地工具與手冊逐層核對。

檔案r與目錄x,是不同的門

普通檔案的r允許讀取內容。目錄的r主要關係到列出其中的名稱,x則允許搜尋已知名稱和穿越該目錄;看得到檔名,不代表能進一步開啟檔案。

假設路徑是/srv/site/private/readme.txt,執行帳號通常需要對/srv、/srv/site與private等各層都有搜尋權限,最後還要對readme.txt有讀取權限。任一層拒絕搜尋,單改最後檔案的r也無法跨過去。

用非root帳號分開測兩種失敗

本文用專用Linux容器,檢查時使用UID與GID都為65534的非root身分。上層目錄為755,private的群組是nogroup,先設740,readme.txt則是644。

drwxr----- root nogroup private
-rw-r--r-- root root    readme.txt
cat: Permission denied

這個帳號屬於nogroup,所以private使用群組的r–,缺少x。檔案雖可供其他使用者讀取,程序仍不能穿過private。只對該目錄增加群組x,變成750後,同一個帳號就能讀到檔案內容。

接著保留目錄750,把檔案改成root擁有的600,又讀取失敗。此時目錄都可穿越,缺的是最後檔案的r;把這個專用檔案的群組設為nogroup並給群組讀取,變成640,才再次成功。

條件                         cat結束碼
目錄740,檔案644              1:缺目錄搜尋權限
目錄750,檔案644              0:讀取成功
目錄750,root檔案600          1:缺檔案讀取權限
目錄750,nogroup檔案640       0:讀取成功

這些權限只用於隔離案例,nogroup不是所有網站應使用的服務群組。正式環境要按真正的服務帳號、資料敏感性與存取範圍設計,不是照抄750或640就算正確。

案例再把目錄的群組r移除,只留搜尋x,目錄變成710,檔案仍為nogroup可讀的640。同一個帳號用ls列目錄失敗,卻仍能依已知完整名稱讀取readme.txt。這進一步分開「列出名稱」與「找到已知檔案」兩種能力。

不過,不能列目錄不等於內容已保密。知道檔名的使用者若有搜尋與檔案讀取權限,仍可能取得內容。私人設定需要按真正的讀取對象保護,不能只靠藏住目錄列表。

先選對權限類別,再看有沒有那個位元

一般模式位元會依檔案擁有者、群組與其他使用者判斷適用類別。不要看到others有r,就認為任何帳號一定可讀;若帳號屬於適用的群組,群組那一段才是要看的權限,不會把三段全部相加成一份。

服務程序的附加群組也要核對。修改帳號群組後,已在執行的程序可能仍保留原本群組身分,需要依服務流程讓它重新取得身分;不能只看帳號資料已更新,就認定現有工作程序已經變了。

同一個檔案在容器內外的UID和GID也可能呈現不同名稱。比對數字身分與掛載條件,避免只因兩邊都叫www-data就推成同一個權限主體。

修正要落在真正擋住的那一層

先保存各層擁有者、群組與模式,再與服務需求核對。若只需要讀一份設定,就讓適當的服務群組能穿越必要目錄並讀該檔;不需要順手開放整個目錄的寫入或執行權限。

隔離案例使用的是群組搜尋與讀取兩個分開的改動:

chmod g+x /專用測試目錄/private
chmod g+r /專用測試目錄/private/readme.txt

這些命令以群組歸屬已確認為前提,只在自己的測試資產操作。正式檔案若屬於別的群組,新增g+r可能讓不該讀的使用者取得內容,也可能仍然沒有幫到服務帳號。

不要直接chmod -R 777,也不要替所有普通檔案加x。目錄需要搜尋權限,文字設定檔通常只需讀取;遞迴套一個數字,容易把不同用途的資產都放寬到不必要的範圍。

符號連結把你帶去哪,也要查清楚

readme.txt若是符號連結,還要核對目標所在目錄。原路徑看起來都有x,目標卻在另一個private目錄,仍可能被那一層擋住。namei的路徑展開能提供線索,不要只看連結本身常見的rwx字樣。

路徑的相對起點也要正確。服務工作目錄與手動終端機不同時,可能查到另一個檔案;先確認真正解析的目標,再談權限。檔案不存在、檔名大小寫不符與存取被拒絕,應保留不同錯誤,不要全部當成644問題。

模式正確,仍可能有其他限制

ACL可以增加更細的使用者或群組規則,還有mask會影響有效權限。若系統使用ACL,以有權限的工具查看有效設定;單看ls -l或mode,不一定涵蓋全部存取判斷。

SELinux、AppArmor、服務沙箱與容器掛載限制,也可能另外拒絕讀取。這時核對相關拒絕紀錄與既有政策,由負責人處理;不要為了驗證就停用全機的安全機制。

修完仍用同一個身分讀一次

讓發生錯誤的程序身分重新讀取,確認每層目錄可搜尋、最後檔案可讀,再驗網站實際功能。命令列cat成功只確認檔案內容可取得,不代表應用設定、路由與解析也正確。

最後確認權限沒有意外擴到其他使用者,保留原值與本次修改範圍。若仍被拒絕,沿路徑找下一個限制,不要把一次局部修改擴成全站權限重設。

參考資料

原文鏈接:https://wntheme.com/linux-path-directory-permissions/,轉載請註明出處。
0

評論0

顯示驗證碼
沒有帳號?註冊  忘記密碼?