Ansible: посоветуйте обновить настройки пути управления, когда ssh выдает ошибку "слишком длинный" сокет домена unix

Созданный на 9 июл. 2015  ·  66Комментарии  ·  Источник: ansible/ansible

ТИП ВЫПУСКА

Идея функции

КОМПОНЕНТ НАЗВАНИЕ

контроль ssh сохраняется

ДОСТУПНАЯ ВЕРСИЯ

2.0

РЕЗЮМЕ

При попытке использовать плагин ec2 ssh выдает следующую ошибку:

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

Вот полный пример:

$ 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.

Я изменил здесь некоторую конфиденциальную информацию, например IP-адрес и т. Д.

affects_2.0 affects_2.3 feature

Самый полезный комментарий

Добавил это в мою конфигурацию ansible, чтобы сократить путь:

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

Может быть полезно включить это в сообщение об ошибке или сделать что-нибудь более изящное вместо ошибки.

Все 66 Комментарий

Добавил это в мою конфигурацию ansible, чтобы сократить путь:

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

Может быть полезно включить это в сообщение об ошибке или сделать что-нибудь более изящное вместо ошибки.

для меня такая же ошибка! Я согласен с Люком Хёрстеном в этом исправлении.

Спасибо, что указали на свое решение @LukeHoersten

Без проблем. Надеюсь, мы сможем исправить это. Особенно плохо для новичков.

В доступной конфигурации есть еще одно закомментированное предложение
control_path = %(directory)s/%%h-%%r

Но да, справочное сообщение было бы полезно.

Я просто ударил и это. Я новичок и потратил впустую огромное количество времени. Спасибо за ответ! И я согласен, это нужно исправить.

Я также: +1: за эту фичу.

Столкнулся с этим сегодня. Спасибо за подсказки по поводу ansible.cfg !!

Редактирование control_path не работает в Mac OSX El Capitan.

Это работает для меня в Эль-Капитане:

[ssh_connection]
control_path =% (каталог) s / %% h - %% r

Как отметил @willotter , это одно из закомментированных утверждений в https://raw.githubusercontent.com/ansible/ansible/devel/examples/ansible.cfg

Интересно узнать, почему это проблема - с каких это пор длинные пути становятся проблемой за пределами Windows?

это работает для меня после обновления до EI Capitan.

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

@deyvsh, почему это проблема - с каких это пор длинные пути становятся проблемой вне Windows?

Поскольку El Capitan был выпущен Apple. Помимо страницы на китайском языке, это единственная страница, которая, кажется, ссылается на это новое поведение в MacOS. Я столкнулся с той же проблемой при попытке использовать режим Tramp в emacs, который обеспечивает прозрачный доступ к удаленным файлам через ssh. Та же ошибка, связанная с длинными именами файлов для сокета домена unix, но ее не так просто исправить, как в Ansible.

@cswarth Конфигурация ~/.ssh/config следующим образом:

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

У меня нет Mac OS X, поэтому я не могу это проверить, но это должно работать, если emacs не передает какие-либо конкретные параметры через SSH.

@willotter Мне пришлось адаптировать эту идею и добавить ее в свой файл ansible.cfg, чтобы заставить ее работать.

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

Обновление 2017: похоже, что @willotter больше не существует :(

@LukeHoersten Спасибо за это, проблема исправлена!

Основная причина этого в

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;
    }

Чтобы узнать предел (sizeof (sunaddr.sun_path)), нам нужно посмотреть 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];
           };

Путь ограничен 104 символами, включая терминатор 0.

Это также обсуждается в https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing#Manually_Establishing_Multiplexed_Connections, где также предполагается, что вы используете

Начиная с 6.7, комбинацию% r @% h:% p и ее вариаций можно заменить на% C, который сам по себе генерирует хэш из конкатенации% l% h% p% r.

В конце концов, вы хотите использовать

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

Кроме того, вы хотите держаться подальше от / tmp или любого другого места, доступного для записи и чтения, из-за безопасности.

См. Также http://pastebin.com/ugXKMFsv

@isotopp хорошие предложения. Интересно, почему мы просто не изменим значение по умолчанию на control_path = %(directory)s/%%C чтобы избежать проблем в будущем.

@LukeHoersten Я думаю, что

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

Ping @bcoca - см. Анализ и предлагаемые изменения выше.

+1

потому что он не будет работать на многих ОС / дистрибутивах, которые запускают даже немного более старые версии openssh

Предлагаемое изменение в http://pastebin.com/ugXKMFsv изменяет только документы и комментарии. Будет работать со старыми версиями openssh, но сделает указатель на% C более очевидным.

У меня длинное имя пользователя на моей машине (11 символов), это привело к превышению лимита символов в моем каталоге.

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

Я сбросил -%%r и он решил эту проблему для меня.

Сегодня я столкнулся с этой ошибкой, потому что вместо своего файла инвентаря я предоставил свой файл group_vars, и ansible каким-то образом успешно проанализировал зашифрованный файл и принял что-то вроде 182937891273891723981723891723987189237189237981273981 в качестве имени хоста. SSH тоже не считал это странным, пока не заметил длинный ControlPath. Предупреждение для потомков - запустите все с -vvvv и убедитесь, что вы указываете на правильный хост и все такое.

Спасибо тебе за это. Он исправил ошибку, которая была у меня в OS X El Capitan.

+1
Это просто решило мою проблему с OS X El Capitan.

У меня тоже работал на OS X EL Capitan. Обратите внимание: если вы установили ansible через brew, то файл будет /usr/local/etc/ansible/ansible.cfg

: +1 Это случилось со мной, когда я просто пытался сделать ansible all -i inventory -m ping имея хост с длинным именем, например ec2-XX-XXX-XX-XX.eu-west-1.compute.amazonaws.com

Это сработало для меня на El Capitan:

Я создал файл ansible.cfg в моем текущем каталоге с помощью:

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

Теперь запуск ansible .. не дал мне никаких ошибок ssh.

У меня тоже работал на OS X EL Capitan. Обратите внимание: если вы установили ansible через brew, то это файл /usr/local/etc/ansible/ansible.cfg.

Я - El Capitan, и установил ansible через brew, и он проигнорировал файл /usr/local/etc/ansible/ansible.cfg который я пытался добавить с этими настройками.

@tleyden Это довольно странно, /usr/local/etc/ansible/ansible.cfg у меня отлично работает.

О, я только что понял разницу - я установил ansible через pip install ansible , а не через brew

Почему так странно добавлять в конце строку типа CErvOvRE5U0urCgm ? У меня все ломается из-за этой бесполезной веревки.

Просто добавьте сюда несколько комментариев, чтобы было понятно, какие действия можно предпринять:

  • Документация. Похоже, что предлагаемые обновления документации находятся в сущности, связанной с этим тикетом, но не в PR, поэтому они никогда не были объединены.
  • Лучшее обнаружение ошибок - если используется% C, а ssh не поддерживает его, попросите людей заменить его на% l-% h-% p. Если путь слишком длинный, посоветуйте попробовать% C или просто сократите путь.
  • попробуйте определить, поддерживает ли ssh, который мы используем,% C, и если да, используйте его, в противном случае нет (возможно, это актуально только по умолчанию, а не когда пользователь что-то настраивает в своем файле конфигурации?) Однако будьте осторожны, чтобы соединения не занимали намного больше времени).

Я также добавил:
%(directory)s/%%h‐%%r
Но мой путь все еще слишком длинный? Как я могу это исправить:

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

Я вижу эту проблему с ansible 2.1.0.0 в Ubuntu 16.04

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

Добавление этого в мой ansible.cfg сработало:

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

В качестве альтернативы, изменение длинного доменного имени AWS на IP-адрес также исправило его, даже без изменения ssh_connection.control_path в ansible.cfg.

Как уже говорили другие, эта ошибка не была очевидна при работе с -vvvv. Мне пришлось скопировать команду из вывода отладки и запустить ее непосредственно в терминале, чтобы увидеть ошибку «слишком долго для сокета домена Unix».

У меня такая же проблема.

эта проблема очень раздражает, поскольку приходится переключаться между IP и FQDN в зависимости от машины, на которой запущена книга воспроизведения Ansible ... какое-либо реальное решение, запланированное со стороны Ansible?

@swoodford , возможно, вы можете

Я все еще думаю, что ansible должен изменить dafault.

Очень забавно. Некоторое время назад у нас была такая же проблема в cdist (и мы ищем другую ошибку, связанную с этим). Ограничение sun_path в Unix - это действительно очень старый предел, который укусил всех нас в 2016 году.

Самое простое решение: нет.
2-е лучшее решение: старайтесь, чтобы имя сокета было коротким. Все еще ломается, если домашний каталог - длинный путь
Третье лучшее решение: сохраните его где-нибудь в / tmp / short-random-path / c (нужен только один символ)

Долгосрочное решение: избавиться от ограничения sun_path или увеличить до разумного значения по умолчанию 2016 года (кто-нибудь из группы austin / posix читает здесь?)

Что означает %(directory) ?

@isotopp

Это правильный синтаксис (с префиксом подчеркивания) для помещения в файл ~/.ssh/config ?

ControlMaster auto
ControlPath ~/.ssh/_%C

Это побег, который будет иметь то же значение, что и двойной %% из файла ansible.cfg? Я пытаюсь настроить их обоих так же, как я использую ssh, даже за пределами возможности.

Даже после добавления control_path в мой ansible.cfg в моем проекте я все еще получал эту ошибку, но я вернулся к версии 2.1.3, выполнил ту же команду, которая вызвала ошибку при запуске 2.2.1, и проблема решена.

По-прежнему возникает эта проблема с версией: ansible 2.2.0.0

действительно странный вопрос. ansible 2.2.0.0 на Fedora 24 -> проблема существовала
git head от 2016/07/05 на OSX -> проблема не существует.

@bcoca Я всегда фанат обратной совместимости (да, я отправил это исправление для centos 6.5). как насчет того, чтобы сделать его динамическим в версии openssh / distro, какой путь управления использовать?

он уже является динамическим, посмотрите, как логика «умного» соединения используется по умолчанию

при подключении с хоста на хост, может быть, у вас в рюкзаке нет ssh ключей? :)

С другой стороны,% C не является отличным вариантом по умолчанию прямо сейчас, поскольку EL7 имеет openssh 6.6, а% C не был добавлен до openssh 6.7 и не был перенесен.

Однако вы можете использовать полностью развернутую форму% l% h% p% r на EL7, но это только частично смягчает, поскольку, конечно же, она не будет выполнять хеширование.

Владельцы дистрибутива должны изменить конфигурацию по умолчанию, чтобы она соответствовала поставляемому пакету. Я думаю, что разведка и добыча не должны ждать 7 лет, прежде чем продвигаться вперед с такими важными улучшениями, как это.

Поскольку я все еще использую Ansible версии 2.2 и Ansible Tower 3.1.1, я также столкнулся с этой проблемой. Как ранее указывал @dennisobrien , изменение инвентаризации с доменного имени AWS на IP-адрес AWS решило эту проблему. Однако я сначала попытался использовать в конфигурации только эти переменные, и это не решило проблему:

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

@ b-long, используйте control_path %(directory)s/%%C

На моем сервере возникла эта проблема, и у меня нет прав на ее изменение. Как я могу решить эту проблему на стороне клиента?

@thefourtheye - это чисто проблема клиента, а не сервера. Вы можете найти опцию для установки в вашем файле ansible.cfg ранее в этом потоке.

@antoineco О, спасибо. Я совершенно не знаком с ansible, и на моем компьютере он даже не установлен. Будет ли работать файл ansible.cfg в домашнем каталоге?

У меня такая же проблема, я пробую все решения, включая добавление файла конфигурации .ansible.cfg в ~ /:
[defaults] inventory=/etc/ansible/hosts [ssh_connection] control_path=%(directory)s/%%h-%%r control_path_dir=~/.ansible/cp

И добавьте известный хост и ip в ssh known_hosts. Но это все равно не работает, это Ubuntu на EC2.
Это ошибка:

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

Вы не используете предлагаемое решение - control_path = %(directory)s/%%C .

@akostadinov Спасибо, работает. Здесь слишком много решений.

Здесь слишком много решений.

Если бы только это было сложнее ... прокляните этих поставщиков решений!

Я попытался добавить все предложенные здесь строки в файл ~/ansible.cfg на моем компьютере, но это не помогло. Я сдаюсь.

Что сейчас работает для меня, так это получение IP-адреса машины с помощью nslookup и вход в систему с этим.

@thefourtheye , я не уверен, сколько "предложенных строк" вы видите здесь. Используйте пост с 50+ лайками. Но помимо правильной опции вам нужно использовать файл конфигурации, о котором знает ansible . В вашем случае ~/.ansible.cfg . Постарайтесь обратить внимание на детали, точка перед файлом конфигурации пользователя - это обычное соглашение unix.

@akostadinov Извините, это была опечатка. Вот как это выглядит

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

Я просто хочу вмешаться со своим .ansible.cfg :

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

для меня directory было чем-то смехотворно длинным, последняя часть была просто соломинкой, которая сломала спину верблюду. Также у меня есть это в моем .ssh/config поэтому я могу повторно использовать то же соединение:

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

Извините, но жестко запрограммированный tmp не только не переносится, но и представляет серьезную угрозу безопасности. По уважительным причинам MacOS не позволяет пользователям писать в / tmp и предоставляет изолированные (частные) папки tmp для каждого пользователя.

Tmp будет работать, только если вы используете путь tmp, предоставленный ОС, что-то вроде% (tmp) s ... после исправления ansible.

Ребята, пожалуйста, прочтите существующие комментарии, это смешно, когда все приходят и спрашивают одно и то же, а кто-то добавляет такое же решение. Используйте соответствующий файл конфигурации и см. Https://github.com/ansible/ansible/issues/11536#issuecomment -153030743.

Кто-нибудь, пожалуйста, закройте ветку, чтобы избежать дальнейшего спама.

@ssbarnea harcoded ничего не переносимо ... поэтому это не по умолчанию в ansible ... не уверен, что я согласен с проблемой безопасности или проблемой macOS, поскольку / tmp липкий, а openssh использует разумный режим (0600) для этих файлов.

относительно решения с использованием %C которое требует недавнего openssh ...

Меня не особо интересуют древние версии ssh, особенно на доступном контроллере. Чтобы развиваться, нам нужно забыть о некоторых вещах, и в этом случае это не имеет большого значения, потому что пострадавшие могут изменить конфигурацию, чтобы иметь возможность продолжать ее использовать.

Я считаю, что для пользовательского опыта (UX) Ansible важно предоставить настройки по умолчанию, которые подходят большинству пользователей, сводя к минимуму необходимость в изменениях. Я сомневаюсь, что у нас более 1-2% пользователей используют версии openssh, не поддерживающие %C .

Я думаю, что нам нужно как можно скорее реализовать в Ansible несколько критических переменных INI, потому что каждые две недели мы сталкиваемся с ошибками, вызванными их отсутствием: %(tmpdir)s m $(configdir)s , %(inventorydir)s .

Если бы у нас были эти люди, они смогли бы проложить надежные относительные пути.

К сожалению, в моем случае проблема еще хуже, потому что мы используем Ansible как часть CI, и поскольку, как и у многих, у нас есть несколько узлов Jenkins на одной машине, работающих под одним и тем же пользователем, мы довольно часто сталкивались с хищением сеансов ssh. В любом случае моя проблема более сложная и выходит за рамки этого тикета.

Я исправил эту проблему обычным образом для всех версий ssh ​​6 месяцев назад. Если кто-то видит проблему с Ansible 2.3+, это потому, что вы установили собственный путь управления в ansible.cfg вместо того, чтобы оставлять его пустым.

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 =

Поскольку этот разговор продолжается без ссылки на патч выше, я собираюсь заблокировать его. Если у вас есть дополнительные вопросы по теме, воспользуйтесь списком рассылки.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

hryamzik picture hryamzik  ·  3Комментарии

arkag picture arkag  ·  3Комментарии

rokka-n picture rokka-n  ·  3Комментарии

renaudguerin picture renaudguerin  ·  3Комментарии

greggilbert picture greggilbert  ·  3Комментарии