Reenvío de agente SSH con Ansible

Estoy usando Ansible 1.5.3 y Git con reenvío de agente ssh ( https://help.github.com/articles/using-ssh-agent-forwarding ). Puedo iniciar session en el server que estoy administrando con Ansible y probar que mi connection a git está configurada correctamente:

ubuntu@test:~$ ssh -T git@github.com Hi gituser! You've successfully authenticated, but GitHub does not provide shell access. 

También puedo clonar y actualizar uno de mis repos usando esta count para que mi configuration de git se vea bien y use ssh forwarding cuando inicio session en mi server directamente a través de ssh.

El problema: cuando bash la misma testing que se muestra arriba utilizando el module de command Ansible. Falla con "Permiso denegado". Parte de la salida de Ansible (con logging detallado) se ve así:

 failed: [xxx.xxxxx.com] => {"changed": true, "cmd": ["ssh", "-T", "git@github.com"], "delta": "0:00:00.585481", "end": "2014-06-09 14:11:37.410907", "rc": 255, "start": "2014-06-09 14:11:36.825426"} stderr: Permission denied (publickey). 

Aquí está el libro de jugadas simple que ejecuta este command:

 - hosts: webservers sudo: yes remote_user: ubuntu tasks: - name: Test that git ssh connection is working. command: ssh -T git@github.com 

La pregunta: ¿por qué todo funciona correctamente cuando inicio session manualmente a través de ssh y ejecuto el command pero fallo cuando el mismo command se ejecuta como el mismo usuario a través de Ansible?

Voy a publicar la respuesta en breve si nadie más me golpea. Aunque estoy usando git para demostrar el problema, podría ocurrir con cualquier module que dependa del reenvío del agente ssh. No es específico de Ansible, pero sospecho que muchos primero encontrarán el problema en este escenario.

El problema se resuelve eliminando esta línea del libro de jugadas:

 sudo: yes 

Cuando sudo se ejecuta en el host remoto, las variables de entorno establecidas por ssh durante el inicio de session ya no están disponibles. En particular, SSH_AUTH_SOCK, que "identifica la ruta de un socket de dominio UNIX utilizado para comunicarse con el agente" ya no está visible, por lo que el reenvío de agente ssh no funciona.

Evitar sudo cuando no lo necesita es una forma de evitar el problema. Otra forma es asegurar que SSH_AUTH_SOCK permanezca durante su session de sudo creando un file sudoers:

 /etc/sudoers: Defaults env_keep += "SSH_AUTH_SOCK" 

Otra respuesta a su pregunta (con la exception de que estoy usando Ansible 1.9) podría ser la siguiente:

Es posible que desee verificar su /etc/ansible/ansible.cfg (u otras tres ubicaciones posibles donde se pueden anular las configuraciones) para transport=smart tal como se recomienda en los documentos ansible . La mía había pnetworkingeterminado transport=paramiko en algún momento durante un bash de installation anterior, lo que impedía que mi máquina de control utilizara OpenSSH y, por lo tanto, el reenvío de agentes. Este es probablemente un caso de borde masivo, pero ¿quién sabe? ¡Podría ser usted!

Aunque no -o ForwardAgent=yes fuera necesario para mi configuration, debería tener en count que otros han mencionado que debe agregar -o ForwardAgent=yes a su configuration de ssh_args en el mismo file, como sigue:

 [ssh_connection] ssh_args=-o ForwardAgent=yes 

Solo lo menciono aquí por el bien de lo completo.

Para ampliar la respuesta de @ j.freckle, la forma más fácil de cambiar el file sudoers es:

 - name: Add ssh agent line to sudoers lineinfile: dest: /etc/sudoers state: present regexp: SSH_AUTH_SOCK line: Defaults env_keep += "SSH_AUTH_SOCK" 

Aquí hay algunas respuestas parciales muy útiles, pero después de toparme con este tema varias veces, creo que una descripción general sería útil.

En primer lugar, debe asegurarse de que el reenvío de agente SSH esté habilitado al conectarse desde su cliente que ejecuta Ansible a la máquina de destino. Incluso con transport=smart , el reenvío de agente SSH puede no habilitarse automáticamente, dependiendo de la configuration SSH de su cliente. Para asegurarse de que sea así, puede actualizar su ~/.ansible.cfg para include esta sección:

 [ssh_connection] ssh_args=-o ControlMaster=auto -o ControlPersist=60s -o ControlPath=/tmp/ansible-ssh-%h-%p-%r -o ForwardAgent=yes 

A continuación, es probable que tenga que lidiar con el hecho de que become: yes (y become_user: root ) generalmente deshabilitará el reenvío del agente porque la variable de entorno SSH_AUTH_SOCK se restablece. (Me parece sorprendente que Ansible parezca suponer que las personas usarán SSH como root, ya que eso imposibilita cualquier auditoría útil). Hay algunas maneras de lidiar con esto. A partir de Ansible 2.2, el enfoque más fácil es preservar el entorno (completo) al usar sudo especificando el indicador -E :

 become_flags: "-E" 

Sin embargo, esto puede tener efectos secundarios no deseados al preservar variables como PATH . El enfoque más limpio es conservar solo SSH_AUTH_SOCK incluyéndolo en env_keep en su /etc/sudoers :

 Defaults env_keep += "SSH_AUTH_SOCK" 

Para hacer esto con Ansible:

 - name: enable SSH forwarding for sudo lineinfile: dest: /etc/sudoers insertafter: '^#?\s*Defaults\s+env_keep\b' line: 'Defaults env_keep += "SSH_AUTH_SOCK"' 

Esta tarea de libro de jugadas es un poco más conservadora que otras sugeridas, ya que agrega esto después de cualquier otra configuration pnetworkingeterminada de env_keep (o al final del file, si no se encuentra), sin cambiar ninguna configuration env_keep existente o asumiendo que SSH_AUTH_SOCK es ya presente.