¿Por qué falla mi intento de reenvío X11 con "connect /tmp/.X11-unix/X0: No such file or directory"?

33

En mi máquina local, ejecuto:

ssh -X [email protected]

(Para completar, también he probado todo lo siguiente usando -Y con resultados idénticos).

Como se esperaba, esto accede a remotemachine.com bien, y todo parece estar bien. Sin embargo, si intento ejecutar xcalc, obtengo:

 connect /tmp/.X11-unix/X0: No such file or directory
 Error: Can't open display: localhost:10.0

Pero,

$ ls -la /tmp/.X11-unix/
total 36
drwxrwxrwt 2 root root  4096 2012-11-23 09:29 .
drwxrwxrwt 8 root root 32768 2012-11-29 08:22 ..
srwxrwxrwx 1 root root     0 2012-11-23 09:29 X0

Entonces, no solo existe /tmp/.X11-unix/X0, ¡también tiene permisos universales r / w / x!

Anteriormente he usado x-forwarding sin problemas, aunque no en algún momento ...

uname -a en el servidor para referencia:

Linux machinename 2.6.32-25-generic #45-Ubuntu SMP Sat Oct 16 19:52:42 UTC 2010 x86_64 GNU/Linux

He estado buscando en la web durante un par de horas sin éxito. Otras menciones del mismo problema, pero no hay soluciones.

John Doucette
fuente
Tenga en cuenta que es el archivo en la máquina local lo que necesita verificar aquí, no el remoto. Solía strace -fo /tmp/trace ssh....comprobar que intenta conectar ese socket de dominio Unix.
Stéphane Chazelas
Ah! Eso podría ser. Aunque parezca extraño, mi máquina local no tiene un directorio /tmp/.X11-unix/.
John Doucette el

Respuestas:

24

Si tiene un servidor X en ejecución y la DISPLAYvariable de entorno está configurada en :0, eso le dice a las aplicaciones que se conecten al servidor X usando un socket de dominio Unix que generalmente se encuentra en Linux /tmp/.X11-unix/X0(aunque vea más abajo sobre el espacio de nombres abstracto en Linux reciente) .

Cuando ssh a la máquina remotemachine , sshden remotemachine establece DISPLAY en localhost:10(por ejemplo), lo que esta vez significa que las conexiones X se deben hacer a través de TCP al puerto 6010 del equipo localhost. sshd en remotemachine escucha las conexiones allí y reenvía cualquier conexión entrante al cliente ssh. El cliente ssh luego intenta conectarse /tmp/.X11-unix/X0(en el extremo local, no en el remoto) para contactar a su servidor X.

Ahora, tal vez no tenga un servidor X ejecutándose (¿está en Mac?) O tal vez el socket del dominio Unix no se encuentre en /tmp/.X11-unix, lo que significaría que ssh no se ha configurado correctamente en la compilación hora.

Para averiguar cuál es la ruta correcta para el socket Unix, puede probar un strace -e connect xlogo(o el equivalente en su sistema) en su máquina local para ver qué hace una aplicación X normal.

netstat -x | grep X También puede dar una pista.

Para el registro, en una máquina Linux Debian wheezy aquí, Xorg escucha tanto /tmp/.X11-unix/X0en el sistema de archivos como /tmp/.X11-unix/X0en el espacio de nombres abstracto (generalmente escrito @/tmp/.X11-unix/X0). Desdestrace , las aplicaciones X11 parecen usar ese espacio de nombres abstracto de forma predeterminada, lo que explica por qué esas todavía funcionan si /tmp/.X11-unixse eliminan, mientras sshque no usan ese espacio de nombres abstracto.

Stéphane Chazelas
fuente
1
O verifique lsof -p <PID of your local X server>dónde debería poder encontrar el /some/thing/Xnarchivo, nsiendo su DISPLAYnúmero.
Peter
Gracias, esto fue bastante útil. De alguna manera mi archivo /tmp/.X11-unix/X0 fue eliminado, aunque todavía había un servidor X ejecutándose. Un reinicio rápido parece haber resuelto el problema. Posiblemente causado por algunas actualizaciones que hice hace un tiempo.
John Doucette el
66
Cambiar la variable DISPLAY de ": 0.0" a "localhost: 0.0" parece haber hecho el truco para mí, al menos conectándose de Cygwin a Linux.
m0j0
FWIW, tuve que ejecutar startxwin(después apt-cyg install xinit) desde el cygwinhost porque estoy conectando Windows local a Unix remoto
Jonathan
40

Tuve el mismo problema con Cygwin y Xming, al conectarme a un servidor remoto de Linux.

Mi variable $ DISPLAY era simplemente ": 0.0" en Cygwin, y aunque eso funciona localmente, no funcionaba con el comando ssh remoto.

Cambiar la variable a "localhost: 0.0" solucionó el problema.

export DISPLAY=localhost:0.0

Una vez que hice eso, mi comando funcionó:

ssh -Yf user@host gvim somefile.c
m0j0
fuente
55
Este fue el problema para mí incluso usando los Servicios de Windows para Linux.
lapo
1
¿En qué servidor ejecutó el export ...comando? 1) máquina local 2) servidor
abalter
1
@abalter Me funcionó ejecutándolo en la máquina local
tralston
3
Pasé un problema de depuración de 2 horas con Cygwin ssh + VcXsrv porque lo configuré DISPLAY=:0 ssh -Y $host. Cambiándolo a un DISPLAY=localhost:0problema mágicamente resuelto.
gavenkoa
1
Gran respuesta, sigue siendo útil para ejecutar el subsistema ubuntu en windows
Tom Swifty
6

Esto complementa otras respuestas con información específica de Windows-Subsystem para Linux. La respuesta aceptada es correcta: su DISPLAYvariable está configurada incorrectamente. Sin embargo, no está exactamente claro por qué ese es el caso solo de esa respuesta, por lo que estoy remediando con esta respuesta.

Si está ejecutando cygwin, o Windows-Subsystem para Linux, y su servidor X11 está basado en Windows (por ejemplo VcXsrv, o XMing), es más probable que su servidor X11 esté escuchando en un puerto TCP (como 127.0.0.1en los puertos TCP 6000-6010) que en el socket de dominio predeterminado de Unix (/tmp/.X11-unix/X0 ). Los sockets Unix no son compatibles con Windows en este momento, incluso dentro de WSL. La comunicación entre programas en el entorno similar a Linux y programas que se ejecutan directamente en el host de Windows también es generalmente más fácil a través de sockets IP.

Cuando ejecuta aplicaciones gráficas localmente (es decir, desde el entorno Cygwin o WSL de su host), y su DISPLAYvariable se establece en el valor predeterminado (es decir DISPLAY=:0.0), las aplicaciones primero intentarán conectarse al servidor X a través del socket Unix /tmp/.X11-unix/X0. Esto fallará, pero la mayoría de las aplicaciones recurrirán a una conexión TCP activada localhost, que debería llegar al servidor, suponiendo que su servidor X esté configurado con los valores predeterminados.

Puede confirmar que esto está sucediendo buscando connect()llamadas en registros de una ejecución de su aplicación gráfica. En general, eso sucedería desde el principio, antes de que aparezca la ventana principal de la aplicación.

Ese comportamiento alternativo no ocurre cuando ssh está redirigiendo una conexión desde el lado remoto, por lo que obtiene ese error. sshdde hecho está reenviando la conexión al lado local, pero la conexión local del cliente ssh llega a un punto muerto ya que no puede llegar al servidor a través del socket Unix. Entonces obtienes el ENOENTerror.

En tales casos, cambiar su DISPLAYvariable para usar la sintaxis TCP en lugar de la :0.0sintaxis, puede solucionar el problema:

DISPLAY=127.0.0.1:0 ssh remote some-gui-application

Como mencionan otras respuestas, también puede exportar esa variable de manera interactiva desde su indicador de shell:

$ export DISPLAY=127.0.0.1:0
...
$ ssh remote some-gui-application

También puede almacenar esta configuración de manera más permanente agregando esa línea a su script de inicialización del perfil de shell de inicio de sesión (por ejemplo ~/.bash_profile).

Nota: Algunos shells tienen un script de inicialización diferente para las sesiones de inicio de sesión y no inicio de sesión. Por ejemplo, con bash podría escribir esa línea en el script sin inicio de sesión, es decir ~/.bashrc, en lugar de ~/.bash_profile. Si lo hace, tenga cuidado de no anular ningún valor personalizado que ssh haya establecido. Ese sería el caso si saltaras primero a tu host a través de ssh y luego saltaras nuevamente a otro host (anidando así tu reenvío X11).

init_js
fuente
3

Si su host de pantalla es macOS , asegúrese de tener XQuartz ejecutándose.

Este mensaje de error le indica que el túnel ssh está funcionando, pero no puede descubrir cómo conectarse al servidor X en su lado del túnel .

En los viejos tiempos, Mac OS X solía iniciar XQuartz por ti, pero aparentemente hemos abandonado esta pequeña característica agradable en la versión de terminal de macOS .

softweyr
fuente
seguimiento: Invalid MIT-MAGIC-COOKIE-1 keyxterm Xt error: Can't open display: localhost:10.0significaba "debes salir y SSH volver a entrar después de iniciar XQuartz" FWIW ...
rogerdpack
1

Acabo de tener el mismo problema. Lo confuso es que obtiene el error de no archivo en la máquina remota , pero en realidad este archivo falta en la máquina local (pantalla).

Solo para ver qué sucedería, creé manualmente el archivo que faltaba (quince, en realidad), en la máquina de visualización, así:

mkfifo /tmp/.X11-unix/X0

Luego volvió a entrar en la máquina remota, y he aquí, X11 se conectó bien.

No sé si esto es relevante o no, pero mi máquina de visualización no es Linux, es Windows con cygwin y VcXsrv. (La máquina remota es Linux)

esmendola
fuente
44
/tmp/.X11-unix/X0es un socket de dominio unix, no un FIFO
Samveen
0

Me encontré con este problema usando el Subsistema de Windows para Linux . El problema es que no tenía una GUI instalada en el cliente, debido a la suposición de que, dado que es una máquina Windows, tengo una GUI.

Para probar si tiene una GUI, ejecute xclocken el cliente. Si recibe el error, Error: Can't open display: :0entonces necesita instalar un programa GUI para Windows. Solía servidor X .

Una vez que tenga una GUI instalada, pruebe los siguientes comandos:

export DISPLAY=:0
xclock

Si aparece un reloj, ¡entonces el éxito!

Ahora intente ssh'ing en el servidor, luego ejecute xclock. ¿ Recibió todavía los mensajes de error connect /tmp/.X11-unix/X0: No existe tal archivo o directorio Error: No se puede abrir la pantalla: localhost: 10.0 ? Esto se debe a que el servidor está intentando conectarse consigo mismo para mostrar la GUI. En cambio, desea que la variable DISPLAY se configure en una dirección donde el servidor pueda obtener su computadora. Entonces, si está en una LAN, simplemente debe poner el nombre de su computadora. Si se está conectando a un servidor en la WAN, debe especificar la IP externa de su enrutador y reenviar el puerto adecuado.

LAN: export DISPLAY=ComputerName:0
WAN:export DISPLAY=257.257.257.257:0

Jack Cole
fuente
"Reenvío X" significa "tunelizar el protocolo X desde las aplicaciones que se ejecutan en la máquina remota (servidor, en su caso) a la máquina local (cliente, en su caso)", por lo que, por supuesto, debe ejecutar un servidor X (y no "cualquier programa GUI") en la máquina local. Windows por sí solo no entiende el protocolo X, a pesar de que "tiene una GUI".
dirkt
-2

Si funcionaba bien y dejaba de funcionar sin ninguna razón adecuada, probablemente podría ser una instancia X no controlada que se ejecuta en segundo plano. Cierra eso usando el administrador de tareas.

Jerin
fuente