Watch at Ease看見世界,讀懂生活。

科技 · 實用指南

systemd 顯示 status=203/EXEC?改權限前先稽核失敗的 execve 路徑

203/EXEC 表示服務管理器無法執行設定的程序。應依日誌的精確原因區分目標或解譯器缺失、格式無效、路徑/掛載拒絕與強制存取控制,再做修改。

原創 systemd 203/EXEC 分支圖,依日誌原因區分缺失、拒絕與格式錯誤
原創概念示意圖:原創圖:先保存第一條 EXEC 日誌,再將 ENOENT、EACCES 與 ENOEXEC 導向不同證據檢查。 Watch at Ease

systemd 單元以 code=exited、status=203/EXEC 結束時,通常還沒進入應用程式邏輯。systemd 將 203 定義為 EXIT_EXEC,即 execve 系統呼叫失敗。這縮小了範圍,卻不能自動指出哪個路徑、解譯器、掛載規則或安全政策造成失敗。

不要先 chmod 777、加一層 shell 或關閉 SELinux。先保留實際載入的單元與第一條「Failed at step EXEC」日誌,再沿服務必須跨過的執行邊界稽核命令。

1. 保留真正失敗的命令

執行 systemctl cat UNIT,以及 systemctl show -p ExecStart -p User -p Group -p RootDirectory -p RootImage UNIT。讀取本次啟動中第一條 EXEC 失敗日誌並保存路徑與尾端原因。只有單元定義真的修改後才需要 daemon-reload。

把 ExecStart 當作 systemd 語法而不是互動式 shell。只有設計上確實需要管線、重新導向或展開時才使用明確 shell。systemd #23235 證明把 ${APP} 放在可執行檔位置會產生 203/EXEC。

2. 依日誌原因對應 execve 分支

遇到「No such file or directory」,先用 readlink -f、stat 檢查目標,再以 head -n1 或 readelf -l 檢查解譯器。execve 文件明確指出 ENOENT 也包括腳本或 ELF 解譯器不存在;CRLF 還可能把隱藏的回車帶入 shebang。

遇到「Permission denied」,用 namei -l 檢查每層目錄,再用 findmnt -T PATH -o TARGET,FSTYPE,OPTIONS 找出 noexec。遇到「Exec format error」,用 file 與 readelf -h 核對格式和架構。這些命令只收集證據,不授權修改權限、標籤或掛載。

3. 檢查服務情境,而不只檢查 shell

確認有效 User、Group,並只以該身分做無害路徑測試。若設定 RootDirectory 或 RootImage,執行檔和依賴必須存在新根中;私人或保護性檔案系統設定也可能改變服務所見路徑。

若日誌為 EACCES 且一般權限正常,使用發行版支援的稽核工具查看政策記錄。Red Hat 記錄 init_t 執行 default_t、user_home_t、nfs_t 或 cifs_t 被 AVC 拒絕並呈現 203/EXEC 的案例。AVC 應導向精確標籤或政策修正,而不是全面關閉強制模式。

4. 只修復已證明的原因

只有分支證明後才精確修正路徑、解譯器、換行、執行位元、父目錄搜尋權限、掛載、架構、命名空間或政策標籤。不要 chmod 777;它無法修復缺失解譯器、錯誤架構、noexec 或政策轉換。

ExecStart 應優先使用直接絕對路徑。加入 /bin/bash 可能繞過一個腳本分支,卻隱藏 shebang 缺陷並改變 execve 啟動的檔案。真正需要 shell 時應明確按 shell 語法設計,而非當成通用修復。

5. 證明服務跨過執行邊界

完成最小修改後,只有單元定義改變才執行 daemon-reload,接著啟動一次並讀取新日誌。203/EXEC 消失只表示已跨過執行邊界,應用程式仍可能以自己的狀態失敗;還要核對 ActiveState、SubState、ExecMainCode 與 ExecMainStatus。

記錄原始原因、唯一改動與修改後狀態。若 203 仍在,回到新的第一條 EXEC 日誌,不要堆疊修正。若路徑或政策屬於套件服務、二進位來源不明或修正會削弱安全邊界,應停止並升級處理。

原創 systemd 服務執行情境稽核圖
原創概念示意圖:原創圖:同一路徑會同時受到服務身分、根目錄或命名空間、掛載選項與 MAC 政策影響。 Watch at Ease