檔案已經是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成功只確認檔案內容可取得,不代表應用設定、路由與解析也正確。
最後確認權限沒有意外擴到其他使用者,保留原值與本次修改範圍。若仍被拒絕,沿路徑找下一個限制,不要把一次局部修改擴成全站權限重設。

評論0