SSH y X11 como root
El objetivo es que las aplicaciones X11 (X-Window) funcionen “también” desde root. Que funcionen desde un usuario es inmediato, pero entrar luego a root con su/sudo
y que X11 funcione no está permitido en Linux. La conexión X11 solo pertenece al usuario con el que entraste por SSH.
Sin embargo siempre hay un truco 🤗, aunque me adelanto un poco, la solución pasa por reutilizar las credenciales X11 del usuario original con el que te conectaste, su lista de cookies
, se las prestaremos a root
usando diferentes métodos, lo vemos más adelante.
Configuración SSH
He documentado en otro apunte una introducción a SSH por si estás interesado. Aquí vamos a ver de nuevo la configuración de SSH en ambos, servidor y cliente, centrándome en la parte de X11. Si quieres saber mucho más sobre SSH consulta la documentación oficial de openssh
Servidor SSH y X11
Para situarnos, las pruebas las hago con ssh
como luis
(desde un Mac), conectando a un servidor linux con sshd
llamado cortafuegix (gentoo)
. Esta es la configuración SSH del servidor:
- Configuración del servidor
sshd
:
cortafuegix ~ # cat /etc/ssh/sshd_config
# Config LuisPa
PubkeyAuthentication yes
PasswordAuthentication no
AuthenticationMethods publickey
UsePAM no
X11Forwarding yes # !! X11 !!
X11DisplayOffset 10 # !! X11 !!
X11UseLocalhost yes # !! X11 !!
AddressFamily inet
PrintMotd no
PrintLastLog no
Subsystem sftp /usr/lib64/misc/sftp-server
AcceptEnv LANG LC_*
Cliente SSH
El cliente SSH que utilizo es el que viene con MacOS (idefix
). Este es el fichero de configuración que uso en mi usuario luis
.
- Configuración del cliente
ssh
:
➜ ~ > confcat /Users/luis/.ssh/config
PubkeyAuthentication yes
Host *
ForwardAgent yes #
ForwardX11 yes # !! X11 !!
ForwardX11Trusted yes # !! X11 !!
XAuthLocation /opt/X11/bin/xauth # !! X11 !!
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_rsa
Apuntes relacionados con X11:
- En el SERVIDOR:
X11Forwarding yes
: Permito reenvío de X11 con mis clientesX11DisplayOffset 10
: Primer número de pantalla (Variable DISPLAY)X11UseLocalhost yes
: Asociar el reenvío de X11 a la direcciónloopback
- En el CLIENTE:
ForwardX11 yes
: Permito reenvío de X11ForwardX11Trusted yes
: Conectar con-X
o-Y
tendrá el mismo efectoXAuthLocation /opt/X11/bin/xauth
: Para evitar el error “No xauth data…”
En terminología X-Window se llama Servidor a lo que vemos, en el mac XQuartz es el servidor y muestra en pantalla lo le piden los clientes remotos. Se llama Cliente a las Aplicaciones, en este caso un ejemplo sería xclock
ejecutándose en el linux.
Nota: XQuartz es un projecto de código abierto que desarrolla una versión del “X.Org X Window System” que funciona en MacOS. El proceso de instalación es muy sencillo, descarga el DMG que encontrarás en XQuartz.com e instálalo en tu Mac, no te olvides de rearrancar to Mac (reboot) tras la instalación o habrá cosas que no funcionen (por ejemplo ssh no será capaz de establecer la variable DISPLAY).
Si xclock
te da el error “Warning: Missing charsets in String to FontSet conversion” la solución es sencilla, modifica tu /etc/profile
añade lo siguiente: alias xclock='LC_ALL=C /usr/bin/xclock'
Al poner ForwardX11Trusted yes
en el Mac lo que estoy diciendo es que ignore la extensión “X11 SECURITY” que provoca que cualquier Aplicación del linux podrá acceder a mi Servidor XQuartz.
Para que funcione X11 desde el cliente usaremos ssh -X
o ssh -Y
. La primera (-X
) consulta ForwardX11Trusted
mientras que la segunda (-Y
) la ignora. Al poner su valor a yes
estoy diciendo que da igual conectar con una o la otra, en ambos casos se ignora la extensión de seguridad “X11 SECURITY”, es decir que da igual si conecto con -X
o -Y
que el efecto será el mismo.
Prueba de concepto
Para empezar desde cero, borro el fichero $HOME/.Xauthority
en mi servidor (además de cualquier fichero $HOME/.xauth*
), tanto en mi usuario luis
como en root
.
La autenticación X se basa en cookies, un chorro de datos que solo el servidor y tu usuario conocen. Al conectar se crea una magic-cookie y se archiva en el fichero de luis
: /home/luis/.Xauthority
. En el siguiente ejemplo vemos que, al conectar no existía, se crea (lo hace el servidor sshd
), insertando la magic cookie y establece la variable DISPLAY
.
➜ ~ > ssh -X luis@cortafuegix.tudominio.com
/usr/bin/xauth: file /home/luis/.Xauthority does not exist
luis@cortafuegix ~ $ ls -al .Xauthority
-rw------- 1 luis luis 57 may 3 11:48 .Xauthority
luis@cortafuegix ~ $ xauth list
cortafuegix/unix:11 MIT-MAGIC-COOKIE-1 afd3b06294cd3963efade050a69c7c4b
luis@cortafuegix ~ $ echo $DISPLAY
localhost:11.0
luis@cortafuegix ~ $ xclock
Me convierto en root
para ver cómo aparece el problema, da igual el método que utilice, aún teniendo bien la variable DISPLAY
nunca consigo que funcione:
➜ ~ > ssh -X luis@cortafuegix.tudominio.com
luis@cortafuegix ~ $ su (Da igual el comando: "su -", "sudo -i", "sudo su -")
:
cortafuegix ~ # echo $DISPLAY
localhost:10.0
cortafuegix /home/luis # xclock
X11 connection rejected because of wrong authentication.
Error: Can't open display: localhost:10.0
La solución
Como decía, la autenticación X se basa en cookies, un chorro de datos que solo el servidor y tu usuario conocen. En el ejemplo anterior luis
conecta vía ssh
con el servidor y X11 funciona, la primera vez se crea dicha cookie en (~/.Xauthority
). Para que también nos funcione al convertirnos en root
necesito esa magic cookie, así que voy ver qué opciones tenemos para prestársela a root.
Método 1: Copiar/Pegar
Este método funciona muy bien si soy el único que entra en root
en mis servidores. Lo que hago es leer la cookie de luis y la añado en el .Xauthority de root. Para conseguirlo voy a añadir una serie de comandos en el .profile
de root
para que hagan precisamente eso:
cortafuegix ~ # cat .profile
:
su - luis -c 'xauth list' |\
grep -E "localhost|`hostname`" |\
xargs -n 3 xauth add
Ten en cuenta que se tiene que ejecutar el .profile o no funcionará, por lo tanto:
- Funcionan:
su -
,sudo -i
,sudo su -
osudo -i xclock
- No funcionan (la primera vez):
su
osudo xclock
. No ejecutan el.profile
de root. Ahora bien, si ya he entrado alguna vez con los anteriores, entonces estos empezarán a funcionar.
OJO! funcionar, funciona, pero es un poco chapuza porque solo le funcionará a un usuario (imagina un linux con múltiples usuario entrando como root) y porque te puede despistar que a veces no funcione… dependiendo de qué comando uses y si está o no creado el .Xauthority…
Método 2: XAUTHORITY
Esta opción es otra pequeña chapuzilla… consiste en usar la variable de entorno XAUTHORITY
apuntando al fichero .Xauthority
del usuario (en mi ejemplo luis
). Añado una línea al .profile
de root y ya está. No necesitas ejecutar el comando xauth
y no necesitas el fichero /root/.Xauthority
.
/root/.profile
export XAUTHORITY=/home/luis/.Xauthority
Tampoco me gusta demasiado, así que no la he activado. Veamos la tercera opción.
Método 3: usar pam_xauth.so
Existe la posibilidad de activar el módulo pam_xauth.so
en la última línea del fichero /etc/pam.d/su
. Añado lo siguiente
session optional pam_xauth.so
Al convertirte en root
se creará automáticamente en el HOME de root un fichero del tipo ./xauthXXXXXX
(siendo XXXXXX valores aleatorios) con la cookie del usuario original (luis
), y al salir de la sesión se eliminará este fichero temporal. Se puede encontrar más información en man pam_xauth
Vamos a probarlo. Elimino la opción 1 del .profile
y activo esta nueva opción en /etc/pam.d/su
:
cortafuegix ~ # cat .profile
:
# LAS SIGUIENTES 3 LINEAS QUEDAN INHABILITADAS
#su - luis -c 'xauth list' |\
# grep -E "localhost|`hostname`" |\
# xargs -n 3 xauth add
cortafuegix ~ # cat /etc/pam.d/su
:
session optional pam_xauth.so
Esta opción es un poco más pura linux, aunque como verás en la tabla siguiente tampoco cubre todos los casos.
Resumen
Opciones disponibles.
Dependiendo de cual de las tres elijas conseguirás que X11 en root
funcione o falle.
(1) .profile | (2) XAUTHORITY | (3) pam_xauth.so | |
---|---|---|---|
su | SEMIFALLA | FALLA | OK |
su - | OK | OK | OK |
sudo su - | OK | OK | FALLA |
sudo -i | OK | OK | FALLA |
sudo xclock | SEMIFALLA | FALLA | FALLA |
sudo -i xclock | OK | OK | FALLA |
Mi propuesta
En mi caso combino las opciones (1), (3) y un alias 🤗:
Archivo | Código |
---|---|
.profile (root) |
su - luis -c 'xauth list' | grep -E "localhost|`hostname`" | xargs -n 3 xauth add |
/etc/pam.d/su |
session optional pam_xauth.so |
.profile (Luis) |
alias sudo='sudo -i' |