有一個非常奇怪的問題。我創建了一個小型 bash 腳本,它透過 ssh 在遠端主機上運行命令(使用公鑰身份驗證)。
當我從命令列手動運行此腳本時,它工作正常,但當放置在 /etc/cron.hourly 中時,它會失敗並出現Permission denied, please try again.
錯誤。
ssh -i /root/.ssh/id_rsa user@remote "command"
我使用;在腳本中明確設定密鑰- 該腳本以 root 身份運行(我添加了一個
echo `id` > /tmp/whoami.log
來仔細檢查);和 - ssh 金鑰不受密碼保護...
系統是 Ubuntu 12.04 伺服器,我在遠端沒有太多存取權限來進行故障排除,但正如我所說,手動執行 ssh 或從命令列運行相同的 bash 腳本是可行的。
知道為什麼會發生這種情況或如何解決它嗎?
更新
事實證明我錯了,ssh 密鑰曾是受密碼保護(使用鑰匙串載入 ssh 代理程式),因此它從腳本中失敗,但從 bash 會話執行時卻失敗。添加. ~/.keychain/$HOSTNAME-sh
到我的腳本解決了問題(感謝@grawity,他為我指明了正確的方向並提供了全面的答案)。
答案1
互動式命令和 cron 作業在不同的環境中運作 - 特別是,互動式會話可能運行 SSH 代理,或儲存 Kerberos TGT。由於ssh
訂購身份驗證方法的方式,您不能確保您的金鑰僅因為您新增了該-i
選項而被使用。
如果 SSH 代理正在執行,
ssh
則用戶端總是會嘗試代理金鑰前使用任何明確指定的鍵。如果網路使用 Kerberos 並且存在 Kerberos TGT,OpenSSH 將使用它前嘗試公鑰身份驗證。
我對您的環境一無所知,但這兩種可能性都很容易檢查:
在命令之前添加
unset SSH_AUTH_SOCK
and ,unset KRB5CCNAME
ssh
然後手動運行修改後的腳本。這將阻止腳本查看代理或 Kerberos 票證,並且僅使用明確指定的金鑰。
將
-v
選項新增至ssh
.這將顯示有關身份驗證如何發生的更多詳細資訊。
您也可以添加-oIdentitiesOnly=yes
到命令中ssh
;這會強制它使用指定的鍵。
如果您添加有關從 cron 訪問代理的提示 - 那就更好了
通常不建議這樣做,因為代理通常與您的互動式登入工作階段緊密相關。特別是,它僅在您登入時啟動,並在您登出時終止 - 並且它需要您的密碼才能實際解鎖 SSH 金鑰(假設它們受密碼保護)。
您提到「Keychain」——這是 OS X 程式還是 Linux 腳本? (我對 Mac OS X 的架構了解不多,但據我所知,它使得它很多從 cronjob 存取用戶的 ssh 代理程式更困難...)
答案2
此問題的另一個解決方法是將 cron 設為 ssh 到本機框,以依序執行 ssh 命令,而不是透過其本地絕對路徑來執行檔案或命令。這會快取 KRB5CCNAME 並在 /path/command 不起作用的地方起作用。
# Fails:
0 * * * * /home/user/sshscript.sh
# Works:
0 * * * * /usr/bin/ssh user@localhost /home/user/sshscript.sh
#!/bin/bash
# Works:
unset SSH_AUTH_SOCK
unset KRB5CCNAME
/usr/bin/ssh user@localhost /home/user/sshscript.sh
答案3
您可以使用ssh cron設定計劃的 SSH 連接到安全伺服器,而不暴露您的 SSH 金鑰,而是使用 SSH 代理。
答案4
您可以在 crontab 中執行腳本或命令,例如:
0 * * * * bash -c -l “/home/user/sshscript.sh”
或者
0 * * * * bash -c -l“ssh root@yourhost 'echo $HOSTNAME'”