当我通过 SSH 登录到我的服务器时,我可以通过 ssh 使用 git (私有存储库):
user@local:~$ ssh example.com
Welcome to Ubuntu 14.04.1 LTS (GNU/Linux 2.6.32-042stab083.2 i686)
* Documentation: https://help.ubuntu.com/
Last login: Thu Oct 30 10:46:22 2014 from 123.123.123.123
user@remote:~$ cd ~/path/to/project/
user@remote:~/path/to/project$ git pull
Enter passphrase for key '/home/user/.ssh/id_rsa':
Already up-to-date.
user@remote:~/path/to/project$ ps -aux | grep ssh-agent
user 450 0.0 0.0 4396 832 pts/4 S+ 10:57 0:00 grep ssh-agent
user 32680 0.0 0.0 4168 696 ? Ss 10:50 0:00 ssh-agent
user@remote:~/path/to/project$
但请注意,我必须输入密码,即使在单独的会话中,我使用ssh-add
ssh-agent 添加了密钥。 ssh-agent 仍在运行,如上所示。我以为这会让我使用 ssh 密钥而无需再次输入密码。我错了。
由于我使用的部署脚本涉及克隆或拉取存储库(取决于项目),因此我从 CI 服务器运行它,如下所示:
ssh [email protected] '~/path/to/deployment/script.sh'
结果,我收到“权限被拒绝(公钥)”。错误,因为密钥需要使用密码来解锁,但没有给出任何密码。
除了创建没有密码的 ssh 密钥之外,还有其他方法可以解决此问题吗?
答案1
要连接到ssh-agent
,ssh
客户端(或任何其他进程)需要知道如何连接到它。此信息ssh-agent
在启动时以 shell 命令的形式发出。通常它看起来像这样:
$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-H8yPWdYCNFmT/agent.506989; export SSH_AUTH_SOCK;
SSH_AGENT_PID=506990; export SSH_AGENT_PID;
echo Agent pid 506990;
生成应用程序通常只是评估这些命令以将变量加载到当前进程环境中(然后传播到所有子进程)。
因此,您需要找到适当的套接字以连接到正确的ssh-agent
进程(是的,您可以同时运行多个代理,即使对于一个用户也是如此)。有两种方法可以做到这一点:
检查有问题的代理的 PID 并扫描所有
/tmp/ssh-*
目录中的套接字最近的较低PID(由于ssh-agent
fork成为守护进程,socket名称中使用的PID低于实际守护进程的PID)如果生成相关代理的程序仍在运行(或者它的子代之一正在运行),您可以从其环境中提取信息:
$ strings /proc/<PID>/environ | grep SSH_
始终通过告诉代理应使用哪个套接字来启动代理:
$ ssh-agent -a /path/to/ssh_agent/socket
例如,当您在本地和远程机器上工作时,这也会派上用场 - 您只需将其硬连接到 shell 初始化脚本中,并且当您连接到桌面环境生成代理的机器时,您只需访问已加载的所有密钥即可。使用终端多路复用器等也是如此。