web-dev-qa-db-fra.com

Transfert de l'agent SSH avec Ansible

J'utilise Ansible 1.5.3 et Git avec le transfert d’agent ssh ( https://help.github.com/articles/using-ssh-agent-forwarding ). Je peux me connecter au serveur que je gère avec Ansible et vérifier que ma connexion à git est correctement configurée:

ubuntu@test:~$ ssh -T [email protected]
Hi gituser! You've successfully authenticated, but GitHub does not provide Shell access.

Je peux également cloner et mettre à jour un de mes dépôts avec ce compte pour que ma configuration git soit correcte et utilise le transfert ssh lorsque je me connecte à mon serveur directement via ssh.

Le problème: lorsque je tente le même test que celui présenté ci-dessus à l’aide du module de commande Ansible. Il échoue avec "permission refusée". Une partie de la sortie Ansible (avec journalisation détaillée) ressemble à ceci:

failed: [xxx.xxxxx.com] => {"changed": true, "cmd": ["ssh", "-T", "[email protected]"], "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).

Voici le playbook simple qui exécute cette commande:

- hosts: webservers
  Sudo: yes
  remote_user: ubuntu

  tasks:

  - name: Test that git ssh connection is working.
    command: ssh -T [email protected]

La question: pourquoi tout fonctionne correctement lorsque je me connecte manuellement via ssh et que je lance la commande, mais échoue lorsque la même commande est exécutée sous le même utilisateur via Ansible?

Je posterai la réponse sous peu si personne d’autre ne m’y bat. Bien que j'utilise git pour démontrer le problème, il peut arriver avec tout module dépendant du transfert de l'agent ssh. Ce n'est pas spécifique à Ansible mais je suppose que beaucoup rencontreront d'abord le problème dans ce scénario.

62
Bob Barcklay

Le problème est résolu en supprimant cette ligne du livre de jeu:

Sudo: yes

Lorsque Sudo est exécuté sur l'hôte distant, les variables d'environnement définies par ssh lors de la connexion ne sont plus disponibles. En particulier, SSH_AUTH_SOCK, qui "identifie le chemin d'un socket de domaine UNIX utilisé pour communiquer avec l'agent", n'est plus visible et le transfert de l'agent ssh ne fonctionne donc pas.

Éviter Sudo lorsque vous n'en avez pas besoin est un moyen de contourner le problème. Une autre méthode consiste à s'assurer que SSH_AUTH_SOCK reste fidèle à votre session Sudo en créant un fichier sudoers:

/etc/sudoers:

     Defaults    env_keep += "SSH_AUTH_SOCK"
49
Bob Barcklay

Il y a ici des réponses partielles très utiles, mais après avoir rencontré ce problème plusieurs fois, je pense qu'un aperçu serait utile.

Tout d'abord, vous devez vous assurer que le transfert de l'agent SSH est activé lors de la connexion de votre client exécutant Ansible à la machine cible. Même avec transport=smart, Le transfert de l'agent SSH peut ne pas être activé automatiquement, selon la configuration SSH de votre client. Pour vous en assurer, vous pouvez mettre à jour votre ~/.ansible.cfg pour inclure cette section:

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

Ensuite, vous devrez probablement faire face au fait que become: yes (et become_user: root) désactivera généralement le transfert d’agent car le SSH_AUTH_SOCK La variable d’environnement est réinitialisée. (Je trouve choquant que Ansible semble supposer que les utilisateurs utiliseront SSH en tant que root, car cela rend impossible tout audit utile.) Il existe plusieurs moyens de gérer cela. Depuis Ansible 2.2, l’approche la plus simple consiste à préserver l’environnement (entier) lors de l’utilisation de Sudo en spécifiant le paramètre -E drapeau:

become_flags: "-E"

Cependant, cela peut avoir des effets secondaires indésirables en préservant des variables telles que PATH. L’approche la plus propre consiste à ne conserver que SSH_AUTH_SOCK en l'incluant dans env_keep dans votre /etc/sudoers fichier:

Defaults    env_keep += "SSH_AUTH_SOCK"

Pour faire cela avec 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"'

Cette tâche est un peu plus conservatrice que certaines des suggestions suggérées, car elle ajoute ceci après tout autre défaut env_keep paramètres (ou à la fin du fichier, si aucun fichier n’est trouvé), sans modifier aucun fichier env_keep réglages ou en supposant que SSH_AUTH_SOCK est déjà présent.

30
Trevor Robinson

Une autre réponse à votre question (à l'exception que j'utilise Ansible 1.9) pourrait être la suivante:

Vous voudrez peut-être vérifier votre /etc/ansible/ansible.cfg (ou les trois autres emplacements potentiels où les paramètres de configuration peuvent être remplacés) pour transport=smart comme recommandé dans la documentation ansible . Le mien était par défaut à transport=paramiko à un moment donné lors d’une tentative d’installation précédente, empêchant ainsi mon ordinateur de contrôle d’utiliser OpenSSH, et donc le transfert d’agent. Il s’agit probablement d’une affaire massive, mais qui sait? Ça pourrait être vous!

Bien que je n’ai pas trouvé cela nécessaire pour ma configuration, je dois noter que d’autres ont mentionné que vous devriez ajouter -o ForwardAgent=yes à votre paramètre ssh_args dans le même fichier comme ceci:

[ssh_connection]
ssh_args=-o ForwardAgent=yes

Je ne le mentionne ici que par souci d'exhaustivité.

26
swendr

Pour développer la réponse de @ j.freckle, la meilleure façon de changer le fichier sudoers est la suivante:

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