如何在 Mac 上使用 ssh-agent 作为系统服务

如何在 Mac 上使用 ssh-agent 作为系统服务

我想将 ssh-agent 作为系统服务运行,因此我运行一个全局 ssh-agent,可以从所有 shell 和 GUI 程序访问。在 Linux 上,我遵循这些说明作为 systemd 用户服务运行ssh-agent,并且运行良好。ssh-agent在启动时自动启动,并且一切都可以通过变量访问代理SSH_AUTH_SOCK

在 Mac 上,我在做同样的事情时遇到了麻烦。服务ssh-agent正在运行并导出一个SSH_AUTH_SOCK变量。该变量指向一个全局可读的套接字。但是,当我尝试使用时ssh-add,我得到“没有这样的文件或目录”。我该如何让它工作?

$ launchctl list | grep com.openssh.ssh-agent
90829   -9      com.openssh.ssh-agent
$ pgrep ssh-agent
90829
$ launchctl print gui/501/com.openssh.ssh-agent | grep SSH_AUTH
                SSH_AUTH_SOCK => /private/tmp/com.apple.launchd.PktEMOxKOJ/Listeners
                        secure key = SSH_AUTH_SOCK
$ file $SSH_AUTH_SOCK
/private/tmp/com.apple.launchd.PktEMOxKOJ/Listeners: socket
$ stat -f '%Sp' $SSH_AUTH_SOCK
srw-rw-rw-
$ ssh-add -l
Error connecting to agent: No such file or directory

我是这样设置SSH_AUTH_SOCK的:.bash_profile

# linux ssh-agent
[ -z "$XDG_RUNTIME_DIR" ] && export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"

# mac ssh-agent (dealing with weirdly inconsistent socket path)
[ -d /private/tmp/com.apple.launchd.* ] && export SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.*/Listeners

Mac 的实现感觉真的很粗糙,但我不确定如何处理它每次启动时创建不同的路径。

注意:我知道你可以ssh-agent在 shell 中启动像这样。我发现在 Linux 上将其作为系统服务进行管理会更干净,并且想知道这种方法在 Mac 上是否可行。

答案1

我认为基本问题是 shell 在分配给变量时不会扩展通配符,因此SSH_AUTH_SOCK不会将其设置为套接字的实际路径,而是将其设置为未扩展的通配符,该通配符不指向任何实际项目。

当您使用 测试它时stat -f '%Sp' $SSH_AUTH_SOCK,变量引用没有双引号,因此它会在该点扩展通配符表达式。但该扩展是一个 shell 函数;ssh 在查找套接字时不会执行此操作,因此您会收到错误。尝试stat -f '%Sp' "$SSH_AUTH_SOCK"在 shell 中查看此效果。

一个可能的解决方法是分配给一个数组(其中你立即扩展通配符)而不是普通变量:

# mac ssh-agent (dealing with weirdly inconsistent socket path)
possible_sockets=(/private/tmp/com.apple.launchd.*/Listeners)
if [[ ${#possible_sockets[@]} -gt 0 ]]; then
    echo "Found multiple possible ssh-agent sockets; you should probably investigate this." >&2
fi
for possible_socket in "${possible_sockets[@]}"; do
    if [[ -e "$possible_socket" ]]; then
        export SSH_AUTH_SOCK="$possible_socket"
        break
    fi
done

我添加了对多个匹配项的检查,因为这似乎是一种脆弱的做事方式。我还没有尝试过这个,但我很想用它来ssh-agent -a /some/predictable/path将套接字放在一个确定的位置。

相关内容