Sudo

為什麼 cron 在我的腳本中默默地無法執行 sudo 的東西?

  • January 28, 2022

我有一個從非特權使用者的 crontab 執行的腳本,該腳本使用sudo. 除非它沒有。該腳本執行良好,但 sudo 的命令靜默失敗。

  • 該腳本作為相關使用者從 shell 完美執行。
  • Sudo 不需要密碼。有問題的使用者在 中(root) NOPASSWD: ALL授予訪問權限/etc/sudoers
  • Cron 正在執行並執行腳本。添加一個簡單date > /tmp/log的在正確的時間產生輸出。
  • 這不是權限問題。再次執行腳本,而不是 sudo 的命令。
  • 這不是路徑問題。從正在執行env的腳本內部執行會顯示$PATH包含 sudo 路徑的正確變數。使用完整路徑執行它沒有幫助。正在執行的命令被賦予完整的路徑名。
  • 嘗試擷取包括 STDERR 在內的 sudo 命令的輸出並沒有顯示任何有用的資訊。添加sudo echo test 2>&1 > /tmp/log到腳本會產生一個空白日誌。
  • sudo 二進製文件本身執行良好,並且即使在腳本內從 cron 執行時也能辨識出它具有權限。添加sudo -l > /tmp/log到腳本會產生輸出:

使用者 ec2-user 可以在此主機上執行以下命令:

(root) NOPASSWD: ALL

使用檢查命令的退出程式碼$?顯示它返回錯誤(退出程式碼:)1,但似乎沒有產生錯誤。一個簡單的命令/usr/bin/sudo /bin/echo test返回相同的錯誤程式碼。

還有什麼可能發生的?

這是最近創建的執行最新 Amazon Linux AMI 的虛擬機。crontab 屬於使用者ec2-user,sudoers 文件是分發預設值。

sudo在其權限文件中有一些特殊選項,其中一個允許限制其對在 a 中執行的 shell 的使用,但事實TTY並非cron如此。

包括 Amazon Linux AMI 在內的一些發行版預設啟用此功能。該/etc/sudoers文件將如下所示:

# Disable "ssh hostname sudo <cmd>", because it will show the password in clear.
#         You have to run "ssh -t hostname sudo <cmd>".
#
Defaults    requiretty

#
# Refuse to run if unable to disable echo on the tty. This setting should also be
# changed in order to be able to use sudo without a tty. See requiretty above.
#
Defaults   !visiblepw

如果您STDERR在 shell 腳本級別而不是 sudo 命令本身擷取了輸出,您會看到類似這樣的消息:

抱歉,您必須有一個 tty 才能執行 sudo

解決方案是允許 sudoTTY通過刪除或註釋掉這些選項在非環境中執行:

#Defaults    requiretty
#Defaults   !visiblepw

引用自:https://unix.stackexchange.com/questions/49077