Administración remota con Apache Guacamole

Permitidme que hoy os hable de un producto que he conocido recientemente llamado Apache Guacamole. Dicho producto, con un nombre tan curioso, es una herramienta para la administración remota que admite los principales protocolos como VNC, RDP y SSH. Una de sus principales ventajas es que no necesita la instalación de cliente alguno, ya que el cliente está basado en HTML5.

Además, los escritorios a los que se accede a través de Guacamole no necesitan existir físicamente. Con Guacamole y un sistema operativo de escritorio alojado en la nube, se puede combinar la conveniencia de esta herramienta con la resistencia y la flexibilidad de la computación en la nube.

Sigue la filosofía de desarrollo del código abierto y es software libre. Ya que utiliza una licencia Apache en su versión 2.0, además de contar una gran comunidad de desarrolladores detrás.

Utiliza un conjunto de API que están ampliamente documentadas, incluyendo tutoriales básicos y descripciones conceptuales en su manual en línea. Esta permite que Guacamole se integre estrechamente en otras aplicaciones.

Por otra parte, si fuese necesario, también se ofrece soporte comercial.

Antes de continuar, me gustaría comentar que en el mes de julio de este año, el portal Hispasec, en la sección «Una al día», explicaba que habían encontrado varias brechas de seguridad en el producto. En cualquier caso el equipo de desarrollo las subsanaron y ya hace tiempo que está solventado.

Logo oficial del proyecto

Instalar Apache Guacamole Server en Debian 10

Este software esta incluido en la mayoría de las distribuciones GNU/Linux, en este caso me voy a decantar por Debian 10, que es una de mis favoritas. Como no podía ser de otra manera, siendo lo ideal instalar este producto con el rol de servidor, en la llamada nube, he decidido utilizar mi proveedor de confianza Clouding.io

Tal y como he comentado muchas veces, una vez ya tenemos creado el host, lo primero es crear un usuario diferente de root y deshabilitar a este del acceso remoto. El siguiente paso es instalar las herramientas necesarias para la instalación y sus respectivas dependencias:

sudo apt install build-essential libcairo2-dev libjpeg62-turbo-dev libpng-dev 
sudo apt install libtool-bin libossp-uuid-dev libvncserver-dev freerdp2-dev libssh2-1-dev 
sudo apt install libtelnet-dev libwebsockets-dev libpulse-dev libvorbis-dev libwebp-dev 
sudo apt install libssl-dev libpango1.0-dev libswscale-dev libavcodec-dev libavutil-dev libavformat-dev

Una vez hecho esto descargamos su última versión estable para servidor, que podemos consultar en este enlace: Apache Guacamole Releases

wget http://mirror.cc.columbia.edu/pub/software/apache/guacamole/1.2.0/source/guacamole-server-1.2.0.tar.gz

Extraemos los ficheros:

tar -xvf guacamole-server-1.2.0.tar.gz

Accedemos dentro de la carpeta e indicamos la configuración del entorno:

cd guacamole-server-1.2.0
./configure --with-init-dir=/etc/init.d

Compilamos e instalamos:

sudo make
sudo make install

Actualizamos la caché de las librerías del sistema:

sudo ldconfig

Recargamos Systemd y nos aseguramos que el fichero guacd se encuentre dentro de la ruta /etc/init.d

sudo systemctl daemon-reload

Ahora sí, encendemos el servicio:

sudo systemctl start guacd.service

Añadimos el servicio para que se inicie al encender o reiniciar el host:

sudo systemctl enable guacd.service

Podemos comprobar su estado:

sudo systemctl status guacd.service

Con el resultado en mi caso:

Estado del servicio guacd.service

Si queremos comprobar las conexiones actuales:

sudo ss -lnpt | grep guacd

O bien:

sudo lsof -i :442

Instalar la Aplicación Web de Guacamole

La aplicación web de Guacamole ha sido escrita en Java, por lo que el siguiente paso es instalar un Java Servlet, en este caso, Apache Tomcat:

sudo apt install tomcat9 tomcat9-admin tomcat9-common tomcat9-user

Por defecto utiliza el puerto 8080, por lo que podemos comprobar si esta escuchando:

sudo ss -lnpt | grep java

O bien:

sudo lsof -i :8080

Es importante que tanto el puerto 442 y el 8080 no se estén utilizando previamente en el host.

Ahora procedemos a descargar la aplicación web de Guacamole:

wget https://downloads.apache.org/guacamole/1.2.0/binary/guacamole-1.2.0.war

Mover el fichero war a la carpeta correspondiente de Tomcat:

sudo mv guacamole-1.2.0.war /var/lib/tomcat9/webapps/guacamole.war

Reiniciamos Tomcat y guacd:

sudo systemctl restart tomcat9 guacd

Configurar Guacamole

Creamos el fichero de configuración:

sudo mkdir /etc/guacamole/
sudo vi /etc/guacamole/guacamole.properties

Añadimos las siguientes líneas en el fichero. Aunque son los valores por defecto, creo que es importante añadirlos por si a posteriori fuese necesario modificarlos:

# Hostname y puerto del proxy de guacamole
guacd-hostname: localhost
guacd-port:     4822
 
# Clase de proveedor de autenticación (autentica la combinación de usuario / contraseña, necesaria si se usa la pantalla de inicio de sesión proporcionada)
auth-provider: net.sourceforge.guacamole.net.basic.BasicFileAuthenticationProvider
basic-user-mapping: /etc/guacamole/user-mapping.xml

Guardamos y salimos del fichero. Por defecto la herramienta utiliza la información contenido en el fichero XML /etc/guacamole/user-mapping.xml para indicar el usuario y la contraseña. Antes de crear este archivo, necesitamos generar un hash MD5 para la contraseña con el siguiente comando. Reemplazamos nuestro_password con nuestra contraseña preferida.

echo -n nuestro_password | openssl md5

Una vez ya tenemos el código de la contraseña, ya podemos editar el fichero, con este contenido:

<user-mapping>

    <!-- Per-user authentication and config information -->
    <authorize
         username="nuestro-nombre"
         password="codigo-md5"
         encoding="md5">
      
       <connection name="default">
         <protocol>vnc</protocol>
         <param name="hostname">localhost</param>
         <param name="port">5901</param>
         <param name="password">vnc_password</param>
       </connection>
    </authorize>

</user-mapping>

Guardamos y salimos del fichero. Volvemos a reinicar los servicios:

sudo systemctl restart tomcat9 guacd

Instalar el entorno de escritorio XFCE en Debian 10

Dado que vamos a configurar un escritorio remoto, necesitamos un entorno de escritorio. Nos debemos asegurar de que nuestro servidor tenga suficiente nenirua antes de instalar el entorno de escritorio. Uno de los más ligeros es XFCE, que es el que vamos a utilizar:

sudo apt update
sudo apt install xfce4 xfce4-goodies

Durante la instalación, es posible que nos solicite que elija un administrador de pantalla predeterminado. Esta elección no importa mucho, porque no veremos la pantalla de inicio de sesión en una sesión de VNC.

Dado que hay un entorno de escritorio que se ejecuta en el servidor, se recomienda utilizar un cortafuegos como UFW, del que ya hemos hablado, para restringir el acceso y abrir solo los puertos necesarios al público.

Instalar el servidor VNC

Hay varios software de servidor VNC disponibles para usuarios de GNU/Linux. Vamos a utilizar el servidor TigerVNC porque funciona mejor con Guacamole.

sudo apt install tigervnc-standalone-server

Para encenderlo:

vncserver

Cuando TigerVNC se inicia por primera vez, nos pide que establezcamos una contraseña de VNC. Debemos tener en cuenta que la contraseña no debe tener más de 8 caracteres. A continuación podemos escoger si necesitamos una contraseña de solo lectura.

Ahora debemos editar el archivo /etc/guacamole/user-mapping.xml y cambiar la contraseña de VNC. Luego reiniciamos Tomcat y guacd.

sudo systemctl restart tomcat9 guacd

El paquete tigervnc-standalone-server se envía con un archivo /etc/X11/Xvnc-session que le dice a TigerVNC que inicie un servidor X cuando se inicie.

El servidor TigerVNC no se envía con ninguna unidad de servicio Systemd. Para que se inicie en el momento del arranque, necesitamos crear una unidad de servicio systemd.

sudo vi /etc/systemd/system/vncserver@.service

Con el siguiente contenido:

[Unit]
Description=a wrapper to launch an X server for VNC
After=syslog.target network.target

[Service]
Type=forking
User=nombre
Group=nombre
WorkingDirectory=/home/nombre

ExecStartPre=-/usr/bin/vncserver -kill :%i > /dev/null 2>&1
ExecStart=/usr/bin/vncserver -depth 24 -geometry 1280x800 -localhost :%i
ExecStop=/usr/bin/vncserver -kill :%i

[Install]
WantedBy=multi-user.target

Debemos cambiar «username» por nuestro usuario.

Guardamos y salimos. Además cerramos la sesión X

vncserver -kill :1

Encendemos el servicio con la unidad recién creada:

sudo systemctl start vncserver@1.service

Lo añadimos al inicio:

sudo systemctl enable vncserver@1.service

Podemos comprobar su estado:

systemctl status vncserver@1.service

Con un resultado, en mi caso:

Estado de VNC Server

VNC escucha por el puerto 5901, lo podemos comprobar:

sudo ss -lnpt | grep vnc

O bien:

sudo lsof -i :5901

Configurar un Proxy Inverso para la Aplicación Web de Guacamole

Apache Tomcat está escuchando en el puerto 8080. En muchas guías utilizan Apache, que es una buena alternativa, pero yo me voy a decantar por Nginx.

La instalación de Nginx es bien sencilla, de hecho todos los pasos os los explique en otra entrada: Instalar y configurar un proxy inverso con Nginx en Ubuntu 18.04

En nuestro caso el fichero de configuración contiene la siguiente información:
server {
    listen 80;
    listen [::]:80;    
    server_name guacamole.bitsandlinux.com;   
 
    access_log  /var/log/nginx/guac_access.log;
    error_log  /var/log/nginx/guac_error.log;
 
    location / {
       proxy_pass http://127.0.0.1:8080/guacamole/;
       proxy_buffering off;
       proxy_http_version 1.1;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection $http_connection;
       proxy_cookie_path /guacamole/ /;
    }
}

Una vez creado recordar crear el correspondiente enlace simbólico:

sudo ln -s /etc/nginx/sites-available/guacamole.bitsandlinux.com \
/etc/nginx/sites-enabled/

Y reiniciamos Nginx:

sudo systemctl restart nginx

Evidentemente, previamente, debemos tener creado el subdominio en nuestro proveedor y asignarle la IP del VPS.

Habilitar HTTPS con Lets Encrypt y Certbot

Por último, que no menos importante, habilitamos la conexión HTTPS con Let’s Encrypt utilizando la herramienta Certbot

sudo apt-get install python-certbot-nginx

Una vez hecho esto, solo hemos de utilizar la herramienta:

sudo certbot --nginx

Nos hará una serie de preguntas y al final listará los proyectos web que ha detectado y debemos seleccionar cuál de ellos será al que se le añadirán los certificados. Todo bastante fácil la verdad.

Los paquetes de Certbot vienen con un trabajo cron o un temporizador systemd que renovará los certificados automáticamente antes de que caduquen. No necesitararemos ejecutar Certbot nuevamente, a menos que cambiemos su configuración. Puede probar la renovación automática de los certificados ejecutando este comando:

sudo certbot renew --dry-run

La herramienta añadira la tarea programada en algún de los siguientes lugares:

/etc/crontab/
/etc/cron.*/*
systemctl list-timers

Podemos comprobar el certificado desde la siguiente URL: https://www.ssllabs.com/ssltest/

Ahora sí podemos acceder al escritorio remoto utilizando la nueva URL, en mi caso: https://guacamole.bitsandlinux.com, con el resultado:

Acceso vía a web a Guacamole Apache

Ahora veamos si efectivamente se ve el escritorio:

Vista del escritorio XFCE vía VNC Server

Y esto es todo, creo que la entrada ya ha quedado lo suficientemente extensa. Espero que ya esta información os se de utilidaden algún momento.

Fuentes consultadas

Página web del proyecto Guacamole Apache

Github – Guacamole Server

Linuxbabe.com – Set Up Apache Guacamole Remote Desktop on Debian 10 Buster