Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學

Linux root 切換用戶獲取 $? 異常歸零案例:/etc/security 權限導致 su 失敗

編輯:Linux 系統常見問題解答

問題現象

在 NBU 備份 I2000 數據庫、ideploy 自動升級環境檢查等場景中,腳本通過 su - user -c "command" 執行命令,命令本身成功(如 ls 正常輸出),但緊隨其後的 echo $? 返回 1 而非預期的 0,導致上層邏輯判定失敗、流程中斷。

NDMC21:~ # su - sshusr -c "ls";echo $?
bin breeze check.sh Documents ideploy_file_history nohup.out public_html
1

排查過程

  1. 初步懷疑命令本身失敗,但 ls 明顯成功輸出。
  2. 檢查 /var/log/messages、secure、su 相關日志,無明顯報錯。
  3. 收集 strace -f su - sshusr -c "ls" 系統調用跟蹤,發現 su 進程在讀取 /etc/security/ 目錄下文件時返回 EACCES(權限拒絕)。
  4. 對比正常機器,發現 /etc/security 目錄權限被安全加固腳本從 755 (drwxr-xr-x) 改為 600 (drw-------),導致非 root 用戶無法遍歷該目錄,su 內部 PAM 模塊讀取 access.conf、limits.conf 等配置失敗,最終導致 su 返回非零退出碼。

根因分析

su 命令在切換用戶上下文時,會調用 PAM(Pluggable Authentication Modules)堆疊。pam_access.so、pam_limits.so 等模塊需要讀取 /etc/security/ 下的配置文件。若目錄權限為 600(無執行位 x),非 root 用戶無法 cd 進入或 stat 目錄內文件,PAM 模塊報錯,導致 su 整體返回失敗碼,即使用戶命令實際執行成功。

驗證與修復

# 確認異常權限
ls -ld /etc/security/
# drw------- 2 root root 368 Jul 12 00:24 /etc/security/

# 修復權限(恢復標準 755)
chmod 755 /etc/security

# 再次測試
su - sshusr -c "ls";echo $?
# bin breeze check.sh Documents ideploy_file_history nohup.out public_html
# 0  <-- 返回碼歸零,問題解決

經驗總結

  • 安全加固需謹慎:修改系統關鍵目錄(/etc、/var、/usr、/lib、/bin、/sbin)權限前,必須在測試環境全流程驗證 su、sudo、ssh、cron、systemd 服務啟動等核心功能。
  • 目錄執行位(x)的含義:目錄的 x 權限控制「能否進入目錄(cd)、能否訪問目錄內文件元數據」。600 只允許 root 讀寫目錄條目,普通用戶完全不可見。
  • 退出碼 $? 的來源:$? 反映的是上一條命令(此處為 su)的退出狀態,而非 su -c 內部命令的退出碼。若需獲取內部命令退出碼,需在 -c 字符串內處理或通過文件傳遞。
  • 排查思路:遇到「命令成功但 $? 非零」先 strace 定位系統調用失敗點,再結合權限、SELinux、PAM、審計日志綜合分析。

參考鏈接: 原文博客 | 作者:Bosco (QQ: 375612082)

Copyright © Windows教程網 All Rights Reserved