實戰案例:網站改完檔案後變成空白頁
情境:你用 root 身份編輯了一個由 nginx + PHP-FPM 服務的網站檔案(例如透過文字編輯器另存新檔),檔案的擁有者、群組、權限都跟其他正常運作的檔案一模一樣,重新整理網頁卻變成空白,HTTP 狀態碼卻是 200。
排查步驟:
# 1. 確認 SELinux 是否為 Enforcing
getenforce
# 2. 比較這個檔案跟「正常運作的檔案」的 context 是否不同
ls -Z 新檔案 正常檔案
# 3. 查看是否有對應的拒絕紀錄
sudo ausearch -m avc -ts recent | grep php
如果第 2 步發現新檔案的 type 是 admin_home_t 或 unconfined_u:object_r:default_t,而正常檔案是 system_u:object_r:httpd_sys_content_t:s0,就找到問題了:
# 4. 還原成這個目錄該有的 context
sudo restorecon -v 新檔案
重新整理頁面,問題通常就解決了。這個案例說明了一個重點:「HTTP 200 但內容空白」不一定是程式邏輯錯誤,也可能是 SELinux 在更底層默默擋下了讀取操作,PHP 進程連檔案內容都讀不到,自然就輸出空白。
實戰案例:容器掛載目錄後應用程式啟動失敗
情境:你用 podman run -v /srv/data:/data myimage 啟動容器,容器內的程式回報「無法寫入 /data」,但 /srv/data 在主機上的 Unix 權限是 777。
ls -Z /srv/data
如果 type 不是 container_file_t,補上 :Z 重新執行:
podman run -v /srv/data:/data:Z myimage
或手動調整現有目錄:
sudo chcon -Rt container_file_t /srv/data
練習建議
- 在自己的測試機上,把
setenforce切到0(Permissive),刻意製造一次「檔案權限正常但 SELinux 會擋」的情境,比較 Permissive 與 Enforcing 下的行為差異 - 練習用
ausearch+audit2why看懂一筆 AVC 紀錄在說什麼 - 對一個自訂的網站目錄,練習寫一條
semanage fcontext規則並用restorecon套用
接下來可以往哪裡學?
學會 SELinux 的基本排查流程後,可以朝這幾個方向繼續探索:
- 網路基礎:搭配防火牆(firewalld)一起理解,網路連線問題常常需要同時排查防火牆規則與 SELinux port context
- Podman / Docker 基礎入門:重新回顧容器的 Volume 掛載章節,這次你會更清楚
:Z/:z背後實際在做什麼 - Linux 基礎入門(使用者與權限):把 DAC 與 MAC 兩套機制放在一起理解,建立完整的存取控制心智模型
- 系統稽核與監控:更進一步學習
auditd的設定與長期日誌分析,建立完整的安全監控習慣
SELinux 常被認為「很難、很煩」,但只要掌握「context → Boolean → audit log」這套排查順序,大多數問題其實都能很快定位並解決。