MacOS Monterey cron睡眠时无法访问带口令的SSH密钥求助
问题
运行Monterey 12.6的MacStudio上,ksh脚本通过ssh连接NAS服务器,终端执行和Mac未睡眠时cron任务均正常,但系统睡眠/锁屏后执行cron出现权限拒绝错误:
Permission denied, please try again. Permission denied, please try again. AdminID@10.0.0.135: Permission denied (publickey,password).
环境细节
- 用管理员权限用户创建cron任务
- SSH密钥带口令,口令存储在「local items」密钥链,NAS侧已配置对应公钥(NAS的AdminID是本地MyUserID的别名)
.ssh/config配置:
Host * AddKeysToAgent yes UseKeychain yes IdentityFile ~/.ssh/id_rsa User MyUserID
- 脚本内容:
if [[ $SSH_AGENT_SOCK == "" ]]; then export SSH_AGENT_SOCK=$(/usr/sbin/lsof -a -w -p $(pgrep ssh-agent) -U -F -n | \ sed -n 's/^n//p') fi ssh -v -p 123 AdminID@10.0.0.135 exit
- cron邮件关键错误日志:
debug1: Server accepts key: /Users/MyUserID/.ssh/id_rsa RSA SHA256:/fsQmP5UzRhE7Z08P3J5p362K3jPotWq3JxnVPccIMs explicit debug1: read_passphrase: can't open /dev/tty: Device not configured
已确认SSH_AGENT_SOCK路径正常,推测问题为锁屏/睡眠时无法从密钥链读取密钥口令,尝试「当显示器关闭时防止自动睡眠」无效,暂不想使用无口令密钥或root运行cron。
可行解决路径
方案1:调整密钥链访问权限(推荐,适配家用场景)
- 打开「钥匙串访问」应用,搜索找到存储SSH密钥口令的条目(关键词如
id_rsa) - 右键条目选择「显示简介」,切换到「访问控制」标签页
- 取消勾选「确认在允许访问前需要此钥匙串密码」
- 点击「+」按钮,添加以下程序到允许访问列表:
/usr/bin/ssh/usr/bin/ssh-agent- 你的ksh脚本路径(如
/Users/MyUserID/bin/BackupTasks.sh)
- 关闭窗口并输入密钥链密码保存更改
设置后,ssh及相关进程无需交互即可读取密钥口令,锁屏/睡眠状态下也能正常访问。
方案2:改用launchd替代cron(更适配macOS的任务调度)
macOS原生的launchd比cron更适配系统状态,能更好处理密钥链和SSH agent的权限问题:
- 在
~/Library/LaunchAgents/目录下创建plist配置文件,例如com.user.backup.tasks.plist:
<?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.user.backup.tasks</string> <key>ProgramArguments</key> <array> <string>/Users/MyUserID/bin/BackupTasks.sh</string> </array> <key>StartCalendarInterval</key> <dict> <key>Hour</key> <integer>14</integer> <key>Minute</key> <integer>57</integer> </dict> <key>StandardOutPath</key> <string>/Users/MyUserID/logs/backup_out.log</string> <key>StandardErrorPath</key> <string>/Users/MyUserID/logs/backup_err.log</string> <key>RunAtLoad</key> <false/> </dict> </plist>
- 加载launchd任务:
launchctl load ~/Library/LaunchAgents/com.user.backup.tasks.plist
- 如需测试,可手动触发执行:
launchctl start com.user.backup.tasks
launchd会继承用户会话的完整环境,包括SSH agent和密钥链访问权限,锁屏状态下也能正常执行任务。
方案3:预加载密钥到SSH agent并持久化
- 根据你使用的shell,修改
~/.zshrc或~/.bash_profile,添加:
ssh-add -K ~/.ssh/id_rsa
-K参数会将密钥口令存入密钥链,每次用户登录时自动加载密钥到agent
2. 重启终端或执行source ~/.zshrc(对应shell配置文件)使设置生效
3. 确认密钥已加载:执行ssh-add -l查看已加载的密钥列表
这样cron任务执行时,SSH agent中已有预加载的密钥,无需再从密钥链读取口令。
内容的提问来源于stack exchange,提问作者ric982
相关产品推荐
相关产品推荐

