ssh-under-cron在OS X 10.7 Lion中停止工作


12

从Snow Leopard升级到Lion,我使用ssh的cron作业已停止工作。似乎ssh-agent不再按预期运行。

这是我的Cron脚本的Bowdlerized版本,在Snow Leopard下效果很好:

#!/bin/bash
whoami # just to verify I'm running as myself, not root
ssh-agent # just to see what it outputs    
eval `ssh-agent`
ssh -vvv REMOTESERVER ls

从命令提示符处运行时,此脚本将按预期工作。

从cron运行时,它不起作用。ssh-agent输出看起来很正常:

SSH_AUTH_SOCK=/tmp/ssh-QRxPUMRxbu/agent.17147; export SSH_AUTH_SOCK;
SSH_AGENT_PID=17148; export SSH_AGENT_PID;
echo Agent pid 17148;
Agent pid 17150

但是ssh -vvv输出显示,当应读取私钥时,它会失败:

debug1: Server accepts key: pkalg ssh-dss blen 818
debug2: input_userauth_pk_ok: fp ...
debug3: sign_and_send_pubkey: DSA ...
debug1: PEM_read_PrivateKey failed
debug1: read PEM private key done: type <unknown>
debug1: read_passphrase: can't open /dev/tty: Device not configured
debug2: no passphrase given, try next key

换句话说,期望我输入的密码~/.ssh/id_dsa,这当然在cron作业中不起作用。

这一切都在雪豹中发挥了作用。

请注意,我有钥匙串访问设置,使sshssh-agentssh-add被允许阅读我的密码我的.ssh/id_dsa文件-作为一个结果,我可以从一个终端提示SSH连接时无需输入密码我。

ssh-add在登录过程中是否需要运行此问题?从标准的bash提示符运行它并不能帮助cron完成工作(尽管,奇怪的是,它确实提示我输入密码...我认为这不是钥匙串访问配置的必要条件)。

注意1-在重定向我之前-我知道这里有一个类似的问题( Mac OS X Lion和sshpass),但这是专门针对sshpass我不使用的程序的(尽管我相信这个问题也可以回答) )。

注2 –我意识到无密码的SSH密钥可以解决我的问题;但是我不想走这条路。


2
cron不见了。请参阅此处的启动标签以获取各种帮助(请采取行动-它可以处理端口,环境,并且比cron以往要好得多)-我确实希望有人能找到解决方案,但是cron mojo在一定程度上已经老化了。
bmike

3
cron仍然在Lion中运行...但是您是对的,我应该采取行动。但是,一个10行以上的XML文件可以完成单个ron crontab的工作。也许十年后,他们会将plist文件切换为JSON,这将带来很多欢乐,而十年后,他们将回到crontab,而BSD灰胡子会大笑。我想届时我将成为BSD灰胡子...
John Hart

1
刚刚切换到启动状态,作品魅力十足。被调用的脚本根本不需要与ssh-agent进行交互-您可以在hashbang之后直接跳入ssh命令。如果您的评论是一个答案,我会接受=)
约翰·哈特

在许多情况下,JSON肯定比XML更为出色,但是之前的所有恳求者都可能导致了该问题。我很高兴我们有一个统一,高效,结构化的基于数据的替代产品。cron并确保我们长期以来为我们服务!
bmike

我一直在寻找其他网络资源的高低,但是我总是回到这篇文章。当然有人可以为讨论做出更多贡献吗?我试图使用一个简单的plist来运行我的shell脚本,但是mailx不会发送我的通知。我仍然喜欢cron,并且一直在Ubuntu中使用它。我不想回到10.6,但是这个问题使我丧命。我不喜欢被迫使用launchctl并不得不学习对我来说感觉像是一个非常扩展的框架,该框架基本上可以自动执行shell脚本。有人有新见解吗?

Answers:


10

对于最终访问此页面的人,我意识到我应该发布答案:

使用launchd代替cron确实可以解决授权问题。您的用户启动的作业(仅在您登录时才运行)正确使用了通过密钥链解锁的SSH代理信息,这是登录的一部分(作为标准OS X密钥管理的一部分,不需要其他软件)。

为了最大程度地减少与Launchd的交互,我创建了一个称为bash脚本的已启动作业。这样,我可以简单地编辑脚本而无需处理启动。

这是启动的文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.mycron.hourly</string>

  <key>ProgramArguments</key>
  <array>
    <string>/Users/john/bin/cron.hourly</string>
  </array>

  <key>Nice</key>
  <integer>1</integer>

  <key>StartInterval</key>
  <integer>3600</integer> <!-- start every X seconds -->

  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

我将文件保存到~/Library/LaunchAgents/com.mycron.hourly.plist,然后加载了:

launchctl load ~/Library/LaunchAgents/com.mycron.hourly.plist

加载后,它将立即运行,然后每60分钟重新运行一次。

如果遵循相同的步骤,则需要使用脚本的正确路径更改`ProgramArguments'字符串。


2
实际上,至少在Lion中已弃用cron。寻找答案的荣誉-最初很难破解launchctl。
zwerdlds 2012年

7

在您的bash shell脚本中添加以下代码将解决此问题:

declare -x SSH_AUTH_SOCK=$( find /tmp/launch-*/Listeners -user your_user -type s | head -1 )

your_user用您自己的用户名替换。

此代码设置了正确的值,用于从shell脚本启动时SSH_AUTH_SOCK通知sshscp如何与之通信。ssh-agentcron


这解决了我遇到的一个问题,尽管它通过常规命令行(iTerm或Terminal)可以正常工作,但是在shell脚本中通过scp无法启动它。很棒的小费。
TJ Luoma

仅作记录,就在El Captain 10.11.2上:zsh: no matches found: /tmp/launch-*/Listeners
Ivan Balashov

1

我希望沙盒等增强的安全性以及将内容进一步移动到64位的更改会引起意外的麻烦。

从本质上讲,这不是一个答案,但是,推出这些天正吸引着苹果的所有喜爱。

它并不能解决cron的问题,但是它会更加稳定,并且有更多的人可以提供帮助。


那里的答案很好。感谢您发布。
bmike

1

对于现在发现此问题,试图在El Capitan中进行这项工作并且仍然不愿意将您的单行cron工作转换为已启动脚本的任何人,Werner Antweiler的答案仍然有效,但是路径已经改变。下面为我​​工作:

declare -x SSH_AUTH_SOCK=$(find /var/folders/*/*/*/*/agent.* -user your_user -type s | head -1)

注意:请记住用您的用户名替换your_user!

因为我没有声誉,所以我不能以此作为对他的回答的评论,但是我不想离开她而不更新它,因为它无疑帮助我最终建立了它。

编辑: 2016年3月30日

在测试了一段时间之后,我需要补充一点,它仅在该登录期间至少使用过一次代理后才起作用。启动ssh连接或手动运行ssh-agent足以完成此操作。如果您希望启动脚本自动运行,也可以使用它。我创建了一个仅运行ssh-agent的startup.sh,然后使用脚本编辑器保存了以下内容的.app并将生成的应用程序添加到我的登录项中:

do shell script "/path/to/startup.sh"

我正在解决这个问题,这不是最好的方法。启动显然是要走的路,但是对于cron,您想在钥匙串中设置ssh钥匙(带有密码)。完成此操作后,只需登录Mac即可完成所有设置。如果您手动运行ssh-agent(并手动键入密码),则将保留发布的套接字路径。在El Cap上,加载钥匙串后,可通过找到插座ls /private/tmp/com.apple.launchd.*/Listeners。除了登录到Mac,您无需执行任何其他操作。

推出绝对是实现此目标的“官方”方法,但是对于那些想继续使用cron的人来说,这确实是一个可行的解决方法。在我的测试中,仅登录不足以使保存的钥匙串钥匙通过cron起作用。您列出的路径确实确实存在。如果您在登录后立即生成了该文件,但仍适用于cron,则可能足以跳过我列出的启动脚本方法。当然至少值得测试-谢谢!
佩蒂

我将其放置在一个备份过程中,并且在整个重启过程中,它一直在干净地运行-跨重新启动。
2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.