Ansible: aconselhar a atualização das configurações de caminho de controle quando ssh lançar o erro 'soquete de domínio unix "muito longo"'

Criado em 9 jul. 2015  ·  66Comentários  ·  Fonte: ansible/ansible

TIPO DE PROBLEMA

Ideia de recurso

NOME DO COMPONENTE

controle ssh persistir

VERSÃO ANSÍVEL

2.0

RESUMO

Ao tentar usar o plug-in ec2, o ssh falha com este erro:

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

Aqui está o exemplo completo:

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

Eu mudei algumas das informações confidenciais aqui, como o IP etc.

affects_2.0 affects_2.3 feature

Comentários muito úteis

Adicionei isso à minha configuração do ansible para encurtar o caminho:

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

Pode ser útil incluir isso na saída de erro ou fazer algo mais elegante em vez de falhar.

Todos 66 comentários

Adicionei isso à minha configuração do ansible para encurtar o caminho:

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

Pode ser útil incluir isso na saída de erro ou fazer algo mais elegante em vez de falhar.

para mim mesmo erro! Eu concordo com LukeHoersten nessa correção.

Obrigado por apontar sua solução @LukeHoersten

Sem problemas. Espero que possamos obter uma solução mais sólida lá. É ruim especialmente para os recém-chegados.

A configuração do ansible tem outra sugestão comentada
control_path = %(directory)s/%%h-%%r

Mas sim, uma mensagem de ajuda seria útil.

Eu apenas acertei isso também. Sou novo e perdi muito tempo. Obrigado pela resposta! E eu concordo, precisa ser consertado.

Eu também: +1: para este recurso.

Enfrentei isso hoje. Obrigado pelas dicas sobre ansible.cfg !!

A edição de control_path não funciona no Mac OSX El Capitan.

Isso funciona para mim em El Capitan:

[ssh_connection]
control_path =% (diretório) s / %% h - %% r

Como @willotter apontou, é uma das declarações comentadas em https://raw.githubusercontent.com/ansible/ansible/devel/examples/ansible.cfg

Interessado em saber por que isso é um problema - desde quando nomes de caminho longos são um problema fora do Windows?

isso funciona para mim após a atualização para o EI Capitan.

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

@deyvsh por que isso é um problema - desde quando nomes de caminho longos são um problema fora do Windows?

Já que El Capitan foi lançado pela Apple. Além de uma página em chinês, esta é a única página que parece fazer referência a esse novo comportamento no MacOS. Encontrei o mesmo problema ao tentar usar o modo Tramp no emacs, que permite acesso transparente a arquivos remotos via ssh. O mesmo erro sobre nomes de arquivo longos para um soquete de domínio Unix, mas não é tão fácil de contornar como no Ansible.

@cswarth A configuração do ansible acabou de ser passada para o seu cliente ssh. Você pode ser capaz de configurar um control_path em seu arquivo de configuração ssh ~/.ssh/config assim:

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

Não tenho Mac OS X, então não posso testar isso, mas deve funcionar, a menos que o emacs passe quaisquer parâmetros específicos para o SSH.

@willotter Tive que adaptar esta ideia e adicioná-la ao meu arquivo ansible.cfg para fazê-lo funcionar.

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

Atualização de 2017: parece que @willotter não existe mais :(

@LukeHoersten Obrigado por isso, corrigiu o problema para mim!

A causa raiz para isso está em

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

Para saber o limite (sizeof (sunaddr.sun_path)), precisamos dar uma olhada em 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];
           };

O caminho é limitado a 104 caracteres, incluindo o terminador 0.

Isso também está sendo discutido em https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing#Manually_Establishing_Multiplexed_Connections que também sugere que você está usando

Começando com 6.7, a combinação de% r @% h:% p e variações dela podem ser substituídas por% C que por si só gera um hash da concatenação de% l% h% p% r.

No final, você deseja usar

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

Além disso, você quer ficar longe de / tmp ou de qualquer outro local gravável e legível mundialmente, por causa da segurança.

Veja também http://pastebin.com/ugXKMFsv

@isotopp boas sugestões. Eu me pergunto por que simplesmente não mudamos o padrão para control_path = %(directory)s/%%C para evitar problemas futuros.

@LukeHoersten Acho que o ansible também deve alterar o padrão. Na verdade, eu fiz

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

Ping @bcoca - veja a análise e as alterações propostas acima.

+1

porque não funcionaria em muitos sistemas operacionais / distros que executam versões um pouco mais antigas do openssh

Alteração proposta em http://pastebin.com/ugXKMFsv altera documentos e comentários apenas. Funcionará com versões antigas do openssh, mas tornará o ponteiro para% C mais óbvio.

Tenho um nome de usuário longo em minha máquina (11 caracteres), o que fez com que meu diretório ultrapassasse o limite de caracteres.

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

Eu deixei cair -%%r e ele resolveu este problema para mim.

Encontrei este erro hoje porque, em vez de meu arquivo de inventário, forneci meu arquivo group_vars e o ansible felizmente analisou o arquivo criptografado de alguma forma e aceitou algo como 182937891273891723981723891723987189237189237981273981 como o nome do host. SSH também não achou isso estranho antes de notar o longo ControlPath. Um aviso para a posteridade - execute tudo com -vvvv e certifique-se de apontar para o host certo e tudo mais.

Obrigado por isso. Ele corrigiu o erro que eu tinha no OS X El Capitan.

+1
Isso apenas resolveu meu problema no OS X El Capitan.

Funcionou para mim também no OS X EL Capitan. Apenas uma observação, se você instalou o ansible através do brew, o arquivo é /usr/local/etc/ansible/ansible.cfg

: +1 Isso aconteceu comigo apenas tentando fazer um ansible all -i inventory -m ping tendo um host com um nome de host longo como ec2-XX-XXX-XX-XX.eu-west-1.compute.amazonaws.com

Isso funcionou para mim no El Capitan:

Eu criei um arquivo ansible.cfg no meu diretório atual com:

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

Agora executando ansible .. não me deu nenhum erro de ssh.

Funcionou para mim também no OS X EL Capitan. Apenas uma observação: se você instalou o ansible por meio do brew, o arquivo é /usr/local/etc/ansible/ansible.cfg

Sou o El Capitan e instalei o ansible via brew, e ele ignorou o arquivo /usr/local/etc/ansible/ansible.cfg que tentei adicionar com essas configurações.

@tleyden Isso é muito estranho, /usr/local/etc/ansible/ansible.cfg funciona bem para mim.

Ah, acabei de perceber a diferença - instalei o ansible via pip install ansible , não via brew

Por que é estranho adicionar strings como CErvOvRE5U0urCgm no final? As coisas se quebram para mim por causa daquele barbante inútil.

Basta adicionar alguns comentários aqui para ficar claro sobre as ações que podem ser tomadas:

  • Documentação. Parece que as atualizações de documentos sugeridas estão em um link essencial deste tíquete, mas não em um PR, então ele nunca foi mesclado.
  • Melhor captura de erros - se% C for usado e o ssh não suportar, diga às pessoas para substituir por% l-% h-% p. Se o caminho for muito longo, diga às pessoas para tentar% C ou simplesmente encurte o caminho.
  • tente detectar se o ssh que estamos usando suporta% C e se sim, faça uso dele, caso contrário, não (talvez isso só seja relevante por padrão, não quando o usuário configura algo em seu arquivo de configuração?) ( ter cuidado para não fazer as conexões demorarem muito mais).

Eu também adicionei:
%(directory)s/%%h‐%%r
Mas meu caminho ainda é muito longo? Como posso consertar isso:

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

Estou vendo este problema com ansible 2.1.0.0 no Ubuntu 16.04

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

Adicionar isso ao meu ansible.cfg funcionou:

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

Como alternativa, alterar o nome de domínio AWS longo para um endereço IP também corrigiu, mesmo sem a alteração para ssh_connection.control_path em ansible.cfg.

Como outros já disseram, esse erro não era aparente durante a execução com -vvvv. Tive que copiar o comando na saída de depuração e executá-lo diretamente em um terminal para ver o erro "muito longo para soquete de domínio Unix".

Eu também estou tendo o mesmo problema.

esse problema tem sido muito chato, ter que alternar entre IPs e FQDNs dependendo da máquina que executa o manual do Ansible ... alguma solução real planejada do lado do Ansible?

@swoodford , talvez você possa registrar um problema com sua distribuição Linux para alterar as configurações padrão. Por exemplo, o mantenedor do fedora modificou o padrão para usar um soquete de controle mais curto. O problema parece ser possível para manter a compatibilidade por padrão com distros antigas. Não tenho certeza se faz sentido porque os usuários de distros mais recentes agora devem ser muito mais. Isso significa que pelo menos as distros mais novas não devem se importar em mudar o padrão durante o empacotamento, porque a distro sabe que é recente o suficiente para trabalhar com a opção mais confiável.

Eu ainda acho que o ansible deveria mudar o padrão.

Muito engraçado. Tivemos o mesmo problema no cdist há algum tempo (e estamos procurando outro bug relacionado a isso). O limite sun_path no Unix é um limite muito, muito antigo que nos incomoda em 2016.

Solução mais fácil: nenhuma.
2ª melhor solução: tente manter o nome do soquete curto. Ainda quebra se o diretório de casa for um longo caminho
3ª melhor solução: armazene-o em algum lugar em / tmp / short-random-path / c (só precisa de um caractere)

Solução de longo prazo: livrar-se do limite sun_path ou aumentar para um padrão sensato de 2016 (alguém do grupo austin / posix lendo aqui?)

O que %(directory) significa?

@isotopp

Esta é a sintaxe correta (com prefixo sublinhado) para colocar dentro do arquivo ~/.ssh/config ?

ControlMaster auto
ControlPath ~/.ssh/_%C

Este é um escape que teria o mesmo significado que o arquivo duplo %% do ansible.cfg? Estou tentando configurar os dois da mesma forma que uso o ssh, mesmo fora do ansible.

Mesmo depois de adicionar control_path ao meu ansible.cfg no meu projeto, ainda recebia esse erro, mas voltei para a versão 2.1.3, executei o mesmo comando que gerou o erro ao executar 2.2.1, e o A questão foi resolvida.

Ainda tendo este problema com a versão: ansible 2.2.0.0

questão realmente estranha. ansible 2.2.0.0 no fedora 24 -> existia problema
git head de 2016/07/05 no OSX -> problem does not exist.

@bcoca eu sempre sou um fã de compatibilidade com versões anteriores (sim, eu enviei aquela correção do centos 6.5). que tal torná-lo dinâmico na versão do openssh / distro, qual controlpath usar?

já é dinâmico, veja a lógica por trás da conexão 'inteligente' sendo o padrão

ao conectar de host para host, talvez você não tenha as chaves SSH em sua mochila? :)

Por outro lado,% C não é um ótimo padrão agora, pois EL7 tem o openssh 6.6, e o% C não foi adicionado até o openssh 6.7 e não foi feito backport.

No entanto, você pode usar a forma totalmente expandida de% l% h% p% r em EL7, mas apenas atenua parcialmente, já que não fará hash, é claro.

Os proprietários da distribuição devem alterar a configuração padrão de acordo com o pacote enviado. Acho que o upstream não deveria esperar 7 anos antes de avançar com melhorias importantes como essa.

Como ainda estou usando o Ansible versão 2.2 e o Ansible Tower 3.1.1, também tive esse problema. Como @dennisobrien apontou anteriormente , mudar o inventário de um nome de domínio da AWS para um endereço IP da AWS resolveu esse problema. No entanto, tentei primeiro usar apenas essas variáveis ​​na configuração e isso não resolveu o problema:

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

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

Meu servidor está com este problema e não tenho permissão para alterá-lo. Como posso resolver no final do cliente?

@thefourtheye é puramente um problema do cliente, não um problema do servidor. Você pode encontrar a opção de definir em seu arquivo ansible.cfg anteriormente neste tópico.

@antoineco Oh, obrigado. Sou totalmente novo no ansible e nem o tenho instalado na minha máquina. Ainda ter o arquivo ansible.cfg no diretório inicial funcionaria?

Eu tenho o mesmo problema, tento todas as soluções incluem adicionar arquivo de configuração .ansible.cfg em ~ /:
[defaults] inventory=/etc/ansible/hosts [ssh_connection] control_path=%(directory)s/%%h-%%r control_path_dir=~/.ansible/cp

E adicione host conhecido e ip a ssh known_hosts. Mas ainda não está funcionando, é ubuntu no EC2.
Este é o erro:

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

Você não está usando a solução proposta, que é control_path = %(directory)s/%%C .

@akostadinov Obrigado, funcionou. Muita solução aqui.

Muita solução aqui.

Se fosse mais difícil ... malditos sejam os provedores de soluções!

Tentei adicionar todas as linhas sugeridas aqui no arquivo ~/ansible.cfg em minha máquina de localização, mas não ajudou. Eu estou desistindo

O que funciona para mim agora é pegar o endereço IP da máquina com nslookup e fazer o login com isso.

@thefourtheye , não tenho certeza de quantas "linhas sugeridas" você vê aqui. Use a postagem com mais de 50 curtidas. Mas além da opção adequada, você precisa usar um arquivo de configuração que o ansible conheça . No seu caso ~/.ansible.cfg . Tente prestar atenção aos detalhes, o ponto na frente do arquivo de configuração do usuário é uma convenção comum do Unix.

@akostadinov Lamento, foi um erro de digitação. É assim que parece

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

Eu só quero intervir com meu .ansible.cfg :

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

para mim, directory era algo ridiculamente longo, a última parte foi apenas a gota que quebrou as costas do camelo. Também tenho isso em meu .ssh/config para que possa reutilizar a mesma conexão:

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

Desculpe, mas o tmp codificado não é apenas portátil, mas também um sério risco à segurança. Por boas razões, o MacOS não permite que os usuários gravem em / tmp e fornece pastas tmp isoladas (privadas) para cada usuário.

Tmp funcionaria apenas se você usar o caminho tmp fornecido pelo sistema operacional, algo como% (tmp) s ... depois de corrigir o ansible.

Pessoal, por favor leiam os comentários existentes, é ridículo todo mundo vir perguntar a mesma coisa e alguém adicionar a mesma solução. Use o arquivo de configuração adequado e consulte https://github.com/ansible/ansible/issues/11536#issuecomment -153030743.

Alguém, feche o tópico para evitar mais spam.

@ssbarnea harcoded qualquer coisa não é portátil ... é por isso que não é o padrão no ansible ... não tenho certeza se concordo sobre o problema de segurança ou o problema do macOS, já que / tmp é pegajoso e o openssh usa um modo sensível (0600) para esses arquivos.

em relação à solução usando %C que requer um openssh recente ...

Eu realmente não me importo com as versões ssh antigas, especialmente no controlador ansible. Para evoluir, precisamos deixar algumas coisas para trás e, neste caso, não é realmente um grande problema porque os afetados podem alterar a configuração para poder continuar a usá-la.

Acho que é essencial para a experiência do usuário (UX) do Ansible, fornecer padrões que atendam à maioria dos usuários, minimizando a necessidade de alterações. Duvido que tenhamos mais de 1-2% dos usuários usando versões do open openssh que não suportam %C .

Acho que precisamos implementar no Ansible algumas variáveis ​​INI críticas o mais rápido possível, porque a cada duas semanas encontramos bugs que são causados ​​pela falta delas: %(tmpdir)s m $(configdir)s , %(inventorydir)s .

Se tivermos essas pessoas seriam capazes de criar caminhos relativos confiáveis.

Infelizmente, no meu caso o problema é ainda pior porque estamos usando Ansible como parte do CI e porque, como muitos, temos vários nós Jenkins na mesma máquina, rodando sob o mesmo usuário, encontramos sequestros de sessão ssh com bastante frequência. De qualquer forma, meu problema é mais complexo e está fora do escopo deste tíquete.

Corrigi este problema de forma genérica para todas as versões do ssh 6 meses atrás. Se alguém está vendo o problema com o Ansible 2.3+, é porque você definiu um caminho de controle personalizado em ansible.cfg em vez de deixá-lo em branco.

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 =

Como essa conversa continua sem fazer referência ao patch acima, vou bloqueá-lo. Se você tiver mais perguntas sobre o assunto, use a lista de e-mails.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

iven picture iven  ·  3Comentários

RaymiiOrg picture RaymiiOrg  ·  3Comentários

hryamzik picture hryamzik  ·  3Comentários

renaudguerin picture renaudguerin  ·  3Comentários

rokka-n picture rokka-n  ·  3Comentários