# # # # # # ## ## # # # # # # # # # # # # # # # # # # # ##### ##### =========================================================================== X11 para todos 1) ¿Qué es eso del X11? 1.1) ¿y lo del X11R4, R5, R6...? 1.2) ¿y lo del Motif? 1.3) ¿y lo de la OpenGL? 2) ¿Cómo funciona en modo remoto? 2.2) la variable DISPLAY 2.3) la seguridad en X11 2.4) ejecución remota 3) Alternativas para la cuestión de seguridad: ssh 4) Alternativas para sesiones remotas: VNC 5) Adjunto: xjost. 6) Adjunto: Seguridad en servidores X para MacOS/Windows. =========================================================================== =========================================================================== 1) ¿Qué es eso del X11? Xwindow es el sistema gráfico standard de Unix. Genéricamente se conoce como X, y 11 es el número de versión. El funcionamiento básico es el siguiente: 1: Una máquina ejecuta un programa (conocido como 'servidor X') Este programa no hace nada (!). Simplemente espera a que alguien le pida que pinte algo en la pantalla y le pida datos sobre el teclado u otros periféricos de entrada. (por eso es un servidor, responde a peticiones de otros programas -clientes- p.e. pintando para ellos) Este programa puede llamarse de diferentes maneras, por ejemplo: X en Unix génerico xnews en Unix Sun (incluye extensión PostScript) MacX, eXodus en MacOS PC Xware en Wintel ...etc En el momento en que 'X' esta corriendo, se dice que esa máquina ofrece un 'display', identificado como se describe en (2.2) 2: Otra máquina (o la misma) ejecuta un programa (conocido como 'cliente X') que hace lo siguiente: - se conecta al servidor (puede que a través de la red) - le pide que pinte un monton de tonterías, que le diga donde esta el ratón, etc etc - se desconecta y acaba Las extensiones de X son funciones opcionales que puede tener el servidor. Por ejemplo, la extensión 'display postscript (DPS)' significa que el cliente puede mandarle comandos postscript al servidor y este sabe dibujarlos en la pantalla. 1.1) ¿y lo del X11R4, R5, R6...? La R es de Release, (sub-version). Cuanto mayor sea, más funciones podrán utilizar los clientes. (en princio, todas las funciones de una release determinada están disponibles en las releases superiores) Antes hemos mencionado dos partes del sistema: el servidor y los clientes; pero aún queda (al menos) una más: Las librerías. La comunicación entre los clientes y el servidor se realiza por medio de funciones de librería. (por ejemplo XDrawString()) Estas librerías suelen ser dinámicas (esto es, el sistema linka con las librerías, que son ficheros normales en el disco, en el momento en que se ejecuta el cliente.) La elección de con que librerías linka viene dada por la variable de entorno LD_LIBRARY_PATH (en general, aunque en algunos unix puede depender del ABI, consultar en cada caso), que es una lista de directorios separados por el caracter ':'. Por lo tanto, si un programa ha sido compilado usando funciones de R6 *jamás* funcionará si el LD_LIBRARY_PATH hace que el sistema utilice librerías de R4. Esto es un problema unicamente en sistemas en los que coexisten dos Releases (por ejemplo, por que la nativa es demasiado vieja -caso de SunOS 4.x-) El mensaje de error que se obtiene en tales casos es algo así como: ld.so: warning: /usr/openwin/lib/libX11.so.4.3 has older revision than expected La solución, obviamente, es cambiar el LD_LIBRARY_PATH, para lo cual debes saber donde estan las librerías correctas (por lo general, en /usr/X11R6/lib) 1.2) ¿y lo del Motif? Aparte de las librerías de dibujo de bajo nivel, se tienen librerías de interface gráfico (que hacen menus, botones, etc. a más alto nivel). Motif es una de las más extendidas (otra bastante frecuente es XView, de Sun, que tiende a desaparecer; también se vienen utilizando recientemente qt, gtk, etc...), y en los sistemas en los que no es nativo, se debe tener la misma precaución con la variable LD_LIBRARY_PATH. Una localización posible en estos casos es /usr/Motif12/lib (En Solaris 2.x es frecuente usar en su lugar las librerías del CDE, en /usr/dt/lib) 1.3) ¿y lo de la OpenGL? Es la extensión 3D más standard. Disponible en máquinas de SGI y en algunos servidores X11 comerciales. (p.e. el de HummingBird). Una alternativa consiste en linkar (ya sea en tiempo de compilación, o de ejecución, jugando con LD_LIBRARY_PATH, con librerías de OpenGL por software, como p.e. Mesa) También existe la extensión 3D IRIS GL (dgl); que esta implementada solo en máquinas de SGI. Si al ejecutar un cliente obtienes un error similar a: dgl error (default init): default dglopen(sol:0.0,4) returned -13 no te queda otra opción que irte a la consola de una SGI a ejecutarlo. =========================================================================== =========================================================================== 2) ¿Cómo funciona en modo remoto? Según hemos visto las conexiones de los clientes con el servidor pueden realizarse a traves de la red. Por ejemplo, una persona puede estar sentada en la maquina 'sol' haciendo telnet a la maquina 'luna'. De pronto se le ocurre que quiere ejecutar una aplicacion X en 'luna' y que las ventanas le aparezcan en donde esta sentado ('sol'). Para eso, todos los clientes X aceptan un sistema por el que se le dice a que 'display' debe conectarse. Por lo general, este metodo consiste en una opción de línea de comandos: xclock -display aunque tambien puede ser la variable de entorno 'DISPLAY' Pero, ¿qué es ""? Es una cadena tal que así: hostname:displaynumber.screennumber Cuando nos referimos al display de la propia máquina (el cliente y el servidor se ejecutan en la misma máquina) suele ser: ":0" En el caso de que la maquina disponga de varios displays (p.e., cuando se usa ssh o vnc), sería ":.0", donde "número" cuenta a partir de 0 ":0.0" es equivalente a ":0" Cuando se tienen varias pantallas en un display: ":." en el caso más general. Cuando el servidor corre en la máquina cuyo nombre es 'sol' el display se llamará normalmente: "sol:0" 2.2) la variable DISPLAY En la variable de entorno DISPLAY se puede poner el display que vamos a utilizar por defecto. Una manera de hacerlo es dándole un valor adecuado en la inicialización del shell, haciendo algo similar a: ########################################################################### Shells tipo Bourne: ########################################################################### ############# # # who am i # if [ ${DISPLAY:-setdisplay} = setdisplay ] then # irix sets REMOTEHOST if [ ${REMOTEHOST:-islocal} != islocal ] then DISPLAY=${REMOTEHOST}:0 else if [ "${SSH_CLIENT:-notssh}" != "notssh" ] then echo "Warning: using ssh w/o X11 fwd" DISPLAY=`echo "$SSH_CLIENT" | sed -e 's/ .*/:0.0/'` else # Try to guess DISPLAY case $ARCH in sunos-sun4|osf-alpha) TTY=`tty | sed 's:/dev/::'` DISPLAY=`who am i | grep $TTY | tail -1 | \ sed -e 's/.*(//' -e 's/[\.)].*//'`:0.0 ;; irix-mips) DISPLAY=:0.0 ;; *) DISPLAY=`who am i | sed -e 's/^.*(//' -e 's/[:)].*//'`:0.0 ;; esac fi fi export DISPLAY fi ########################################################################### Shells tipo C ########################################################################### ############# # # who am i # if ( ${?DISPLAY} == 0 ) then # irix sets REMOTEHOST if ( ${?REMOTEHOST} == 0 ) then if ( ${?SSH_CLIENT} == 0 ) then # Try to guess DISPLAY switch (${ARCH}) case sunos-sun4: case osf-alpha: set TTY=`tty | sed 's:/dev/::'` setenv DISPLAY `who am i | grep $TTY |tail -1| sed -e 's/.*(//' -e 's/[\.)].*//'`:0.0 breaksw irix-mips: setenv DISPLAY :0.0 breaksw default: setenv DISPLAY `who am i | sed -e 's/^.*(//' -e 's/[:)].*//'`:0.0 breaksw endsw else echo "Warning: using ssh w/o X11 fwd" setenv DISPLAY `echo "${SSH_CLIENT}" | sed -e 's/ .*/:0.0/'` endif else setenv DISPLAY ${REMOTEHOST}:0 endif endif ########################################################################### 2.3) la seguridad en X11 o qué hacer cuando se obtiene el error: Xlib: connection to "sol:0.0" refused by server Xlib: Client is not authorized to connect to server xhost: unable to open display "sol:0.0" X es un servidor al que se puede acceder a traves de la red. Pero, ¿quien puede acceder? Cuando lanzamos un cliente de X no pide login y password, el mecanismo es algo diferente. Es importante limitar el acceso, en caso contrario, cualquiera puede conectarse al display en el que estamos trabajando y espiar nuestras pulsaciones de tecla o capturar una imagen de nuestras ventanas (por poner dos ejemplos de cosas que se pueden hacer con programas ampliamente difundidos) Una forma muy primitiva es ejecutar en la máquina en la que corre el servidor el comando xhost luna (si 'luna' es la dirección de la máquina que corre los clientes) Este comando significa "dale permiso a *cualquier* usuario de la máquina 'luna' para que se conecte al servidor". Con esto hemos limitado algo el acceso, pero no mucho. Otra forma consiste en xhost user@host pero muy pocos sistemas la soportan. La forma recomendada consiste en la utilización de xauth. Cuando el usuario entra en sesión (introduciendo login y password en la consola gráfica, suponiendo que se usa xdm), el sistema le genera un fichero llamado ~/.Xauthority Entonces, cualquier usuario que en su ~/.Xauthority tenga una entrada correspondiente al display y a la sesión en curso, puede lanzar clientes. Así, si el usuario 'dumb' de la máquina 'sol' (en la que esta en sesión) quiere darle permiso al usuario 'luser' de la máquina 'luna' para que lance clientes tiene que hacer algo así como: xauth extract - sol:0 | rsh luna -l luser /usr/bin/X11/xauth merge - (un script en shell que hace esto de forma similar a xhost está en el punto 5, y puede instalarse como /usr/local/bin/xjost) (esto no es necesario si las máquinas sol y luna comparten el HOME, ya que en ese caso el fichero ~/.Xauthority esta accesible directamente, por lo tanto, si tanto en la máquina en la que corre el cliente como la que tiene el DISPLAY comparten el HOME via NFS, no es necesario ni siquiera hacer xhost) 2.4) ejecución remota Una vez que hay permiso, existe un comando similar a rsh, pero para X11, que facilita la ejecución de clientes. la sintaxis es xon remoteuser@remotehost comando argumentos o xon remotehost -user remoteuser comando argumentos =========================================================================== =========================================================================== 3) Alternativas para la cuestión de seguridad: ssh Todo el follón de autorizaciones se puede evitar si se dispone de ssh. La explicación completa de lo que es ssh no corresponde a este documento; pero si ya tienes disponible ssh y ya lo tienes configurado, lo puedes utilizar para ahorrarte problemas: Cuando te conectas a la maquina remota (luna en el ejemplo de arriba) vía ssh, la variable DISPLAY ya es inicializada por el propio servidor sshd (por lo que es importante que nuestro .profile/.cshrc asigne valor a DISPLAY *solo* si no lo tiene previamente); y tiene una pinta tal que así: luna:1.0 donde esperariamos encontrar sol:0.0 Esto es así porque la conexion por ssh activa un 'servidor X11 virtual' en luna, que en realidad corresponde a una comunicacion encriptada y autentificada entre el ssh de 'sol' y el sshd de 'luna'. Así pues, no necesitamos hacer ningun tipo de xhost, xauth ni nada de nada; y encima tenemos la ventaja de que toda la comunicación es encriptada y opcionalmente comprimida (lo que tiene mucho interes especialmente cuando el servidor X11 ('sol') esta conectado a la red via modem... Con esto ademas, nos ahorramos la necesidad de un comando 'xon', ya que basta con ssh -n remotehost -l remoteuser comando =========================================================================== =========================================================================== 4) Alternativas para sesiones remotas: VNC Esto esta en http://webdiis.unizar.es/~spd/sec/vnc.txt Vease http://www.orl.co.uk/vnc/ =========================================================================== =========================================================================== 5) Adjunto: xjost. #!/bin/sh # # SPDsoft 05/10/1995 # SPDsoft Dec 98; ssh # # Replacement for xhost(1) when using MIT-MAGIC-COOKIE-1 # CMD=`basename $0` usage() { echo "Usage: $CMD [-s] [user@]host" echo "-s: Use ssh" echo "-q: Quiet" exit 1 } set -- `getopt sqh $*` if [ $? != 0 ] then usage fi if [ -z "$RSH_CLIENT" ] then if test -x /usr/bin/remsh then RSH_CLIENT=/usr/bin/remsh else RSH_CLIENT=rsh fi fi QUIET=false; for i in $* do case $i in -s) RSH_CLIENT="ssh"; shift;; -q) QUIET=true; shift;; -h) usage; shift;; --) shift; break;; esac done if [ "$1" = "" ] then usage fi execho() { if ( $QUIET ); then : ; else echo "$*"; fi eval $* } user=`echo $1 | awk -F@ '{print $1}'` host=`echo $1 | awk -F@ '{print $NF}'` if [ "$user" = "$host" ] then LOGNAME=${LOGNAME:=`id | sed -e 's/^[^\!(]*(//' -e 's/).*//'`} user="-l $LOGNAME" else user="-l $user" fi RSH="$RSH_CLIENT $host $user" RP=/usr/bin/X11:/usr/openwin/bin:/usr/X11R6/bin if [ "`echo $DISPLAY | awk -F: '{printf $1}'`" = "" ] then DISPLAY=`hostname`:0 fi execho xauth extract - $DISPLAY \| $RSH env PATH=$RP xauth merge - =========================================================================== =========================================================================== 6) Seguridad en servidores X para MacOS/Windows. * Mecanismos basados en xhost: Son los que ofrecen casi todos los servidores X de MacOS/Windows; además suelen tener la alternativa de "requerir confirmación manual para cada nueva conexión", cosa bastante recomendable toda vez que hablamos de máquinas (clientes) multiusuario; asi que haciendo p.e. "xhost luna" te expones a cualquier cosa, ya que cualquier usuario que tenga una sesión abierta en "luna" se te puede conectar. Ejemplos prácticos: * MacOS:MacX 2.0.4 Menu->Remote->Access Control->On si intentamos abrir una conexión, el MacX dice: 'An X11 client is connecting to MacX from the host "luna.example.com". Permit the connection? [OK] [Cancel]' con lo que sabes desde donde, pero no quien. El administrador del host cliente ("luna", en el ejemplo), si está conectado en ese mismo instante, si que podría llegar a averiguar el nombre del usuario; pero un usuario normal, por lo general, no (aunque puede haber casos en que si). MacX acepta el comando "xhost -" o "xhost host" ejecutado desde unix; pero responde diciendo que el comando no tiene efecto por no ser la máquina local con lo que, en efecto, no hace nada * MacOS:MI/X Oct 98 Preferences->Hosts->Warn if a client... On Este no solo avisa del nombre del cliente, sino que además nos dice el puerto del cliente, lo que puede ayudar al root del cliente a identificar al usuario. En el mismo cuadro de dialogo se permite especificar una lista de hosts permitidos (equivalente a un "xhost"). Así pues, permitiendo solo "localhost" podemos utilizar clientes SSH con "X11 Forwarding"; aunque usando p.e. el de F-Secure 1.x de DataFellows, resulta excesivamente lento. * MacOS:eXodus 7.0->Settings->Confirm Connections->On También avisa de la IP y del puerto del cliente. El log además lleva registro de todo lo que pide el cliente, aunque genera demasiada información para usarlo habitualmente. Conviene notar que la opción "Allow all connections from XDM host" que aparece en el Connection Manager para las sesiones XDM no es un mecanismo seguro tipo xauth, si no mas bien, equivalente a un "xhost + xdm-host" Atención: aunque eXodus acepte el comando "xhost -" o "xhost host" ejecutado desde unix; en realidad no hace caso y sigue estando abierto. Las únicas protecciones son el "confirm..." y el "allow" del XDM. Asi pues, parece que eXodus no es muy apropiado para utilizarlo con la capacidad de "X11 Forwarding" de clientes SSH para Mac como el de DataFellows. * X:Unix Lo recomendado es usar xauth (y, si es posible, X11 via ssh); con eso no hay problemas. No hay medios standard para que te avise de los intentos de conexión, se podrian utilizar a mas bajo nivel los del S.O. (se deja como ejercicio al lector :-) ) * X-Win32 3.4.1:WinNT X-Win32 Utility->Options->Access Control->On No avisa del puerto, pero si del Host. Permite personalizar el mensaje de respuesta del servidor * X-Win32 4.1.x:WinNT X-Win32 Utility->Options->Access Control->On No avisa del puerto, pero si del Host. Permite personalizar el mensaje de respuesta del servidor Incluye la opción de usar Xauth, pero solo en sesiones XDM Incluye lista de hosts permitidos (xhost), lo que permitiría uso via ssh. * X-WinPro 5.2 - Xsettings -> enable "Hosts Access Check" Valid Hosts File: Nombre de fichero de texto con la lista de hosts aceptados. Similar a xhost + host Cuando llega un cliente de un host que no esta en la lista informa de la IP y del puerto, dando la opción de aceptarlo manualmente (usando el boton "cancel", algo anti-intuitivo) - Xsettings -> enable "Authorize File" Se supone que usa un fichero xauth, pero no parece funcionar (al menos sin usar XDM) * MI/X 5.6:WinNT No parece tener mecanismos ni de xhost ni de aviso. * Terminales X11 "dumb" (tipo NCD, Tektronix, etc) Que yo recuerde tampoco pueden avisar, y el unico control que llevan es de tipo "xhost"; aunque (en teoria) si se usa sesión xdm remota, se puede usar xauth. Aparte de las propias protecciones del servidor X11 se tienen herramientas a nivel de sistema; p.e. * MacOS: MacTCP Watcher puede servir para ver las conexiones abiertas, incluyendo las que van al puerto 6000 (X11) * WinNT: En los settings de TCP/IP se pueden añadir filtros para permitir conexiones al puerto 6000 solo desde ciertas direcciones. El comando "netstat /a" te da la lista de conexiones y servicios abiertos en el PC. * Unix: Tambien ofrece variados mecanismos de filtrado de bajo nivel; el comando "netstat -a" tambien es util. A la hora de saber si alguien se te ha conectado a tu servidor X11, un comando muy util es 'xlsclients -l' Con eso sabes el nombre de los clientes, incluido el nombre del comando, lo que te puede ayudar a localizar al usuario sin ser root, usando el comando 'ps -efl / ps -aucx'