為什麼檔案的 Context 會「不對」?
SELinux 的政策規則是綁定在 type 上,每個目錄都有一個「預設應該有的 type」(由政策定義)。但如果你用 cp、mv,或是用文字編輯器另存新檔,新檔案的 context 可能不會自動套用該目錄的預設值,而是繼承來源檔案或建立者的 context——這就是常見的「明明權限對,服務卻讀不到」的原因。
restorecon:還原成政策預設值
sudo restorecon -v 檔案或目錄 # 還原單一檔案
sudo restorecon -Rv 目錄 # 遞迴還原整個目錄
這是最常用、也最安全的修復方式:讓系統依照政策規則,自動算出這個路徑「應該」是什麼 type。
chcon:手動指定 Context(暫時)
sudo chcon -t httpd_sys_content_t 檔案
sudo chcon -R -t httpd_sys_content_t 目錄
chcon 修改的是檔案當前的 context,重新整理檔案系統標籤(如執行 restorecon 或某些更新流程)後可能會被還原,適合臨時測試。
semanage fcontext:永久新增規則
如果某個目錄「本來就應該」一直保持某個 type(例如你自訂了一個網站根目錄路徑),應該把規則寫進政策資料庫,這樣以後執行 restorecon 也會套用:
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/myweb(/.*)?"
sudo restorecon -Rv /srv/myweb
(/.*)? 是正規表示式,代表「這個路徑本身,以及底下所有檔案與子目錄」。
容器常見的 :Z 與 :z
在 Podman / Docker 掛載 volume 時:
podman run -v /data:/data:Z myimage
:Z:把該目錄標記成只給這一個容器使用的 MCS label(私有):z:標記成可以給多個容器共用的 MCS label(共用)
這其實就是 chcon 的自動化版本——容器引擎幫你把目錄的 context 改成符合該容器 MCS 等級的標籤,容器內的程序才能存取。
常用組合
ls -Z /path/to/file # 1. 先看現況
sudo restorecon -Rv /path/to # 2. 嘗試還原預設值
sudo semanage fcontext -a ... # 3. 如果預設值不符需求,新增永久規則