Ansible: conseiller de mettre à jour les paramètres de chemin de contrôle lorsque ssh renvoie l'erreur « unix domaine socket « trop long » »

Créé le 9 juil. 2015  ·  66Commentaires  ·  Source: ansible/ansible

TYPE DE PROBLEME

Idée de fonctionnalité

NOM DU COMPOSANT

le contrôle ssh persiste

VERSION ANSIBLE

2.0

SOMMAIRE

Lorsque vous essayez d'utiliser le plugin ec2, ssh échoue avec cette erreur :

SSH Error: unix_listener: "/Users/luke/.ansible/cp/ansible-ssh-ec2-255-255-255-255.compute-1.amazonaws.com-22-ubuntu.CErvOvRE5U0urCgm" too long for Unix domain socket

Voici l'exemple complet :

$ ansible -vvvv -i ec2.py -u ubuntu us-east-1 -m ping
<ec2-255-255-255-255.compute-1.amazonaws.com> ESTABLISH CONNECTION FOR USER: ubuntu
<ec2-255-255-255-255.compute-1.amazonaws.com> REMOTE_MODULE ping
<ec2-255-255-255-255.compute-1.amazonaws.com> EXEC ssh -C -tt -vvv -o ControlMaster=auto -o ControlPersist=60s -o ControlPath="/Users/luke/.ansible/cp/ansible-ssh-%h-%p-%r" -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 ec2-255-255-255-255.compute-1.amazonaws.com /bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1436458336.4-21039895766180 && chmod a+rx $HOME/.ansible/tmp/ansible-tmp-1436458336.4-21039895766180 && echo $HOME/.ansible/tmp/ansible-tmp-1436458336.4-21039895766180'
ec2-255-255-255-255.compute-1.amazonaws.com | FAILED => SSH Error: unix_listener: "/Users/luke/.ansible/cp/ansible-ssh-ec2-255-255-255-255.compute-1.amazonaws.com-22-ubuntu.CErvOvRE5U0urCgm" too long for Unix domain socket
    while connecting to 255.255.255.255:22
It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.

J'ai modifié certaines des informations sensibles ici, comme l'adresse IP, etc.

affects_2.0 affects_2.3 feature

Commentaire le plus utile

J'ai ajouté ceci à ma configuration ansible pour raccourcir le chemin :

[ssh_connection]
control_path = %(directory)s/%%h-%%p-%%r

Il peut être utile d'inclure cela dans la sortie d'erreur ou de faire autre chose de plus gracieux au lieu d'échouer.

Tous les 66 commentaires

J'ai ajouté ceci à ma configuration ansible pour raccourcir le chemin :

[ssh_connection]
control_path = %(directory)s/%%h-%%p-%%r

Il peut être utile d'inclure cela dans la sortie d'erreur ou de faire autre chose de plus gracieux au lieu d'échouer.

pour moi même erreur ! Je suis d'accord avec LukeHoersten dans ce correctif.

Merci d'avoir indiqué votre solution @LukeHoersten

Aucun problème. Espérons que nous pourrons y trouver une solution plus solide. C'est particulièrement mauvais pour les nouveaux arrivants.

La configuration ansible a une autre suggestion commentée
control_path = %(directory)s/%%h-%%r

Mais oui, un message d'aide serait utile.

Je viens de frapper ça aussi. Je suis nouveau et j'ai perdu énormément de temps. Merci d'avoir répondu! Et je suis d'accord, doit être corrigé.

J'ai aussi :+1: pour cette fonctionnalité.

Face à cela aujourd'hui. Merci pour les conseils sur ansible.cfg !!

La modification de control_path ne fonctionne pas sur Mac OSX El Capitan.

Cela fonctionne pour moi à El Capitan :

[ssh_connexion]
chemin_contrôle = %(répertoire)s/%%h-%%r

Comme @willotter l'a souligné, c'est l'une des déclarations commentées dans https://raw.githubusercontent.com/ansible/ansible/devel/examples/ansible.cfg

Intéressé de savoir pourquoi c'est un problème - depuis quand les noms de chemin longs sont-ils un problème en dehors de Windows ?

cela fonctionne pour moi après la mise à niveau vers EI Capitan.

[ssh_connection]
control_path = %(directory)s/%%h-%%p-%%r

@deyvsh pourquoi c'est un problème - depuis quand les noms de chemin longs sont-ils un problème en dehors de Windows ?

Depuis El Capitan a été publié par Apple. Hormis une page en chinois, c'est la seule page qui semble faire référence à ce nouveau comportement dans MacOS. J'ai rencontré le même problème en essayant d'utiliser le mode Tramp dans emacs qui permet un accès transparent aux fichiers distants via ssh. Même erreur sur les noms de fichiers longs pour un socket de domaine unix, mais pas aussi facile à contourner que dans Ansible.

@cswarth La configuration ansible est juste transmise à votre client ssh. Vous pourrez peut-être configurer un control_path dans votre fichier de configuration ssh ~/.ssh/config comme ceci :

Host *
  ControlPath /tmp/%r@%h:%p

Je n'ai pas Mac OS X, je ne peux donc pas tester cela, mais cela devrait fonctionner à moins qu'emacs ne transmette des paramètres spécifiques à SSH.

@willotter J'ai dû adapter cette idée et l'ajouter à mon fichier ansible.cfg pour que cela fonctionne.

[ssh_connection]
control_path = /tmp/%%h-%%p-%%r

Mise à jour 2017 : on dirait que @willotter n'existe plus :(

@LukeHoersten Merci pour cela, a résolu le problème pour moi !

La cause principale de ceci est à

https://github.com/openssh/openssh-portable/blob/9ada37d36003a77902e90a3214981e417457cf13/misc.c#L1070

int
unix_listener(const char *path, int backlog, int unlink_first)
{
    struct sockaddr_un sunaddr;
    int saved_errno, sock;

    memset(&sunaddr, 0, sizeof(sunaddr));
    sunaddr.sun_family = AF_UNIX;
    if (strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) {
        error("%s: \"%s\" too long for Unix domain socket", __func__,
            path);
        errno = ENAMETOOLONG;
        return -1;
    }

Pour connaître la limite (sizeof(sunaddr.sun_path)), nous devons regarder https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man4/unix.4.html

           struct sockaddr_un {
                   u_char  sun_len;
                   u_char  sun_family;
                   char    sun_path[104];
           };

Le chemin est limité à 104 caractères, y compris le terminateur 0.

Ceci est également discuté dans https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing#Manually_Establishing_Multiplexed_Connections qui suggère également que vous utilisez

À partir de la version 6.7, la combinaison de %r@%h:%p et de ses variantes peut être remplacée par %C qui, à lui seul, génère un hachage à partir de la concaténation de %l%h%p%r.

En fin de compte, vous voulez utiliser

[ssh_connection]
control_path = %(directory)s/%%C

De plus, vous voulez rester en dehors de /tmp ou de tout autre emplacement accessible en écriture et lisible par le monde, car la sécurité.

Voir aussi http://pastebin.com/ugXKMFsv

@isotopp bonnes suggestions. Je me demande pourquoi nous ne changeons pas la valeur par défaut en control_path = %(directory)s/%%C pour éviter de futurs problèmes.

@LukeHoersten Je pense qu'ansible devrait également changer la valeur par défaut. En fait, j'ai fait

[:~] $ grep -i control ~/.ssh/config
ControlMaster auto
ControlPath ~/.ssh/_%C

Ping @bcoca - voir l'analyse et les modifications proposées ci-dessus.

+1

car cela ne fonctionnerait pas sur de nombreux systèmes d'exploitation/distributions qui exécutent des versions légèrement plus anciennes d'opensh

Le changement proposé dans http://pastebin.com/ugXKMFsv modifie uniquement la documentation et les commentaires. Fonctionnera avec les anciennes versions d'opensh, mais rendra le pointeur vers %C plus évident.

J'ai un nom d'utilisateur long sur ma machine (11 caractères), ce qui a fait que mon répertoire a dépassé la limite de caractères.

https://github.com/ansible/ansible/blob/devel/examples/ansible.cfg#L216 -L225

J'ai laissé tomber le -%%r et cela a résolu ce problème pour moi.

J'ai rencontré cette erreur aujourd'hui car au lieu de mon fichier d'inventaire, j'ai fourni mon fichier group_vars et ansible a heureusement analysé le fichier crypté d'une manière ou d'une autre et accepté quelque chose comme 182937891273891723981723891723987189237189237981273981 comme nom d'hôte. SSH ne pensait pas non plus que c'était bizarre avant de remarquer le long ControlPath. Un avertissement pour la postérité - exécutez tout avec -vvvv et assurez-vous de pointer vers le bon hôte et tout ça.

Merci pour ça. Cela a corrigé l'erreur que j'avais sur OS X El Capitan.

+1
Cela vient de résoudre mon problème sur OS X El Capitan.

A également travaillé pour moi sur OS X EL Capitan. Juste une note, si vous avez installé ansible via brew, alors le fichier est /usr/local/etc/ansible/ansible.cfg

:+1 Cela m'est arrivé juste en essayant de faire un ansible all -i inventory -m ping avec un hôte avec un nom d'hôte long comme ec2-XX-XXX-XX-XX.eu-west-1.compute.amazonaws.com

Cela a fonctionné pour moi sur El Capitan:

J'ai créé un fichier ansible.cfg dans mon répertoire actuel avec :

[ssh_connection]
control_path = %(directory)s/%%C

Maintenant, l'exécution de ansible .. ne m'a donné aucune erreur ssh.

A également travaillé pour moi sur OS X EL Capitan. Juste une note, si vous avez installé ansible via brew, alors le fichier est /usr/local/etc/ansible/ansible.cfg

Je suis El Capitan et j'ai installé ansible via brew, et il a ignoré le fichier /usr/local/etc/ansible/ansible.cfg que j'ai essayé d'ajouter avec ces paramètres.

@tleyden C'est assez étrange, /usr/local/etc/ansible/ansible.cfg fonctionne bien pour moi.

Oh, je viens de réaliser la différence - j'ai installé ansible via pip install ansible , pas via brew

Pourquoi ajoute-t-il une chaîne comme CErvOvRE5U0urCgm à la fin ? Les choses se cassent pour moi à cause de cette ficelle inutile.

Ajoutez simplement quelques commentaires ici pour être clair sur les actions qui peuvent être prises :

  • Documentation. On dirait que les mises à jour de doc suggérées sont dans un résumé lié à ce ticket mais pas dans un PR, donc il n'a jamais été fusionné.
  • Meilleure détection des erreurs -- Si %C est utilisé et que ssh ne le prend pas en charge, dites aux gens de remplacer par %l-%h-%p. Si le chemin est trop long, dites aux gens d'essayer %C ou de raccourcir simplement le chemin.
  • essayez de détecter si le ssh que nous utilisons prend en charge %C et si c'est le cas, utilisez-le, sinon ne le faites pas (cela n'est peut-être pertinent que par défaut, pas lorsque l'utilisateur configure quelque chose dans son fichier de configuration ?) (Avoir faire attention à ne pas faire des connexions beaucoup plus longtemps, cependant).

J'ai aussi ajouté :
%(directory)s/%%h‐%%r
Mais mon chemin est encore trop long ? Comment puis-je réparer cela:

SSH Error: unix_listener: "/Users/myfullname/.ansible/cp/ec2-xx-xx-xx-xx.eu-central-1.compute.amazonaws.com-centos.AAZFTHkT5xXXXXXX" too long for Unix domain socket
    while connecting to 52.xx.xx.xx:22

Je vois ce problème avec ansible 2.1.0.0 sur Ubuntu 16.04

$ ssh -V
OpenSSH_7.2p2 Ubuntu-4ubuntu1, OpenSSL 1.0.2g-fips  1 Mar 2016

L'ajout de ceci à mon ansible.cfg a fonctionné :

[ssh_connection]
control_path=%(directory)s/%%h-%%p-%%r

Alternativement, la modification du long nom de domaine AWS en une adresse IP l'a également corrigé, même sans la modification de ssh_connection.control_path dans ansible.cfg.

Comme d'autres l'ont dit, cette erreur n'était pas apparente lors de l'exécution avec -vvvv. J'ai dû copier la commande dans la sortie de débogage et l'exécuter directement dans un terminal pour voir l'erreur "trop ​​longue pour le socket de domaine Unix".

J'ai aussi le même problème.

ce problème a été super ennuyeux, devoir basculer entre les IP et les FQDN en fonction de la machine exécutant le playbook Ansible... une vraie solution prévue du côté d'Ansible ?

@swoodford , vous pouvez peut-être

Je pense toujours que ansible devrait changer par défaut.

Très drôle. Nous avons eu le même problème dans cdist il y a quelque temps (et nous examinons un autre bogue lié à cela). La limite sun_path dans Unix est une très, très vieille limite qui nous mord tous en 2016.

Solution la plus simple : aucune.
2ème meilleure solution : essayez de garder le nom de socket court. Casse toujours si le répertoire d'accueil est un long chemin
3ème meilleure solution: stockez-le quelque part dans /tmp/short-random-path/c (juste besoin d'un caractère)

Solution à long terme : supprimez la limite sun_path ou augmentez à une valeur par défaut sensible de 2016 (quelqu'un du groupe austin / posix lit ici ?)

Que signifie le %(directory) ?

@isotopp

Est-ce la bonne syntaxe (avec le préfixe souligné) pour mettre dans le fichier ~/.ssh/config ?

ControlMaster auto
ControlPath ~/.ssh/_%C

Est-ce un échappement qui aurait la même signification que le double %% du fichier ansible.cfg ? J'essaie de les configurer tous les deux de la même manière que j'utilise ssh même en dehors d'ansible.

Même après avoir ajouté le control_path à mon ansible.cfg dans mon projet, j'obtenais toujours cette erreur mais je suis revenu à la version 2.1.3, j'ai exécuté la même commande qui a généré l'erreur lors de l'exécution de 2.2.1, et le problème a été résolu.

Toujours ce problème avec la version : ansible 2.2.0.0

problème vraiment étrange. ansible 2.2.0.0 sur fedora 24 -> un problème existait
git head du 2016/07/05 sur OSX -> le problème n'existe pas.

@bcoca, je suis toujours fan de la rétrocompatibilité (oui, j'ai envoyé ce correctif centos 6.5). qu'en est-il de le rendre dynamique sur la version openssh/distro quel chemin de contrôle utiliser ?

il est déjà dynamique, voyez la logique derrière la connexion « intelligente » étant la valeur par défaut

lors de la connexion d'hôte à hôte, vous n'avez peut-être pas de clés ssh dans votre sac à dos ? :)

Sur une note latérale, %C n'est pas un excellent paramètre par défaut pour le moment, car EL7 a openssh 6.6 et %C n'a été ajouté qu'à openssh 6.7 et n'a pas été rétroporté.

Vous pouvez cependant utiliser la forme entièrement développée de %l%h%p%r sur EL7, mais cela n'atténue que partiellement car il ne fera pas de hachage bien sûr.

Ce devrait être aux propriétaires de la distribution de modifier la configuration par défaut pour s'adapter au package expédié. Je pense qu'en amont il ne faut pas attendre 7 ans avant d'avancer avec des améliorations importantes comme celle-ci.

Comme j'utilise toujours Ansible version 2.2 et Ansible Tower 3.1.1, j'ai également rencontré ce problème. Comme @dennisobrien l'a souligné précédemment , la modification de l'inventaire d'un nom de domaine AWS en une adresse IP AWS a résolu ce problème. Cependant, j'ai d'abord essayé d'utiliser uniquement ces variables dans la configuration, et cela n'a pas résolu le problème :

---
ssh_connection:
  control_path: "%(directory)s/%%h-%%p-%%r"

@b-long , utilisez control_path %(directory)s/%%C

Mon serveur a ce problème et je n'ai pas les autorisations pour le modifier. Comment puis-je le résoudre du côté du client ?

@thefourtheye c'est purement un problème de client, pas un problème de serveur. Vous pouvez trouver l'option à définir dans votre fichier ansible.cfg plus tôt dans ce fil.

@antoineco Oh, merci. Je suis totalement nouveau sur ansible et je ne l'ai même pas installé sur ma machine. Avoir toujours le fichier ansible.cfg dans le répertoire personnel fonctionnerait-il ?

J'ai le même problème, j'essaie toutes les solutions, notamment l'ajout du fichier de configuration .ansible.cfg dans ~/ :
[defaults] inventory=/etc/ansible/hosts [ssh_connection] control_path=%(directory)s/%%h-%%r control_path_dir=~/.ansible/cp

Et ajoutez know host et ip à sshknown_hosts. Mais ça ne marche toujours pas, c'est Ubuntu sur EC2.
C'est l'erreur :

fatal: [default]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Warning: Permanently added 'ec2-xx-192-174-42.ap-northeast-1.compute.amazonaws.com,xx.192.174.42' (ECDSA) to the list of known hosts.\r\nunix_listener: \"/Users/name/.ansible/cp/ec2-xx-192-174-42.ap-northeast-1.compute.amazonaws.com-ubuntu.1fndG2vtHPliheeZ\" too long for Unix domain socket\r\n", "unreachable": true

Vous n'utilisez pas la solution proposée qui est control_path = %(directory)s/%%C .

@akostadinov Merci, ça marche. Trop de solution ici.

Trop de solution ici.

Si seulement c'était plus dur... maudis ces fournisseurs de solutions !

J'ai essayé d'ajouter toutes les lignes suggérées ici dans le fichier ~/ansible.cfg de ma machine de localisation, mais cela n'a pas aidé. J'abandonne.

Ce qui fonctionne pour moi maintenant, c'est d'obtenir l'adresse IP de la machine avec nslookup et de se connecter avec.

@thefourtheye , je ne sais pas combien de "lignes suggérées" vous voyez ici. Utilisez la publication avec plus de 50 likes. Mais en plus de l'option appropriée, vous devez utiliser un fichier de configuration qu'ansible connaît . Dans votre cas ~/.ansible.cfg . Essayez de faire attention aux détails, le point devant le fichier de configuration de l'utilisateur est une convention Unix courante.

@akostadinov Je suis désolé, c'était une faute de frappe. C'est à ça que ça ressemble

➜  ~ cat ~/.ansible.cfg
[ssh_connection]
control_path = %(directory)s/%%h-%%p-%%r

Je veux juste intervenir avec mon .ansible.cfg :

[ssh_connection]
control_path = /tmp/control_%%l_%%h_%%p_%%r

pour moi, directory était quelque chose de ridiculement long, la dernière partie n'était que la goutte d'eau qui a fait déborder le vase. J'ai aussi ceci dans mon .ssh/config pour pouvoir réutiliser la même connexion :

ControlMaster                    auto
ControlPath                      /tmp/control_%l_%h_%p_%r

Désolé, mais tmp codé en dur n'est pas seulement portable, mais constitue également un risque sérieux pour la sécurité. Pour de bonnes raisons, MacOS ne permet pas aux utilisateurs d'écrire dans /tmp et fournit des dossiers tmp isolés (privés) pour chaque utilisateur.

Tmp ne fonctionnerait que si vous utilisez le chemin tmp fourni par le système d'exploitation, quelque chose comme %(tmp)s ... après avoir patché ansible.

Les gars, veuillez lire les commentaires existants, c'est ridicule que tout le monde vienne demander la même chose et que quelqu'un ajoute la même solution. Utilisez le fichier de configuration approprié et consultez https://github.com/ansible/ansible/issues/11536#issuecomment -153030743.

Quelqu'un, s'il vous plaît fermer le fil pour éviter d'autres spams.

@ssbarnea harcoded tout n'est pas portable... c'est pourquoi ce n'est pas la valeur par défaut dans ansible... je ne suis pas sûr d'être d'accord sur le problème de sécurité ou le problème macOS car /tmp est collant et openssh utilise un mode sensible (0600) pour ces fichiers.

concernant la solution utilisant %C qui nécessite un openssh récent...

Je ne me soucie pas vraiment des anciennes versions de ssh, en particulier sur le contrôleur ansible. Afin d'évoluer, nous devons laisser peu de choses derrière nous et dans ce cas ce n'est pas vraiment grave car les personnes concernées pourraient changer de configuration afin de pouvoir continuer à l'utiliser.

Je pense qu'il est essentiel pour l'expérience utilisateur (UX) d'Ansible de fournir des valeurs par défaut qui conviendront à la plupart des utilisateurs, en minimisant le besoin de changement. Je doute que nous ayons plus de 1 à 2% d'utilisateurs utilisant des versions d'openshsh qui ne prennent pas en charge %C .

Je pense que nous devons implémenter dans Ansible quelques variables INI critiques dès que possible, car toutes les deux semaines, nous rencontrons des bogues causés par leur manque : %(tmpdir)s m $(configdir)s , %(inventorydir)s .

Si nous avons ces personnes, nous pourrions créer des chemins relatifs fiables.

Malheureusement, dans mon cas, le problème est encore pire car nous utilisons Ansible dans le cadre de CI et parce que, comme beaucoup, nous avons plusieurs nœuds Jenkins sur la même machine, fonctionnant sous le même utilisateur, nous avons rencontré assez souvent des détournements de session ssh. Quoi qu'il en soit, mon problème est plus complexe et sort du cadre de ce billet.

J'ai corrigé ce problème de manière générique pour toutes les versions de ssh il y a 6 mois. Si quelqu'un voit le problème avec Ansible 2.3+, c'est parce que vous avez défini un chemin de contrôle personnalisé dans ansible.cfg au lieu de le laisser vide.

https://github.com/ansible/ansible/commit/ac78347f2bc4a489c7e254c6c1d950fb45f240ad

https://github.com/ansible/ansible/blob/devel/examples/ansible.cfg#L360 -L367

# The path to use for the ControlPath sockets. This defaults to a hashed string of the hostname, 
# port and username (empty string in the config). The hash mitigates a common problem users 
# found with long hostames and the conventional %(directory)s/ansible-ssh-%%h-%%p-%%r format. 
# In those cases, a "too long for Unix domain socket" ssh error would occur.
#
# Example:
# control_path = %(directory)s/%%h-%%r
#control_path =

Étant donné que cette conversation continue sans faire référence au correctif ci-dessus, je vais la verrouiller. Si vous avez d'autres questions sur le sujet, veuillez utiliser la liste de diffusion.

Cette page vous a été utile?
0 / 5 - 0 notes