¿Cómo configurar D-Bus y SSH X-Forwarding para evitar que SSH se cuelgue en la salida?

19

Estoy intentando ejecutar varias aplicaciones de Gnome a través de X11 Forwarding y SSH. Algunas aplicaciones harán que la aplicación 'dbus-launch' se genere primero. El problema es que dbus-launch no se cierra cuando se cierra la aplicación X y, por lo tanto, debe eliminarse antes de que la sesión SSH pueda cerrarse correctamente.

Supongo que el problema es que las aplicaciones X / Gnome no pueden conectarse con el demonio del bus de mensajes principal y, por lo tanto, deben lanzar su propia copia. ¿Cómo puedo arreglar esto? ¿O qué me estoy perdiendo?

Aquí hay un ejemplo. Tengo habilitado el reenvío X11, todo parece funcionar bien.

[me@host ~]$ gnome-calculator &
[1] 4803

(aquí se inicia el programa gcalctool y se muestra en mi servidor X de eliminación (Xming))

[me@host ~]$ ps
  PID TTY          TIME CMD
 4706 pts/0    00:00:00 bash
 4803 pts/0    00:00:00 gnome-calculator
 4807 pts/0    00:00:00 dbus-launch
 4870 pts/0    00:00:00 ps

(ahora, después de cerrar la aplicación gcalctool en la sesión remota)

[me@host ~]$ ps
  PID TTY          TIME CMD
 4706 pts/0    00:00:00 bash
 4807 pts/0    00:00:00 dbus-launch
 4898 pts/0    00:00:00 ps

Tenga en cuenta que dbus-launch todavía está activo. Y la peor parte, esto evita que la conexión SSH se cierre correctamente hasta que se cierre.

Tenga en cuenta que el demonio de mensajes de todo el sistema se está ejecutando, como se puede ver aquí:

[me@host ~]$ ps ax
 4696 ?     Ssl   0:00 dbus-daemon --system

¿Que me estoy perdiendo aqui? Nunca he visto este comportamiento antes. Presumiblemente, ¿solo he visto aplicaciones sin problemas que puedan conectarse al demonio del bus de mensajes? He buscado respuestas en / etc / dbus-1, pero no sé qué buscar.

Gracias de antemano por la ayuda.

[EDITAR]

OK, me estoy dando cuenta de que estoy experimentando un problema común. Parece que este es un comportamiento bastante común, pero sin una buena solución. Estoy experimentando el bloqueo de SSH porque dbus-launch todavía está activo en el tty. Pero aparentemente no hay una buena manera de lograr que el lanzamiento de dbus ocurra en silencio.

Mirando /etc/X11/xinit/xinitrc.d/00-start-message-bus.sh da una idea de lo que se supone que sucederá con una sesión X "normal". Por supuesto, esto no funciona cuando solo se invoca una aplicación X en un servidor X remoto.

Como solución temporal, he agregado esto a mi .bash_logout:

# ~/.bash_logout
pkill -u $USER -t `tty | cut -d '/' -f 3,4` dbus-launch

Esto permitirá que la sesión SSH se cierre, pero se siente muy torpe. ¿Hay alguna solución mejor por ahí? ¿Cuál es la forma correcta de ejecutar aplicaciones X11 remotas sin que dbus se interponga en el camino?

taftster
fuente

Respuestas:

15

Por lanzamiento de dbus (1):

Si DBUS_SESSION_BUS_ADDRESS no está configurado para un proceso que intenta usar D-Bus, por defecto el proceso intentará invocar dbus-launch con la opción --autolaunch para iniciar un nuevo bus de sesión o encontrar la dirección de bus existente en la pantalla X o en un archivo en ~ / .dbus / session-bus /

Cada vez que se produce un inicio automático, la aplicación que tuvo que iniciar un nuevo bus estará en su pequeño mundo; efectivamente puede terminar comenzando una sesión completamente nueva si intenta utilizar muchos servicios de autobús. Esto puede ser subóptimo o incluso totalmente roto, dependiendo de la aplicación y de lo que intente hacer.

Hay dos razones comunes para el inicio automático. Uno es ssh para una máquina remota.

Entonces parece que el truco es iniciar dbus-daemon de manera preventiva, de tal manera que los programas puedan encontrarlo. Yo suelo:

[me@host ~]$ dbus-launch --exit-with-session gnome-terminal

que, aparte de gnome-terminal, inicia dbus-daemon y establece $ DBUS_SESSION_BUS_ADDRESS dentro de gnome-terminal .

Todos los programas X que se ejecutan desde gnome-terminal se comportan bien, y dbus-launch se limpia por sí mismo cuando sale gnome-terminal.

Nathan
fuente
Marqué esto como la respuesta, me gusta su solución aquí. Gracias. Lanzar un terminal gnome primero, y luego iniciar programas adicionales desde él parece solucionar mi problema. ¿Es este nuevo comportamiento, sin embargo? Aparentemente recuerdo haber podido iniciar muchas ventanas X reenviadas sin tener este problema. Tal vez los nuevos programas de Gnome están usando Dbus ahora, ¿así que todavía no he visto esto?
taftster
2

Me pregunto si el problema no se debe a una sesión de dbus desconocida o inexacta.

De hecho, cuando una sesión SSH está abierta, no inicia una sesión dbus. Algunos programas pueden iniciarlo, pero la sesión no lo sabe (por lo tanto, no puede cerrarlo).

No saber acerca de la sesión dbus también significa que los programas que usan dbus pero no lo inician por sí mismos tendrán problemas.

Las secciones de dbus son por máquina y por pantalla X11. Su información se almacena en $ HOME / .dbus / session-bus / - sin embargo, el proceso al que se hace referencia allí puede estar cerrado, por lo que se necesita una verificación adicional para determinar si es necesario iniciar dbus o no. Luego, las variables que hay que exportar a la sesión.

Entonces funciona como un encanto :)

Puse lo siguiente en mi archivo .bash_profile:

# set dbus for remote SSH connections
if [ -n "$SSH_CLIENT" -a -n "$DISPLAY" ]; then
    machine_id=$(LANGUAGE=C hostnamectl|grep 'Machine ID:'| sed 's/^.*: //')
    x_display=$(echo $DISPLAY|sed 's/^.*:\([0-9]\+\)\(\.[0-9]\+\)*$/\1/')
    dbus_session_file="$HOME/.dbus/session-bus/${machine_id}-${x_display}"
    if [ -r "$dbus_session_file" ]; then
            export $(grep '^DBUS.*=' "$dbus_session_file")
            # check if PID still running, if not launch dbus
            ps $DBUS_SESSION_BUS_PID | tail -1 | grep dbus-daemon >& /dev/null
            [ "$?" != "0" ] && export $(dbus-launch) >& /dev/null
    else
            export $(dbus-launch) >& /dev/null
    fi
fi

notas: hostnamectl es parte de systemd y permite recuperar la identificación de la máquina, el dbus-launch muestra las variables que queremos; mediante el uso export $(dbus-launch)recuperamos la salida de dbus-launch y exportamos las variables

si desea que se realice en una sesión no interactiva (por ejemplo, cuando se ejecuta un comando desde ssh) intente ponerlo en .bashrc en su lugar (pero tenga cuidado de que bashrc se ejecute en el shell abierto de EVEERY)

Pablo Saratxaga
fuente
1

Tuve el mismo problema al intentar ejecutar un comando X remoto y hacer que la sesión salga después de que la herramienta X haya salido.

Entonces quise correr

ssh -X user@remotehost "firefox -no-remote"

Pero tuvo que usar:

ssh -X user@remotehost 'export \`dbus-launch\`; dbus-launch firefox -no-remote; kill -TERM $DBUS_SESSION_BUS_PID'

Después de cerrar firefox, esto también cerraría la sesión ssh.

Actualización :

Esto parece dejar una carga de procesos dbus-daemon ejecutándose en el servidor, por lo que esto no es óptimo, agregar --exit-with-session en ambas cuentas no ayuda, porque esto revierte el comportamiento original

Actualización 2 : esto funciona cuando uso comillas simples, (como lo sugiere @lobo) y agrego kill -TERM $DBUS_SESSION_BUS_PIDpara matar los sobrantes procesos dbus-daemon, según lo propuesto por Holgr Joukl de https://blog.dhampir.no/content/how- para evitar ssh-x-de-colgar-en-salida-cuando-dbus-se utiliza )

Jens Timmerman
fuente
Debe usar comillas simples en el último comando (de lo contrario, dbus-launchse ejecuta localmente ), pero luego funciona. ¡Gracias!
l0b0