科技 · 實用指南
systemd 顯示 status=203/EXEC?改權限前先稽核失敗的 execve 路徑
203/EXEC 表示服務管理器無法執行設定的程序。應依日誌的精確原因區分目標或解譯器缺失、格式無效、路徑/掛載拒絕與強制存取控制,再做修改。

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 日誌,不要堆疊修正。若路徑或政策屬於套件服務、二進位來源不明或修正會削弱安全邊界,應停止並升級處理。
