Abrir una ventana en una pantalla X remota (¿por qué "No se puede abrir la pantalla")?

81

Érase una vez,

DISPLAY=:0.0 totem /path/to/movie.avi

después de pasar a mi escritorio desde mi computadora portátil, el tótem se reproduciría movie.avien mi escritorio.

Ahora da el error:

No protocol specified
Cannot open display:

Reinstalé Debian Squeeze cuando se estabilizó en ambas computadoras, y supongo que rompí la configuración.

He buscado en Google esto, y por mi vida no puedo entender lo que se supone que debo hacer.

(VLC tiene una interfaz HTTP que funciona, pero no es tan conveniente como ssh).

El mismo problema surge cuando intento ejecutar esto desde un trabajo cron.

berro de justin
fuente
1
¿Su máquina remota muestra un archivo .Xauthority? La otra pregunta obvia es: ¿su servidor ssh y su cliente están configurados para permitir el reenvío X? ¿Qué comando usaste para ssh?
Faheem Mitha
1
¿Estoy tratando de reenviar X? Quiero que el comando se ejecute en el host, no en el cliente. Mi comando ssh es solo ssh me @ host ubicar .Xauthority en la computadora host no coincide con ningún archivo.
Justin Cress
Como sugiere Faheem, hay un buen cambio en que su problema se debe a que totemno encuentra su cookie X, y debe establecer XAUTHORITYel valor adecuado, es decir, el valor en su sesión normal en su escritorio. Lea Linux: wmctrl no puede abrir la pantalla cuando la sesión se inicia a través de ssh + screen para algunos antecedentes; también vea la respuesta relacionada Como root, ¿puedo iniciar un programa gráfico en el escritorio de otro usuario? .
Gilles
1
bien, físicamente sentado en la computadora y escribiendo echo $ XAUTHORITY da / var / run / gdm3 / auth-for-jcress-bb32gX / database en la sesión ssh, escribiendo echo $ DISPLAY = (la ruta anterior) no resuelve el problema
justin berro
1
Culpo gdm3, ¿por qué no sólo han mantenido $XAUTHORITYal ~/.Xauthorityigual que todo el mundo espera que sea.
Arrowmaster

Respuestas:

78

(Adaptado de Linux: wmctrl no puede abrir la pantalla cuando la sesión se inicia a través de ssh + pantalla )

PANTALLA y AUTORIDAD

Un programa X necesita dos piezas de información para conectarse a una pantalla X.

  • Se necesita la dirección de la pantalla, que es normalmente :0cuando está conectado localmente o :10, :11, etc, cuando está conectado de forma remota (pero el número puede cambiar dependiendo del número de conexiones X están activos). La dirección de la pantalla normalmente se indica en la DISPLAYvariable de entorno.

  • Necesita la contraseña para la pantalla. Las contraseñas de visualización X se llaman cookies mágicas . Las cookies mágicas no se especifican directamente: siempre se almacenan en archivos de autoridad X, que son una colección de registros de la forma "pantalla :42tiene cookie 123456". El archivo de autoridad X normalmente se indica en la XAUTHORITYvariable de entorno. Si $XAUTHORITYno está configurado, los programas lo usan ~/.Xauthority.

Estás intentando actuar en las ventanas que se muestran en tu escritorio. Si eres la única persona que usa tu máquina de escritorio, es muy probable que el nombre para mostrar sea :0. Encontrar la ubicación del archivo de autoridad X es más difícil, porque con gdm configurado en Debian squeeze o Ubuntu 10.04, está en un archivo con un nombre generado aleatoriamente. (No tenía ningún problema antes porque las versiones anteriores de gdm usaban la configuración predeterminada, es decir, las cookies almacenadas en ~/.Xauthority).

Obteniendo los valores de las variables

Aquí hay algunas formas de obtener los valores de DISPLAYy XAUTHORITY:

  • Puede iniciar sistemáticamente una sesión de pantalla desde su escritorio, tal vez automáticamente en sus scripts de inicio de sesión (desde ~/.profile; pero hágalo solo si inicia sesión en X: pruebe si DISPLAYestá configurado en un valor que comience desde :(eso debería cubrir todos los casos que probablemente encontrar)). En ~/.profile:

    case $DISPLAY in
      :*) screen -S local -d -m;;
    esac
    

    Luego, en la sesión ssh:

    screen -d -r local
    
  • También puede guardar los valores de DISPLAYy XAUTHORITYen un archivo y recuperar los valores. En ~/.profile:

    case $DISPLAY in
      :*) export | grep -E '(^| )(DISPLAY|XAUTHORITY)=' >~/.local-display-setup.sh;;
    esac
    

    En la sesión ssh:

    . ~/.local-display-setup.sh
    screen
    
  • Puede detectar los valores de DISPLAYy XAUTHORITYdesde un proceso en ejecución. Esto es más difícil de automatizar. Debe averiguar el PID de un proceso que está conectado a la pantalla en la que desea trabajar, luego obtener las variables de entorno de /proc/$pid/environ( eval export $(</proc/$pid/environ tr \\0 \\n | grep -E '^(DISPLAY|XAUTHORITY)=')¹).

Copiando las cookies

Otro enfoque (siguiendo una sugerencia de Arrowmaster ) es no intentar obtener el valor de $XAUTHORITYla sesión ssh, sino hacer que la sesión X copie sus cookies ~/.Xauthority. Dado que las cookies se generan cada vez que inicia sesión, no es un problema si mantiene valores obsoletos ~/.Xauthority.

Puede haber un problema de seguridad si se puede acceder a su directorio de inicio a través de NFS u otro sistema de archivos de red que permita a los administradores remotos ver su contenido. Todavía tendrían que conectarse a su máquina de alguna manera, a menos que haya habilitado las conexiones X TCP (Debian las tiene desactivadas por defecto). Entonces, para la mayoría de las personas, esto no se aplica (sin NFS) o no es un problema (sin conexiones X TCP).

Para copiar cookies cuando inicia sesión en su sesión X de escritorio, agregue las siguientes líneas ~/.xprofileao ~/.profile(o algún otro script que se lea cuando inicie sesión):

case $DISPLAY:$XAUTHORITY in
  :*:?*)
    # DISPLAY is set and points to a local display, and XAUTHORITY is
    # set, so merge the contents of `$XAUTHORITY` into ~/.Xauthority.
    XAUTHORITY=~/.Xauthority xauth merge "$XAUTHORITY";;
esac

¹ En principio, esto carece de una cita adecuada, pero en este caso específico $DISPLAYy $XAUTHORITYno contendrá ningún metacarácter de shell.

Gilles
fuente
2
Una forma de automatizar esto sería crear una ~/.xprofileque solo debería ejecutarse durante el inicio de sesión X y hacer que se cree / actualice ~/.Xauthoritycon la información correcta. ¿Sería suficiente un enlace simbólico?
Arrowmaster
@Arrowmaster: Esa es una buena sugerencia. No lo había pensado. No funcionará en todos los casos, por ejemplo, si inicia sesión en más de una sesión X (en diferentes terminales, con vnc, ...), pero es simple y es lo suficientemente bueno para el uso típico. Un enlace simbólico es la mejor manera. Hmm, en realidad hay una manera mejor y más simple: puedes copiar la información ~/.Xauthority.
Gilles
1
¿Poner algo como xauth extract - $DISPLAY | xauth -f "$HOME/.Xauthority" merge -en ~/.xprofileresolver el caso de múltiples $ DISPLAY?
Arrowmaster
@Arrowmaster: ¿Qué problema ves con múltiples pantallas? Si bien su código puede ser un poco más limpio en principio, ya que solo está extrayendo información sobre la pantalla que le interesa, no veo nada malo con una simple fusión en el caso del autor de la pregunta, o de hecho fuera de circunstancias muy inusuales.
Gilles
1
Leer el entorno de un proceso existente conectado a la pantalla es inesperado, ya que es deliciosamente malo. Lo apruebo de todo corazón. Unix.SE necesita una insignia Evil Genius ™ para esto.
derobert
19

Resolví este problema agregando

xhost +si:localuser:$USER

a ~/.xprofile. No sé si esto es completamente seguro (estaría muy interesado en saber qué piensa la gente con más conocimientos), pero supongo que es mucho mejor que desactivar el control de acceso (con xhost +) como se sugiere comúnmente cuando google para este problema

queso Edam
fuente
1
localuserLas direcciones interpretadas por el servidor son completamente seguras. Debian incluso hace esto por defecto como parte del proceso de inicio de sesión (en /etc/X11/Xsession.d/35x11-common_xhost-local). Consulte la página del manual de Xsecurity para obtener más detalles.
Sam Morris
Si estás en una LAN, xhost +probablemente sea suficiente en la mayoría de los casos ...
Alexis Wilke
¿Serías capaz de explicar qué significa este comando?
alpha_989
@ alpha_989: Significa "Conceder acceso [+] a cualquier aplicación [localuser] que se ejecute localmente y que se ejecute como yo [$ USER]". El "si" es solo pegamento (ver xhost(1)y Xsecurity(7)para documentos). Por sí solo, este comando no permite ningún tipo de acceso remoto o reenvío X11 (para el cual generalmente se prefiere el mecanismo de "cookie mágica" xhost).
Kevin
7

Necesitas export DISPLAY=:0.0

asoundmove
fuente
No. Unix no requiere una exportación cuando la variable se escribe en la misma línea. Esa variable es efectiva hasta que termine la línea.
Alexis Wilke
De hecho, tienes razón.
asoundmove
Esta respuesta es claramente incorrecta y debe eliminarse.
Piotr Dobrogost
No sabía que simplemente escribir DISPLAY =: 0.0 establecería el nombre de la variable. Gracias @asoundmove. Sin embargo, creo que: 0.0 es el valor de la variable DISPLAY en la pantalla del servidor. Si está iniciando sesión desde Putty, la variable DISPLAY debe ser 10 o superior. entonces debería ser DISPLAY =: 10
alpha_989
3

Funciona para mí, debian wheezy -> ubuntu trusty.

Nota: en este caso, el servidor no ejecuta un administrador de pantalla, es una máquina virtual 'sin cabeza' sin tarjeta gráfica o monitor conectado.

bob@laptop:~$ grep -iB 1 tcp /etc/gdm3/daemon.conf
[security]
DisallowTCP = false
bob@laptop:~$ ssh -C -R 6000:127.0.0.1:6000 alice@server
X11 forwarding request failed on channel 0
alice@server:~$ export DISPLAY=:0.0
alice@server:~$ xterm

La pantalla X en la computadora portátil muestra la salida de xterm ejecutándose en el servidor.

Depurar usando:

bob@laptop:~/tmp$ nc -v 127.0.0.1 6001
localhost [127.0.0.1] 6001 (x11-1) : Connection refused
bob@laptop:~/tmp$ nc -v 127.0.0.1 6000
localhost [127.0.0.1] 6000 (x11) open
alice@server:~$ nc -v 127.0.0.1 6000
Connection to 127.0.0.1 6000 port [tcp/x11] succeeded!*
alice@server:~$ strace xterm

strace derramará un montón de detalles sangrientos sobre lo que está haciendo, deberías ser capaz de adivinar dónde se atasca, esperando una conexión o lo que sea.

En una linea ..

ssh -C -R 6000:127.0.0.1:6000 alice@server "DISPLAY=:0.0 xterm"
jmullee
fuente