Capistrano error : could not connect to ssh-agent

Capistrano error : could not connect to ssh-agent

我正在使用带有 Capistrano 部署的基岩。
当我使用命令 bundle exec cap staging deploy:check 时出现身份验证错误:

...
D, [2015-05-09T15:39:53.878464 #15636] DEBUG -- net.ssh.authentication.session[1e34a58]: trying publickey
D, [2015-05-09T15:39:53.878464 #15636] DEBUG -- net.ssh.authentication.agent[1e30d2c]: connecting to ssh-agent
E, [2015-05-09T15:39:53.879447 #15636] ERROR -- net.ssh.authentication.agent[1e30d2c]: could not connect to ssh-agent
E, [2015-05-09T15:39:53.879447 #15636] ERROR -- net.ssh.authentication.session[1e34a58]: all authorization methods failed (tried publickey)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as deploy@SERVER_IP: Authentication failed for user deploy@SERVER_IP
Tasks: TOP => git:check => git:wrapper

Capistrano 无法连接到我服务器上的 ssh-agent。

但我可以通过 SSH 像这样 ssh deploy@SERVER_IP 无需密码登录我的服务器。我把Capistrano Authentication & Authorisation Docs page中的所有指令都删掉了,所以我可以使用像me@localhost $ ssh deploy@one-of-my-servers.com 'hostname; uptime'这样的命令。

如果我输入命令 ssh -A deploy@SERVER_IP 'env | grep SSH_AUTH_SOCK' 我得到结果

SSH_AUTH_SOCK=/tmp/ssh-UweQkw7578/agent.7578

这是我的 deploy.rb 文件:

set :application, 'APP'
set :repo_url, 'URL'
set :branch, :master
set :tmp_dir, '~/tmp'
set :log_level, :info
set :linked_files, fetch(:linked_files, []).push('.env')
set :linked_dirs, fetch(:linked_dirs, []).push('web/app/uploads')

这是我的 staging.rb 文件:

set :stage, :staging
set :deploy_to, -> { "/var/www/vhosts/project/dev" }
server 'SERVER_IP', user: 'deploy', roles: %w{web app}
set :ssh_options, {
  user: 'deploy',
  keys: %w('/c/Users/alexander/.ssh/id_rsa'),
  forward_agent: true,
  auth_methods: %w(publickey),
  verbose: :debug
}
fetch(:default_env).merge!(wp_env: :staging)

Apache 的代理转发代理指令在 sshd_config 文件中启用:AllowAgentForwarding yes

应该如何处理我的配置文件才能使我的部署工作?

Windows 8.1
Ruby 2.2.0
卡皮斯特拉诺 3.2.1
Git Bash

好的,所以我遇到了同样的问题,我花了太长时间弄清楚这里到底发生了什么,结果是 -

  • 对于 windows 上的 ruby,您 必须 运行 pagent,而不是 ssh-agent,Capistrano 和代理转发才能工作 -事实上,几乎任何使用 Windows.
  • 上的 Ruby net-ssh 库的工具

而且我认为这不会改变,至少暂时不会。

代理转发

请参阅 An Illustrated Guide to SSH Agent Forwarding 了解有关代理转发的更多信息,以及关键挑战如何在我们的工作站上结束。

术语

  • workstation - 机器 (Windoa server/desktop/laptop) 我们的 SSH 客户端软件 运行ning 来自,最重要的是,我们的 PKI 私钥存储在(有或没有密码)

  • 部署节点——我们Capistrano部署任务的目标,大部分 就像在 config/deploy.rb 中的 'server' 键中定义的那样,或者 config/deploy/.rb 文件

  • git 回购 - 我们将从中提取代码,首先通过“git 查询 ls-remote" - 我们将通过 SSH 和部署访问这个 git 仓库 节点将使用代理转发将密钥挑战传回给 工作站

  • SSH 客户端软件 - 我们如何连接到远程服务器上的 sshd,以及 它可以访问我们的私钥。可能是 putty,一个 OpenSSH ssh Ruby.

  • 中的客户端或 net-ssh 库

设置

我有一个 Windows 7 工作站盒,带有 Git-Bash 和它的 OpenSSH ssh 客户端,加上来自 Joe Reagle 的脚本,它设置了一些环境说明 ssh-agent 在哪个端口和 pid 上运行的变量。

我也有 Putty 和 Pageant,但最初我只关注 OpenSSH/Git-Bash 工具。

我已经设置了从工作站到部署节点的无密码 ssh,我有 ssh-agent 运行ning,我通过 ssh-add 添加了我的密钥,我有我的 public 密钥注册为 git 存储库的只读访问密钥。

基础知识

所以我们正在尝试使用 SSH 代理转发让 Capistrano 从我们的 Git 仓库拉到我们的部署节点。

现在我们可以通过在部署节点上设置我们的 public SSH 密钥并使用 OpenSSH ssh 客户端来自行测试这一切,以确认我们有无密码 ssh 工作。然后我们可以通过

设置ssh-agent
  1. 启动 ssh-agent 并根据需要设置 SSH_AUTH_SOCK 和 SSH_AGENT_PID。
  2. 通过 ssh-add 将我们的私钥添加到 ssh-agent
  3. 将我们的 public 密钥作为授权密钥添加到 git 存储库
  4. ssh 到部署节点,然后从那里执行 "git ls-remote git@"(或 ssh -T git@)

如果一切都设置正确,这一切都会起作用,所以我们会认为 "ok I can do a 'cap deploy:check'" - 它 失败。

哪里出了问题

我们会得到一个错误

"Error reading response length from authentication socket"

谁告诉我们的?目前还不清楚,但是

  • 不是 git 存储库

  • 它不是部署节点上的 git 客户端

  • 不是部署节点上的 sshd 守护进程想要将密钥质询传回工作站。

它是工作站上的 Ruby ssh 客户端库。

我们怎么知道的

在 deploy.rb 文件的 ssh_options 散列中,我们添加以下内容: 详细::调试

当我们这样做时,我们会看到这条消息

  • 选美未运行宁。

为什么 Capistrano 尝试使用 Pageant 而不是 ssh-agent

当 运行通过 Capistrano 连接时,ssh 客户端与您手动验证时使用的不同。

手工验证时,是OpenSSH ssh客户端。现在是 Ruby.

中的 net-ssh 库

并且在 Windows 上,net-ssh 有这些行

if Net::SSH::Authentication::PLATFORM == :win32
  require 'net/ssh/authentication/pageant'
end

case Net::SSH::Authentication::PLATFORM
when :java_win32
  require 'net/ssh/authentication/agent/java_pageant'
else
  require 'net/ssh/authentication/agent/socket'

所以加载选美是硬编码到 net-ssh 中的。它甚至不会尝试查看您是否在类 unix shell(如 git-bash 或 cygwin)下 运行ning,然后使用 unix 域ssh 代理 SSH_AUTH_SOCK

目前 net-ssh 不尝试打开一个 unix 域命名的套接字。理论上我认为它可以通过 stdlib 中的 UNIXSocket class。但我还没有在 Windows 机器上试验过。