Error de Capistrano: no se pudo conectar con ssh-agent

Estoy usando Bedrock con deployments de Capistrano.
Cuando uso el command bundle exec cap staging deploy:check obtengo un error de authentication:

 ... 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 no pudo conectarse a ssh-agent en mi server.

Pero puedo iniciar session en mi server a través de SSH, como esta ssh deploy@SERVER_IP sin contraseña. Doy todas las instrucciones en la página de Documentos de Autenticación y Autorización de Capistrano , así que puedo usar un command como me@localhost $ ssh deploy@one-of-my-servers.com 'hostname; uptime' me@localhost $ ssh deploy@one-of-my-servers.com 'hostname; uptime' .

Si ingreso el command ssh -A deploy@SERVER_IP 'env | grep SSH_AUTH_SOCK' ssh -A deploy@SERVER_IP 'env | grep SSH_AUTH_SOCK' obtengo el resultado

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

Aquí está mi file deploy.rb:

 set :application, 'dyxovka-special' set :repo_url, 'git@github.com:tanzoor/dyxovka-wp-theme.git' 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') 

Aquí está mi file 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) 

La instrucción del agente de reenvío de agente Apache está habilitada en el file sshd_config: AllowAgentForwarding yes

¿Qué debería hacer con mis files de configuration para que mi implementación funcione?

Windows 8.1
Ruby 2.2.0
Capistrano 3.2.1
Git Bash

OK, así que tuve el mismo problema, y ​​pasé demasiado time trabajando exactamente lo que está sucediendo aquí, y el resultado es –

  • para ruby ​​en Windows, debe ejecutar pagent, no ssh-agent, para que Capistrano y el reenvío de agente funcionen, de hecho, prácticamente cualquier herramienta que use la biblioteca Ruby net-ssh en Windows.

Y no creo que eso cambie, al less por un time.

Reenvío de agente

Consulte una guía ilustrada para el reenvío de agentes SSH para get más información sobre el reenvío de agentes y cómo el desafío key finaliza en nuestra estación de trabajo.

Terminología

  • estación de trabajo: la máquina (server Windowa / computadora de escritorio / computadora portátil) de la que se ejecuta nuestro software de cliente SSH y, lo que es más importante, nuestra key privada PKI está almacenada (con o sin frase de contraseña)

  • nodo de implementación: el objective de nuestra tarea de implementación de Capistrano, tal como se define en la key 'server' en nuestro file config / deploy.rb, o config / deploy / .rb

  • git repo – de dónde sacaremos el código, consultado primero a través de "git ls-remote" – accederemos a este git repo a través de SSH, y el nodo de implementación usará el reenvío de agentes para pasar el desafío key a la estación de trabajo

  • Software de cliente SSH: cómo llegar a sshd en serveres remotos y que tiene acceso a nuestra key privada. Podría ser putty, un cliente OpenSSH ssh o la biblioteca net-ssh en Ruby.

Preparar

Tengo una caja de estación de trabajo con Windows 7, con Git-Bash, y su cliente OpenSSH ssh, más el script de Joe Reagle que establece algunas variables ambientales que dicen en qué puerto y pid está funcionando el ssh-agent.

También tengo masilla y desfile, pero me centré, inicialmente, solo en las herramientas OpenSSH / Git-Bash.

He configurado ssh sin contraseña desde la estación de trabajo al nodo de implementación, tengo el ssh-agent en ejecución, tengo mi key agregada a través de ssh-add, y tengo mi key pública registrada como key de acceso de solo lectura para el git repo .

Lo esencial

Así que estamos tratando de utilizar el reenvío de agente SSH para que Capistrano extraiga de nuestro repository de Git en nuestro nodo de deployment.

Ahora podemos probar esto nosotros mismos configurando nuestra key SSH pública en el nodo de deployment y utilizando, por ejemplo, el cliente OpenSSH ssh, para confirmar que tenemos ssh sin contraseña funcionando. Entonces podemos configurar ssh-agent por

  1. iniciando ssh-agent y configurando SSH_AUTH_SOCK y SSH_AGENT_PID según sea necesario.
  2. agregando nuestra key privada al ssh-agent a través de ssh-add
  3. agregue nuestra key pública como key autorizada para el repository git
  4. ssh al nodo de deployment, y desde allí hacer un "git ls-remote git @" (o un ssh -T git @)

Si todo está configurado correctamente, todo funcionará, por lo que pensaremos "ok, puedo hacer un 'deployment cap': verificar '", y fallará.

Qué salió mal

Obtendremos un error

"Error al leer la longitud de respuesta del socket de authentication"

¿Quién nos está diciendo esto? No está inmediatamente claro, pero

  • no es el repo git

  • no es el cliente git en el nodo de deployment

  • no es el daemon sshd en el nodo de deployment, que quiere pasar el desafío key a la estación de trabajo.

Es la biblioteca cliente de Ruby ssh en la estación de trabajo.

Cómo sabemos esto

En el hash ssh_options en el file deploy.rb, agregamos lo siguiente: verbose:: debug

Cuando hacemos esto, vemos este post

  • El concurso no se está ejecutando.

¿Por qué Capistrano intenta usar el concurso en lugar de ssh-agent?

Cuando se ejecuta a través de Capistrano, el cliente ssh es diferente al que usó al verificar las cosas a mano.

Al verificar manualmente, era un cliente OpenSSH ssh. Ahora es la biblioteca net-ssh en Ruby.

Y en Windows, net-ssh tiene estas líneas

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

o

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

Entonces cargar el concurso está codificado en net-ssh. Ni siquiera trata de ver si se está ejecutando bajo un shell unix (como git-bash o cygwin), y luego usa el ssh-agent SSD_AUTH_SOCK de unix-domain

En la actualidad, net-ssh no intenta abrir un socket con nombre de dominio Unix. En teoría, creo que podría, a través de la class UNIXSocket en stdlib. Pero aún no he experimentado con eso en una máquina con Windows.