Ansible: Aconsejar actualizar la configuración de la ruta de control cuando ssh arroja el error 'socket de dominio unix "demasiado largo"'

Creado en 9 jul. 2015  ·  66Comentarios  ·  Fuente: ansible/ansible

TIPO DE PROBLEMA

Idea característica

NOMBRE DEL COMPONENTE

persiste el control ssh

VERSION ANSIBLE

2.0

RESUMEN

Al intentar usar el complemento ec2, ssh falla con este error:

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

Aquí está el ejemplo 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.

He cambiado parte de la información confidencial aquí, como la IP, etc.

affects_2.0 affects_2.3 feature

Comentario más útil

Agregué esto a mi configuración ansible para acortar la ruta:

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

Podría ser útil incluir eso en la salida de error o hacer algo más elegante en lugar de fallar.

Todos 66 comentarios

Agregué esto a mi configuración ansible para acortar la ruta:

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

Podría ser útil incluir eso en la salida de error o hacer algo más elegante en lugar de fallar.

para mi mismo error! Estoy de acuerdo con LukeHoersten en esta solución.

Gracias por señalar su solución @LukeHoersten

No hay problema. Ojalá podamos conseguir una solución más sólida allí. Es especialmente malo para los recién llegados.

La configuración ansible tiene otra sugerencia comentada
control_path = %(directory)s/%%h-%%r

Pero sí, un mensaje de ayuda sería útil.

Solo le di a esto también. Soy nuevo y he perdido mucho tiempo. ¡Gracias por la respuesta! Y estoy de acuerdo, necesita ser arreglado.

Yo también: +1: para esta función.

Enfrenté eso hoy. ¡¡Gracias por las sugerencias sobre ansible.cfg !!

La edición de control_path no funciona en Mac OSX El Capitan.

Esto me funciona en El Capitán:

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

Como señaló @willotter , es una de las declaraciones comentadas en https://raw.githubusercontent.com/ansible/ansible/devel/examples/ansible.cfg

¿Le interesa saber por qué es un problema? ¿Desde cuándo los nombres de ruta largos son un problema fuera de Windows?

esto funciona para mí después de actualizar a EI Capitan.

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

@deyvsh ¿por qué es un problema? ¿Desde cuándo los nombres de ruta largos son un problema fuera de Windows?

Desde que Apple lanzó El Capitán. Aparte de una página en chino, esta es la única página que parece hacer referencia a este nuevo comportamiento en MacOS. Me encontré con el mismo problema al intentar usar el modo Tramp en emacs, que permite el acceso transparente a archivos remotos a través de ssh. El mismo error sobre nombres de archivo largos para un socket de dominio Unix, pero no es tan fácil de solucionar como en Ansible.

@cswarth La configuración ansible acaba de pasar a su cliente ssh. Es posible que pueda configurar un control_path en su archivo de configuración ssh ~/.ssh/config así:

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

No tengo Mac OS X, así que no puedo probar esto, pero debería funcionar a menos que emacs pase algún parámetro específico a SSH.

@willotter Tuve que adaptar esta idea y agregarla a mi archivo ansible.cfg para que funcione.

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

Actualización de 2017: parece que @willotter ya no existe :(

@LukeHoersten Gracias por esto, ¡solucionó el problema para mí!

La causa fundamental de esto está en

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 conocer el límite (tamaño de (sunaddr.sun_path)), debemos mirar 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];
           };

La ruta está limitada a 104 caracteres, incluido el terminador 0.

Esto también se discute en https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing#Manually_Establishing_Multiplexed_Connections, que también sugiere que está utilizando

A partir de 6.7, la combinación de% r @% h:% p y sus variaciones se puede reemplazar con% C, que por sí mismo genera un hash a partir de la concatenación de% l% h% p% r.

Al final, quieres usar

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

Además, desea mantenerse al margen de / tmp o de cualquier otra ubicación en la que se pueda escribir y leer en todo el mundo, por motivos de seguridad.

Véase también http://pastebin.com/ugXKMFsv

@isotopp buenas sugerencias. Me pregunto por qué no cambiamos el valor predeterminado a control_path = %(directory)s/%%C para evitar problemas futuros.

@LukeHoersten Creo que ansible también debería cambiar el valor predeterminado. De hecho, lo hice

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

Haga ping a

+1

porque no funcionaría en muchos sistemas operativos / distribuciones que ejecutan incluso versiones un poco más antiguas de openssh

El cambio propuesto en http://pastebin.com/ugXKMFsv solo cambia los documentos y los comentarios. Funcionará con versiones antiguas de openssh, pero hará que el puntero a% C sea más obvio.

Tengo un nombre de usuario largo en mi máquina (11 caracteres), esto hizo que mi directorio superara el límite de caracteres.

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

Dejé caer el -%%r y me resolvió este problema.

Hoy encontré este error porque en lugar de mi archivo de inventario, proporcioné mi archivo group_vars y ansible analizó felizmente el archivo cifrado de alguna manera y acepté algo como 182937891273891723981723891723987189237189237981273981 como nombre de host. SSH tampoco pensó que eso fuera extraño antes de notar el largo ControlPath. Una advertencia para la posteridad: ejecute todo con -vvvv y asegúrese de que está apuntando al host correcto y todo eso.

Gracias por esto. Se solucionó el error que tenía en OS X El Capitan.

+1
Esto acaba de resolver mi problema en OS X El Capitan.

También funcionó para mí en OS X EL Capitan. Solo una nota, si ha instalado ansible a través de brew, entonces el archivo es /usr/local/etc/ansible/ansible.cfg

: +1 Esto me pasó solo tratando de hacer un ansible all -i inventory -m ping con un host con un nombre de host largo como ec2-XX-XXX-XX-XX.eu-west-1.compute.amazonaws.com

Esto funcionó para mí en El Capitán:

Creé un archivo ansible.cfg en mi directorio actual con:

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

Ahora ejecutar ansible .. no me dio ningún error de ssh.

También funcionó para mí en OS X EL Capitan. Solo una nota, si ha instalado ansible a través de brew, entonces el archivo es /usr/local/etc/ansible/ansible.cfg

Soy El Capitán e instalé ansible a través de brew, e ignoró el archivo /usr/local/etc/ansible/ansible.cfg que intenté agregar con esa configuración.

@tleyden Eso es bastante extraño, /usr/local/etc/ansible/ansible.cfg funciona bien para mí.

Oh, me acabo de dar cuenta de la diferencia: instalé ansible a través de pip install ansible , no a través de brew

¿Por qué está freakin agregar cadenas como CErvOvRE5U0urCgm al final? Las cosas se me rompen por esa cuerda inútil.

Solo agregue algunos comentarios aquí para tener claro qué acciones se pueden tomar:

  • Documentación. Parece que las actualizaciones de documentos sugeridas están en una esencia vinculada desde este ticket pero no en un PR, por lo que nunca se fusionó.
  • Mejor detección de errores: si se usa% C y ssh no lo admite, dígale a la gente que lo reemplace con% l-% h-% p. Si la ruta es demasiado larga, dígale a la gente que pruebe% C o simplemente acorte la ruta.
  • intenta detectar si el ssh que estamos usando es compatible con% C y, de ser así, haz uso de él; de lo contrario, no lo hagas (tal vez esto solo sea relevante por defecto, no cuando el usuario configura algo en su archivo de configuración) (¿Tienes Sin embargo, debe tener cuidado de que las conexiones no demoren mucho más).

También agregué:
%(directory)s/%%h‐%%r
¿Pero mi camino todavía es demasiado largo? Cómo puedo arreglar esto:

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

Veo este problema con ansible 2.1.0.0 en Ubuntu 16.04

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

Agregar esto a mi ansible.cfg funcionó:

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

Alternativamente, cambiar el nombre de dominio largo de AWS a una dirección IP también lo solucionó, incluso sin el cambio a ssh_connection.control_path en ansible.cfg.

Como han dicho otros, este error no era evidente cuando se ejecutaba con -vvvv. Tuve que copiar el comando en la salida de depuración y ejecutarlo directamente en una terminal para ver el error "demasiado largo para el socket de dominio Unix".

También estoy teniendo el mismo problema.

este problema ha sido muy molesto, tener que alternar entre IP y FQDN dependiendo de la máquina que ejecute el libro de jugadas de Ansible ... ¿alguna solución real planeada por parte de Ansible?

@swoodford , tal vez pueda presentar un problema con su distribución de Linux para cambiar la configuración predeterminada. Por ejemplo, el mantenedor de Fedora cambió por defecto para usar un socket de control más corto. El problema parece ser ansible, desea conservar la compatibilidad de forma predeterminada con las distribuciones antiguas. No estoy seguro de que tenga sentido porque los usuarios de las distribuciones más nuevas deberían ser ahora mucho más. Eso significa que al menos a las distribuciones más nuevas no les debería importar cambiar el valor predeterminado durante el empaquetado porque la distribución sabe que es lo suficientemente reciente como para funcionar con la opción más confiable.

Sin embargo, sigo pensando que ansible debería cambiar por defecto.

Muy divertido. Hemos tenido el mismo problema en cdist hace algún tiempo (y estamos viendo otro error relacionado con esto). El límite de sun_path en Unix es un límite muy, muy antiguo que nos afecta a todos en 2016.

Solución más sencilla: ninguna.
Segunda mejor solución: intente que el nombre del socket sea corto. Todavía se rompe si el directorio de inicio es un camino largo
Tercera mejor solución: guárdelo en algún lugar en / tmp / short-random-path / c (solo necesita un carácter)

Solución a largo plazo: elimine el límite sun_path o aumente a un valor predeterminado sensato de 2016 (¿alguien del grupo austin / posix leyendo aquí?)

¿Qué significa %(directory) ?

@isotopp

¿Es esta la sintaxis correcta (con prefijo subrayado) para colocar dentro del archivo ~/.ssh/config ?

ControlMaster auto
ControlPath ~/.ssh/_%C

¿Es este un escape que tendría el mismo significado que el doble %% del archivo ansible.cfg? Estoy tratando de configurar ambos de la misma manera que uso ssh incluso fuera de ansible.

Incluso después de agregar control_path a mi ansible.cfg en mi proyecto, seguía recibiendo este error, pero volví a la versión 2.1.3, ejecuté el mismo comando que arrojó el error al ejecutar 2.2.1, y el cuestión ha sido resuelta.

Todavía tengo este problema con la versión: ansible 2.2.0.0

problema realmente extraño. ansible 2.2.0.0 en fedora 24 -> existía un problema
git head de 2016/07/05 en OSX -> el problema no existe.

@bcoca siempre soy un fanático de la compatibilidad con versiones anteriores (sí, envié esa corrección de centos 6.5). ¿Qué tal si lo hace dinámico en la versión openssh / distro qué ruta de control usar?

ya es dinámico, vea que la lógica detrás de la conexión 'inteligente' es la predeterminada

al conectarse de un host a otro, ¿tal vez no tenga claves ssh en su mochila? :)

En una nota al margen,% C no es un gran valor predeterminado en este momento, ya que EL7 tiene openssh 6.6, y% C no se agregó hasta openssh 6.7 y no se ha actualizado.

Sin embargo, puede usar la forma completamente expandida de% l% h% p% r en EL7, pero solo mitiga parcialmente, ya que no hará un hash, por supuesto.

Los propietarios de las distribuciones deberían cambiar la configuración predeterminada para adaptarla al paquete enviado. Creo que upstream no debería esperar 7 años antes de seguir adelante con importantes mejoras como esta.

Como todavía estoy usando Ansible versión 2.2 y Ansible Tower 3.1.1, también encontré este problema. Como @dennisobrien señaló anteriormente , cambiar el inventario de un nombre de dominio de AWS a una dirección IP de AWS resolvió este problema. Sin embargo, primero intenté usar solo estas variables en la configuración y no resolvió el problema:

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

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

Mi servidor tiene este problema y no tengo permisos para cambiarlo. ¿Cómo puedo solucionarlo al final del cliente?

@thefourtheye es puramente un problema del cliente, no un problema del servidor. Puede encontrar la opción para establecer en su archivo ansible.cfg anteriormente en este hilo.

@antoineco Oh, gracias. Soy totalmente nuevo en ansible y ni siquiera lo tengo instalado en mi máquina. ¿Seguiría funcionando el archivo ansible.cfg en el directorio de inicio?

Tengo el mismo problema, trato de que todas las soluciones incluyen agregar el archivo de configuración .ansible.cfg en ~ /:
[defaults] inventory=/etc/ansible/hosts [ssh_connection] control_path=%(directory)s/%%h-%%r control_path_dir=~/.ansible/cp

Y agregue know host e ip a ssh known_hosts. Pero todavía no funciona, es ubuntu en EC2.
Este es el error:

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

No está utilizando la solución propuesta que es control_path = %(directory)s/%%C .

@akostadinov Gracias, funciona. Demasiada solución aquí.

Demasiada solución aquí.

Si tan solo fuera más difícil ... ¡maldice a esos proveedores de soluciones!

Intenté agregar todas las líneas sugeridas aquí en el archivo ~/ansible.cfg en mi máquina de ubicación, pero no ayudó. Me estoy dando por vencido.

Lo que me funciona ahora es obtener la dirección IP de la máquina con nslookup e iniciar sesión con eso.

@thefourtheye , no estoy seguro de cuántas "líneas sugeridas" ves aquí. Usa la publicación con más de 50 me gusta. Pero además de la opción adecuada, debe usar un archivo de configuración que ansible conozca . En su caso ~/.ansible.cfg . Trate de prestar atención a los detalles, el punto delante del archivo de configuración del usuario es una convención común de Unix.

@akostadinov Lo siento, fue un error tipográfico. Así es como esto luce

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

Solo quiero intervenir con mi .ansible.cfg :

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

para mí, directory fue algo ridículamente largo, la última parte fue solo la gota que colmó el vaso. También tengo esto en mi .ssh/config para poder reutilizar la misma conexión:

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

Lo sentimos, pero el tmp codificado no solo no es portátil, sino que también representa un grave riesgo de seguridad. Por buenas razones, MacOS no permite a los usuarios escribir en / tmp y proporciona carpetas tmp aisladas (privadas) para cada usuario.

Tmp funcionaría solo si usa la ruta tmp proporcionada por el sistema operativo, algo así como% (tmp) s ... después de parchear ansible.

Chicos, por favor lean los comentarios existentes, es ridículo que todos vengan a preguntar lo mismo y que alguien agregue la misma solución. Utilice el archivo de configuración adecuado y consulte https://github.com/ansible/ansible/issues/11536#issuecomment -153030743.

Alguien, cierre el hilo para evitar más spam.

@ssbarnea harcoded cualquier cosa no es portátil ... es por eso que no es el predeterminado en ansible ... no estoy seguro de estar de acuerdo con el problema de seguridad o el problema de macOS ya que / tmp es pegajoso y openssh usa un modo sensible (0600) para estos archivos.

con respecto a la solución usando %C que requiere un openssh reciente ...

Realmente no me importan las versiones antiguas de ssh, especialmente en el controlador ansible. Para evolucionar necesitamos dejar algunas cosas atrás y en este caso no es gran cosa porque los afectados podrían cambiar la configuración para poder seguir usándola.

Creo que es esencial para la experiencia del usuario (UX) de Ansible, proporcionar valores predeterminados que se adapten a la mayoría de los usuarios, minimizando la necesidad de cambios. Dudo que tengamos más del 1-2% de usuarios usando versiones de open openssh que no son compatibles con %C .

Creo que necesitamos implementar en Ansible algunas variables INI críticas lo antes posible porque cada dos semanas encontramos errores causados ​​por la falta de ellos: %(tmpdir)s m $(configdir)s , %(inventorydir)s .

Si contamos con estas personas, seríamos capaces de crear caminos relativos fiables.

Lamentablemente, en mi caso, el problema es aún peor porque estamos usando Ansible como parte de CI y porque, como muchos, tenemos varios nodos de Jenkins en la misma máquina, ejecutándose bajo el mismo usuario, nos encontramos con el secuestro de sesiones ssh con bastante frecuencia. De todos modos mi problema es más complejo y está fuera del alcance de este ticket.

Solucioné este problema de forma genérica para todas las versiones de ssh hace 6 meses. Si alguien ve el problema con Ansible 2.3+, es porque ha configurado una ruta de control personalizada en ansible.cfg en lugar de dejarla en blanco.

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 =

Dado que esta conversación continúa sin hacer referencia al parche anterior, lo bloquearé. Si tiene más preguntas sobre el tema, utilice la lista de correo.

¿Fue útil esta página
0 / 5 - 0 calificaciones