Solución para gestión remota con OpenVPN, TigerVNC y Guacamole – PART 2

En esta segunda parte veremos las configuraciones referentes al host «tservice» y cómo se configurará OpenVPN como cliente en Linux (para el tservice) y en Windows para la estaciones de trabajo de los administradores (en caso de usar Windows). También se analizará la instalación y configuración de Guacamole como Remote Desktop Gateway (RDG) en Linux.

1.    Configuraciones en host “tservice”

En este apartado se configurará el host para que sirva de intermediario entre la red aislada y la red pública. Para el uso de estas herramientas por parte de los usuarios que acceden desde sus terminales móviles y, por tanto, desde el TUN10, será necesario configurar al host “tservice” para que forme parte de esta red. Esto posibilitará que con la debida configuración del servidor, realizada anteriormente, usuarios del TUN10 y el host “tservice”, puedan verse entre ellos y poder así, brindar el servicio a los mismos.

1.1.       Entorno gráfico ligero XFCE

Necesitamos que “tservice” tenga un entorno visual de escritorio, para que una vez se acceda a éste por RDP o por VNC, se pueda ejecutar el navegador y acceder a su vez a la red aislada de gestión. En este caso usaremos el escritorio XFCE, el cual como indica la documentación oficial, su objetivo es “ser visualmente atractivo y fácil de usar”.

apt install -y xfce4

Instalamos, opcionalmente, el terminal de gnome:

apt install -y gnome-terminal

Si desde la consola local (no desde SSH) ejecutamos el siguiente comando, podremos iniciar el entorno escritorio XFCE:

startx

Al seleccionar la opción predeterminada XFCE se encuentra listo para que trabajemos sobre él.

Una vez reiniciado el sistema se perderán los cambios y XFCE no iniciará. Para habilitarlo con el inicio del sistema, ejecutamos la siguiente línea:

systemctl set-default graphical.target

Debe devolver lo siguiente:

Created symlink /etc/systemd/system/graphical.target → /lib/systemd/system/graphical.target.

Con esto nuestro sistema iniciara con entorno de escritorio XFCE.

Podemos instalar Firefox para usarlo como navegador por defecto:

apt install firefox-esr -y

1.2.       Implementación y configuración de TigerVNC

Existen varios servidores VNC disponibles en Linux. En este caso usaremos «TigerVNC», porque funciona mejor con Guacamole. TigerVNC es una bifurcación de TightVNC, totalmente de código abierto, con desarrollo y debate que se realiza a través de listas de correo de acceso público y repositorios. Esta aplicación se preocupa especialmente del desempeño y la función de mostrar pantalla (escritorio) remotamente:

Instalamos el TigerVNC:

apt install -y tigervnc-standalone-server

Corremos el siguiente comando para iniciar el servidor VNC:

vncserver

Cuando «TigerVNC» inicia por primera vez, solicita una contraseña VNC y almacena el dichero de la contraseña en el directorio «~/.vnc». Esta debe tener una longitud no más de 8 caracteres:

You will require a password to access your desktops.

Password:***** <-- vncadmin
Verify:***** <-- vncadmin

Would you like to enter a view-only password (y/n)? n

New 'tservice.midominio.local:1 (root)' desktop at :1 on machine tservice.midominio.local

Starting applications specified in /etc/X11/Xvnc-session
Log file is /root/.vnc/tservice.midominio.local:1.log

Use xtigervncviewer -SecurityTypes VncAuth -passwd /root/.vnc/passwd :1 to connect to the VNC server.

Note el «:1» que nos devuelve en la salida después del hostname. Esto significa que el servidor estará corriendo en el puerto TCP 5901 (5900+1). Se pueden tener varias instancias, siempre y cuando se cumpla que :X especifique el puerto para 590X (5900+X).

El servidor «TigerVNC» no se instala con ninguna unidad de servicio de systemd. Para hacer que inicie con el sistema, creamos el servicio:

nano /etc/systemd/system/[email protected]

Agregamos lo siguiente:

[Unit]
Description=Remote Desktop Service (VNC)
After=syslog.target network.target

[Service]
Type=forking
User=root
Group=root
WorkingDirectory=/home/root
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

Creamos el directorio «/home/root:

mkdir /home/root

Detenemos la actual instancia del servidor VNC:

vncserver -kill :1

Iniciamos el servicio con «systemd»:

systemctl start [email protected]

Habilitamos el servicio con el inicio del sistema:

systemctl enable [email protected]

Verificamos su estado:

systemctl status [email protected]

El servidor TigerVNC estará escuchando en el puerto 5901:

ss -lnpt | grep vnc

Debe devolver lo siguiente:

LISTEN    0         5                 127.0.0.1:5901            0.0.0.0:*        users:(("Xtigervnc",pid=29685,fd=7))
LISTEN    0         5                     [::1]:5901               [::]:*        users:(("Xtigervnc",pid=29685,fd=8))

1.2.1.   Múltiples instancias de VNC y múltiples perfiles de Firefox

Pensando en la gestión de múltiples sesiones, será necesario que TigerVNC inicie varias instancias por un puerto diferente, cada una. Esto lo haremos con el objetivo de que, cuando se haga una conexión a cada una de estas instancias, se muestre un escritorio para cada una, sin interrumpir el trabajo de las demás.

Habilitamos que inicien con el sistema varias instancias VNC para el localhost:

systemctl enable [email protected]
systemctl enable [email protected]
systemctl enable [email protected]
systemctl enable [email protected]
systemctl enable [email protected]
systemctl enable [email protected]

Verificamos las instancias iniciadas:

ss -lnpt | grep vnc

Debe devolver lo siguiente:

LISTEN    0         5                  0.0.0.0:5901             0.0.0.0:*        users:(("Xtigervnc",pid=821,fd=7))
LISTEN    0         5                  0.0.0.0:5902             0.0.0.0:*        users:(("Xtigervnc",pid=1947,fd=7))
LISTEN    0         5                  0.0.0.0:5903             0.0.0.0:*        users:(("Xtigervnc",pid=2251,fd=7))
LISTEN    0         5                  0.0.0.0:5904             0.0.0.0:*        users:(("Xtigervnc",pid=2429,fd=7))
LISTEN    0         5                  0.0.0.0:5905             0.0.0.0:*        users:(("Xtigervnc",pid=2607,fd=7))
LISTEN    0         5                  0.0.0.0:5906             0.0.0.0:*        users:(("Xtigervnc",pid=2783,fd=7))
LISTEN    0         5                  0.0.0.0:5907             0.0.0.0:*        users:(("Xtigervnc",pid=2959,fd=7))
LISTEN    0         5                     [::]:5901                [::]:*        users:(("Xtigervnc",pid=821,fd=8))
LISTEN    0         5                     [::]:5902                [::]:*        users:(("Xtigervnc",pid=1947,fd=8))
LISTEN    0         5                     [::]:5903                [::]:*        users:(("Xtigervnc",pid=2251,fd=8))
LISTEN    0         5                     [::]:5904                [::]:*        users:(("Xtigervnc",pid=2429,fd=8))
LISTEN    0         5                     [::]:5905                [::]:*        users:(("Xtigervnc",pid=2607,fd=8))
LISTEN    0         5                     [::]:5906                [::]:*        users:(("Xtigervnc",pid=2783,fd=8))
LISTEN    0         5                     [::]:5907                [::]:*        users:(("Xtigervnc",pid=2959,fd=8))

Abrimos el navegador y accedemos al gestor de perfiles de Firefox, con el comando, mostrado en la imagen:

Siguiendo este mismo procedimiento, se crea los demás perfiles de Firefox, hasta llegar a los 7 requeridos (total de administradores de red):

  • franco.diaz
  • naylet.carballo
  • maybel
  • danilo.noa
  • mairela.usatorres
  • pavel
  • mayra.perez

De esta manera, cada vez que un usuario se conecte a una instancia VNC del localhost, podrá ejecutar su propio navegador sin interrumpir el trabajo de otro administrador que esté administrando simultáneamente desde el Firefox. Para ello, es necesario que se ejecute desde la consola (genoma-terminal, en este caso), dentro de cada sesión VNC, el comando que permitirá lanzar el gestor de perfiles de Firefox:

firefox --profilemanager

O simplemente ejecutar la aplicación desde el entorno gráfico. Cualquiera de las dos vías nos llevara a donde queremos:

Nos abrirá una instancia de Firefox para el perfil “franco.diaz”, en este caso:

Lo anterior significa que, cada usuario podrá trabajar individualmente con su perfil de Firefox, siendo el usuario del sistema “root” quien ejecute siempre el programa.

Es importante resaltar, el desempeño que pueda tener el servidor con tantos perfiles de Firefox ejecutándose simultáneamente y varias instancias VNC. Siempre probar y analizar su consumo, por si es necesario dotar al servidor de mayores recursos hardware.

1.3.       Implementación y configuración de Guacamole

Guacamole es un RDG (Remote Desktop Gateway) sin cliente dedicado. Soporta protocolos estándar como SSH, VNC, RDP. Gracias a HTML5, una vez Guacamole es instalado en un servidor, todo lo que se necesita para acceder a los escritorios es un navegador. Se trata de una solución de software libre que nos permitirá gestionar remotamente nuestros servidores vía web.

1.3.1.  Servidor Guacamole

Instalar paquetes de dependencia:

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

Descargamos el servidor de Guacamole y lo descompactamos:

cd /tmp
wget https://downloads.apache.org/guacamole/1.3.0/source/guacamole-server-1.3.0.tar.gz
tar xfz guacamole-server-*.tar.gz

Accedemos al directorio y lo preparamos para la compilación:

cd guacamole-server-1.3.0
./configure --with-init-dir=/etc/init.d --enable-allow-freerdp-snapshots

Compilamos el servidor:

make

Instalamos el servidor:

make install

Actualizamos la cache del sistema de las bibliotecas instaladas:

ldconfig

Recargamos «systemd», para que pueda encontrar el servicio «guacd» (demonio proxy Guacamole), instalado en el directorio «/etc/init.d»:

systemctl daemon-reload

Iniciamos el servicio:

systemctl start guacd

Habilitamos auto-inicio con el sistema:

systemctl enable guacd

Verificamos su estado:

systemctl status guacd

El servicio debe estar funcionando y escuchando por la IP 127.0.0.1 y puerto 4822:

ss -lnpt | grep guacd

Debe devolver lo siguiente y confirmar lo dicho anteriormente:

LISTEN    0         5                 127.0.0.1:4822            0.0.0.0:*        users:(("guacd",pid=5883,fd=4))

Creamos el directorio y fichero de configuración de Guacamole:

mkdir /etc/guacamole/
nano /etc/guacamole/guacamole.properties

Agregamos las siguientes líneas al fichero, que ya vienen por defecto habilitadas en el servicio, pero que, de esta manera, podremos editar cuando la necesidad lo requiera:

# Hostname and port of guacamole proxy
guacd-hostname: localhost
guacd-port:     4822

1.3.2.  Cliente web para Guacamole

La aplicación web de Guacamole está escrita en Java, así que necesitaremos instalar lo siguiente:

apt install -y tomcat9 tomcat9-admin tomcat9-common tomcat9-user

Habilitamos su inicio con el sistema:

systemctl enable tomcat9

Apache Tomcat escuchara en el puerto 8080:

ss -lnpt | grep java

Debe devolver lo siguiente y confirmar lo dicho anteriormente:

LISTEN    0         100                       *:8080                  *:*        users:(("java",pid=10867,fd=37))

Descargamos la aplicación web de Guacamole:

cd /tmp
wget https://downloads.apache.org/guacamole/1.3.0/binary/guacamole-1.3.0.war

Movemos el fichero al directorio de la aplicación web:

mv guacamole-1.3.0.war /var/lib/tomcat9/webapps/guacamole.war

Reiniciamos tomcat9 y guacd:

systemctl restart tomcat9 guacd

1.3.3.  MariaDB para Guacamole

Instalamos MariaDB:

apt install -y mariadb-server mariadb-client

Aseguramos la instalación de MariaDB:

mysql_secure_installation

Respondemos según convenga:

  • Enter current password for root (enter for none): ENTER
  • Set root password? [Y/n] y
  • New password: *****
  • Re-enter new password: *****
  • Remove anonymous users? [Y/n] y
  • Disallow root login remotely? [Y/n] y
  • Remove test database and access to it? [Y/n] y
  • Reload privilege tables now? [Y/n] y

Creamos la DB y el usuario:

mysql -p

En color blanco se especifican los comandos necesarios para la creación de la DB, el usuario y sus permisos:

MariaDB [(none)]> CREATE DATABASE guacamole_db;
MariaDB [(none)]> CREATE USER 'guacamole_user'@'localhost' IDENTIFIED BY 'passw0rd';
MariaDB [(none)]> GRANT SELECT,INSERT,UPDATE,DELETE ON guacamole_db.* TO 'guacamole_user'@'localhost';
MariaDB [(none)]> FLUSH PRIVILEGES;
MariaDB [(none)]> quit;

Descargamos la extensión «jdbc-extension», para el uso de la autenticación por DB, en este caso MariaDB. Esto será necesario para poder autenticarnos con el usuario de administración de Guacamole “guacadmin”:

cd /tmp
wget http://apache.mirror.digionline.de/guacamole/1.3.0/binary/guacamole-auth-jdbc-1.3.0.tar.gz
tar xfz guacamole-auth-jdbc-1.3.0.tar.gz

Importamos la DB:

cat guacamole-auth-jdbc-1.3.0/mysql/schema/*.sql | mysql -u root -p guacamole_db

Tras especificar la contraseña root de MariaDB, se importará la DB.

Creamos el directorio de extensiones de Guacamole:
mkdir /etc/guacamole/extensions/

Instalamos la extensión, moviendo al directorio de extensiones:

mv guacamole-auth-jdbc-1.3.0/mysql/guacamole-auth-jdbc-mysql-1.3.0.jar /etc/guacamole/extensions/

Instalación del driver JDBC, para que Guacamole se conecte correctamente a la DB:

cd /tmp
wget https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-8.0.23.tar.gz
tar xfz mysql-connector-java-8.0.23.tar.gz

Creamos el directorio para el driver en guacamole y lo agregamos a dicho directorio:

mkdir /etc/guacamole/lib
mv mysql-connector-java-8.0.23/mysql-connector-java-8.0.23.jar /etc/guacamole/lib/

1.3.4.  Ajustes para autenticación por LDAP

Para que Guacamole pueda autenticar usuarios LDAP, primero hay que configurar la autenticación por MySQL/MariaDB, para acceder con el usuario de administración

nano /etc/guacamole/guacamole.properties

Agregamos lo siguiente:

# [...]
# Datos para Auth MySQL/MariaDB
mysql-hostname: localhost
mysql-port: 3306
mysql-database: guacamole_db
mysql-username: guacamole_user
mysql-password: passw0rd

Descargamos el plugin de Guacamole para autenticación por LDAP y la descompactamos:

cd /tmp
wget https://apache.mirror.iphh.net/guacamole/1.3.0/binary/guacamole-auth-ldap-1.3.0.tar.gz
tar xfz guacamole-auth-ldap-1.3.0.tar.gz

Movemos el plugin al directorio de extensiones de Guacamole:

mv guacamole-auth-ldap-1.3.0/guacamole-auth-ldap-1.3.0.jar /etc/guacamole/extensions

Agregamos la configuración de autenticación LDAP al fichero de Guacamole:

nano /etc/guacamole/guacamole.properties

Agregamos lo siguiente:

# [...]
# Auth provider class
auth-provider: net.sourceforge.guacamole.net.auth.ldap.LDAPAuthenticationProvider

# Datos para Auth LDAP/AD
ldap-hostname:           dc1.empresa.midominio.cu
ldap-port:               389
ldap-user-base-dn:       ou=Usuarios,dc=empresa,dc=midominio,dc=cu
ldap-username-attribute: samAccountName
ldap-config-base-dn:     cn=Users,dc=empresa,dc=midominio,dc=cu
ldap-encryption-method:  none
ldap-search-bind-dn:cn=administrator,cn=Users,dc=empresa,dc=midominio,dc=cu
ldap-search-bind-password:Admin*123
ldap-user-search-filter:(&(objectClass=person)(|(memberOf=cn=Guacamole,ou=Grupos,dc=empresa,dc=midominio,dc=cu)))

El servidor LDAP estará integrado en un AD (Samba4) y no se usará método de encriptación alguno para la comunicación entre el LDAP y el Guacamole.

NOTA: En el servidor AD necesitamos crear el grupo «Tservice» para los usuarios que vayan a hacer uso del Guacamole:

samba-tool group add "Guacamole" \
--groupou="OU=Grupos" \
--description="Grupo para acceso al Terminal Service de gestion"

Creamos el usuario “guacadmin” en el AD:

samba-tool user create guacadmin guacamoleadmin \
--userou="OU=Servicios,OU=Usuarios" \
--given-name="guacadmin"

Agregamos al grupo creado, los usuarios del AD que vayan a hacer uso del Guacamole:

samba-tool group addmembers "Guacamole" guacadmin
samba-tool group addmembers "Guacamole" usuario1.apellido

Reiniciamos Tomcat y y el servidor de Guacamole:

systemctl restart tomcat9 guacd

Accedemos al cliente web de Guacamole:

http://192.168.120.50:8080/guacamole

Nos autenticamos con el usuario de administración:

  • Usuario: guacadmin
  • Contraseña: guacadmin

Nos recibe la página inicial del servicio:

Nos desplazamos a la esquina superior derecha, damos clic en la ventana desplegable y click sobre “Configuración”:

Accedemos a la pestaña “Usuarios” para gestionar los permisos de los usuarios LDAP:

Vemos cómo Guacamole identifica los usuarios miembros del grupo “Guacamole” del AD para Guacamole. Ahora accedemos en el usuario del AD “usuario1.apellido”:

En este caso estaremos ajustando permisos para un usuario del AD con permisos de administración en Guacamole:

Damos click en “Guardar” para aplicar los cambios.

Ahora ya podremos acceder Guacamole con el usuario del AD “usuario1.apellido” y tener permisos de administración sobre el servicio:

Con esto realizado ya nos encontramos en condiciones de configurar conexiones. A continuación, se muestra un ejemplo de la configuración para una conexión por VNC (para acceder por escritorio remoto) al propio servidor “tservice”:

Vamos a la sección “Inicio” para acceder a las conexiones disponibles para el usuario:

En este caso aparecerán todas las conexiones habilitadas para este usuario:

Al intentar acceder a la conexión con nombre “tservice”, que está configurada para VNC, nos deberá pedir automáticamente la contraseña configurada en TigerVNC para hacer uso de la instancia 1 del servidor VNC (habíamos especificado vncadmin):

Se puede configurar la conexión VNC para que guarde la contraseña de acceso a la instancia del TigerVNC especificada.

Tras una autenticación exitosa, nos debe mostrar el escritorio de XFCE, entorno gráfico configurado para el host “tservice”:

Gucamole nos permite interactuar con algunas herramientas mediante la combinación de teclas “Crtl+Shift+Alt” (para acceder a ellas y para ocultarlas también). Podremos incluso, pegar texto usando la combinación “Crtl+Shift+v”. La barra de herramientas desplegable nos permite también subir y descargar ficheros, si el usuario tiene permitido el servicio SFT para la conexión.

1.3.5.  Asegurando el acceso al cliente web con HTTPS

Apache Tomcat se encuentra escuchando por el puerto 8080. Para tener una forma más sencilla de acceder al Guacamole, instalaremos Nginx y lo configuraremos como un proxy inverso, para que se acceda por el nombre de dominio “guacamole.empresa.midominio.cu” (se necesita una entrada en el DNS) para la IP del host “tservice” de cara a la red pública. Se redireccionará el tráfico de HTTP a HTTPS, cuando se intente acceder con nombre de servidor “guacamole.empresa.midominio.cu”.

Instalamos Nginx:

apt install nginx -y

Configuramos un bloque de configuración para Guacamole:

openssl req -x509 -nodes -days 730 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt

Respondemos según convenga, lo resaltado en color blanco:

Generating a RSA private key
........................................................................................................................................................................+++++
..................+++++
writing new private key to '/etc/ssl/private/nginx-selfsigned.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CU
State or Province Name (full name) [Some-State]:HABANA
Locality Name (eg, city) []:LaHabana
Organization Name (eg, company) [Internet Widgits Pty Ltd]:EMPRESA
Organizational Unit Name (eg, section) []:REDES
Common Name (e.g. server FQDN or YOUR name) []:guacamole.empresa.midominio.cu
Email Address []:[email protected]

Generamos el parámetro DH. Con 2048 bits debería ser suficientes, pero por requerimientos de la empresa, lo llevaremos a su máximo valor, al tratarse de un acceso que pudiera ser desde internet (aun cuando sea un acceso desde una VPN):

openssl dhparam -out /etc/nginx/dhparam.pem 4096

Creamos un nuevo fragmento de configuración de Nginx en el directorio “/etc/nginx/snippets”:

nano /etc/nginx/snippets/self-signed.conf

Agregamos lo siguiente:

ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

Crearemos otra pequeña configuración que defina algunas opciones SSL:

nano /etc/nginx/snippets/ssl-params.conf

Agregamos lo siguiente:

# Autorizar solamente el uso de los protocolos TLSv1.2 y TLSv1.3
ssl_protocols TLSv1.2 TLSv1.3;

# Imponer la seleccion del cifrado por el servidor y no por el cliente
ssl_prefer_server_ciphers on;

# Autorizar cifrados de tipo AEAD y Perfect Forward Secrecy (FS-ECDHE) para TLSv1.2:
# (para TLSv1.3 no es necesario especificar los cifrados, pues todos son seguros)
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256;

# Especificar una curva para cifrados ECDHE:
ssl_ecdh_curve secp384r1;

# Parametro Diffie-Hellman para la suite de cifrados de tipo DHE:
ssl_dhparam /etc/nginx/dhparam.pem;

# Habilitar reanudacion de la sesion para mejorar rendimiento de HTTPS:
ssl_session_cache shared:SSL:10m;
ssl_session_timeout  10m;
ssl_session_tickets off;

# Habilitar OCSP stapling:
ssl_stapling on;
ssl_stapling_verify on;
resolver ns1.empresa.midominio.cu valid=300s;
resolver_timeout 5s;

# HSTS (HTTP Strict Transport Security):
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

# Proteccion contra ataque Clickjacking:
add_header X-Frame-Options SAMEORIGIN;

# Proteccion de rastreo del navegador:
add_header X-Content-Type-Options nosniff;

# Filtro Cross-site scripting (XSS):
add_header X-XSS-Protection "1; mode=block";

Creamos el bloque de configuración de Nginx para Prometheus:

nano /etc/nginx/sites-available/guacamole.vhost

Agregamos lo siguiente:

server {
        listen 80;
        server_name guacamole.empresa.midominio.cu;

        # Redireccion permanente a HTTPS
        return 301 https://$server_name$request_uri;
}

server {
        listen 443 ssl http2;
        server_name guacamole.empresa.midominio.cu;

        include snippets/self-signed.conf;
        include snippets/ssl-params.conf;

        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/ /;
        }

}

Habilitamos la configuración:

ln -s /etc/nginx/sites-available/guacamole.vhost /etc/nginx/sites-enabled/

Verificamos que la configuración no tenga errores de sintaxis:

nginx -t

Si todo está bien, debe devolvernos lo siguiente, ignorando la advertencia que nos indica:

nginx: [warn] "ssl_stapling" ignored, issuer certificate not found for certificate "/etc/ssl/certs/nginx-selfsigned.crt"
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Esta configuración en particular arroja una advertencia ya que nuestro certificado auto-firmado no puede usar el engrapado SSL. Esto se espera y nuestro servidor aún puede cifrar las conexiones correctamente, por lo que obviamos la advertencia.

Modificaremos el fichero de configuración principal de Nginx, para implementar algunas medidas de seguridad extra:

nano /etc/nginx/nginx.conf

Deshabilitamos que Nginx envíe su versión en las paginas de error o en las cabeceras del servidor, y también deshabilitamos la compresión por gzip, modificando las siguientes líneas:

# [...]       
        server_tokens off;
# [...]       
        gzip off;
# [...]

Reiniciamos el servicio:

systemctl restart nginx

El servidor web Nginx está funcionando ahora como proxy inverso para Guacamole:

https://guacamole.empresa.midominio.cu

NOTA: Se recomienda cerrar el puerto 8080 de cara a la red empresarial.

Para el caso de los usuarios que acceden por el VPN, el proxy inverso no funcionará, ya que desde el TUN10 no se tiene acceso por enrutamiento al DNS, con toda intensión, pues no se desea que lo tengan. La única opción que hay para proteger las credenciales de estos usuarios al acceder al cliente web de Guacamole, es configurar Tomcat para que funcione por el 8443 para HTTPS. Así como Tomcat usa 8080 para alejarse del puerto 80, también da la posibilidad a las conexiones cifradas mediante el 8443, alejándose el 443.

Lo primero será crear el certificado en formato “jks” para Java.

NOTA: Tomcat usa tres diferentes implementaciones de SSL:

  • JSSE: Implementación provista como parte de “Java runtime”.
  • JSSE: Implementación que usa el OpenSSL.
  • APR: implementación, que usa el motor por defecto de OpenSSL.

Generamos el certificado para ser usado por JSSE:

keytool -genkey -alias tomcat -keyalg RSA -keystore /var/lib/tomcat9/conf/localhost-rsa.jks

Respondemos las preguntas, acorde a una información que sea lógica para el usuario que revise el certificado:

Introduzca la contraseña del almacén de claves:
Volver a escribir la contraseña nueva:
¿Cuáles son su nombre y su apellido?
  [Unknown]:  guacamole.empresa.midominio.cu
¿Cuál es el nombre de su unidad de organización?
  [Unknown]:  REDES
¿Cuál es el nombre de su organización?
  [Unknown]:  EMPRESA
¿Cuál es el nombre de su ciudad o localidad?
  [Unknown]:  LaHabana
¿Cuál es el nombre de su estado o provincia?
  [Unknown]:  HABANA
¿Cuál es el código de país de dos letras de la unidad?
  [Unknown]:  CU
¿Es correcto CN=guacamole.empresa.midominio.cu, OU=REDES, O=EMPRESA, L=LaHabana, ST=HABANA, C=CU?
  [no]:  si

Editamos el siguiente fichero:

nano /var/lib/tomcat9/conf/server.xml

Localizamos en el fichero “JSSE style configuration is used below” y después del primer “–>” que le sigue, agregamos lo siguiente debajo de esa flecha:

    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true">
        <SSLHostConfig protocols="TLSv1.3">
            <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
                         certificateKeystorePassword="changeit"
                         certificateKeyAlias="tomcat"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>

Reiniciamos tomcat9:

systemctl restart tomcat9

Tomcat deberá estar escuchando ahora por el 8080 (para HTTP) y el 8443 (para HTTPS):

ss -lnpt | grep java

Debe devolver algo, como lo siguiente:

LISTEN    0         100                       *:8080                  *:*        users:(("java",pid=29823,fd=37))
LISTEN    0         100                       *:8443                  *:*        users:(("java",pid=29823,fd=43))

Con esto configurado, se resuelve el problema de los usuarios dentro del TUN10, los cuales podrán acceder al Guacamole mediante el siguiente enlace:

https://192.168.254.50:8443/guacamole

 

Siendo “192.168.254.50” la dirección IP fija del “tservice”, por dentro del TUN10. Lo mismo sucederá por el TUN11, pero con la IP “192.168.253.50”.

NOTA: Se recomienda cerrar el puerto 8080 para el TUN10 y el TUN11.

 

1.4.       Instancias OpenVPN en modo cliente

Se repetirá el mismo procedimiento realizado en el host “vpn” para la instalación de OpenVPN.

Instalamos OpenSSL y libssl1.1 (1.1.1d), easy-rsa (3.0.6-1) y openvpn (2.4.7-1) por los repos oficiales de Buster:

apt install openssl libssl-dev easy-rsa openvpn -y

Agregamos los repos de Bullseye:

echo "deb [trusted=yes] https://ftp.debian.org/debian bullseye main contrib non-free" > /etc/apt/sources.list.d/bullseye.list
apt update

Instalación de OpenSSL (1.1.1i) y sus librerías actualizadas

apt install openssl libssl-dev -y

Instalación de OpenVPN (2.5.0-1):

apt install openvpn -y

Comentamos los repos de Bullseye y volvemos actualizar el listado:

echo "#deb https://ftp.debian.org/debian bullseye main contrib non-free" > /etc/apt/sources.list.d/bullseye.list
apt update

Creamos el siguiente enlace simbólico:

ln -s /usr/sbin/openvpn /usr/local/sbin/

Directorio que albergará la ca, certificado y llaves para cliente:

mkdir -p /etc/openvpn/client/ovpn10/auth
mkdir -p /etc/openvpn/client/ovpn11/auth

Creamos el fichero de configuración de OpenVPN para TUN10:

nano /etc/openvpn/client/ovpn10.conf

Agregamos lo siguiente:

#     ____                 _    ______  _   __   _________            __
#    / __ \____  ___  ____| |  / / __ \/ | / /  / ____/ (_)__  ____  / /_
#   / / / / __ \/ _ \/ __ \ | / / /_/ /  |/ /  / /   / / / _ \/ __ \/ __/
#  / /_/ / /_/ /  __/ / / / |/ / ____/ /|  /  / /___/ / /  __/ / / / /_ 
#  \____/ .___/\___/_/ /_/|___/_/   /_/ |_/   \____/_/_/\___/_/ /_/\__/ 
#      /_/                                                              

# Especificar modo de funcionamiento
client

# Tipo de interfaz
dev tun10

# Protocolo de transporte a usar
proto udp

# Servidor remoto
remote 192.168.130.103 11940

# No almacenar en RAM las credenciales de autenticacion
auth-nocache

# Autenticarse con el servidor por usuario y password
auth-user-pass

# Mantener estado de llave e interfaz, aun despues del reinicio
persist-key
persist-tun

# Rutas para CA, y certificado y llave del cliente, con las capas de TLS activadas
tls-client
ca      /etc/openvpn/client/ovpn10/auth/ca.crt
cert    /etc/openvpn/client/ovpn10/auth/tservice.crt
key     /etc/openvpn/client/ovpn10/auth/tservice.key

# HMAC firewall con encriptacion de mensajes con llave pre-compartida
tls-crypt /etc/openvpn/client/ovpn10/auth/ta.key 1

# Usar AES-GCM para encriptacion de datos
cipher AES-256-GCM

# Migrar de cifrados obsoletos
data-ciphers AES-256-GCM

# Medida para prevenir que un cliente use su certificado para hacerse pasar por un servidor
remote-cert-tls server

# Para certificados con el estandar X509v3 de la UIT
remote-cert-eku "TLS Web Server Authentication"

# Usar SHA512 para autenticar datos encriptados
auth SHA512

# Nivel de verbosidad de los logs
verb 3

# Intentar de resolver indefinidamente el hostname del servidor
resolv-retry infinite

# Permitir compresion y usar la ultima version de compresion disponible
allow-compression yes
compress lz4-v2

# No enlazarse a un puerto local especifico
nobind

# Degradar privilegios despues de la inicializacion (solo para clientes no-Windows)
user nobody
group nogroup

# Si el cliente no es sobre Windows y presenta problemas con la opcion "block-outside-dns", descomentar la siguiente opcion
ignore-unknown-option block-outside-dns

Creamos el fichero de configuración de OpenVPN para TUN11:

nano /etc/openvpn/client/ovpn11.conf

Agregamos lo siguiente:

#     ____                 _    ______  _   __   _________            __
#    / __ \____  ___  ____| |  / / __ \/ | / /  / ____/ (_)__  ____  / /_
#   / / / / __ \/ _ \/ __ \ | / / /_/ /  |/ /  / /   / / / _ \/ __ \/ __/
#  / /_/ / /_/ /  __/ / / / |/ / ____/ /|  /  / /___/ / /  __/ / / / /_ 
#  \____/ .___/\___/_/ /_/|___/_/   /_/ |_/   \____/_/_/\___/_/ /_/\__/ 
#      /_/                                                              

# Especificar todo de funcionamiento
client

# Tipo de interfaz
dev tun11

# Protocolo de transporte a usar
proto udp

# Servidor remoto
remote 192.168.130.103 11941

# No almacenar en RAM las credenciales de autenticacion
auth-nocache

# Autenticarse con el servidor por usuario y password
auth-user-pass

# Mantener estado de llave e interfaz, aun despues del reinicio
persist-key
persist-tun

# Rutas para CA, y certificado y llave del cliente, con las capas de TLS activadas
tls-client
ca    /etc/openvpn/client/ovpn11/auth/ca.crt
cert /etc/openvpn/client/ovpn11/auth/tservice.crt
key   /etc/openvpn/client/ovpn11/auth/tservice.key

# HMAC firewall con encriptacion de mensajes con llave pre-compartida
tls-crypt /etc/openvpn/client/ovpn11/auth/ta.key 1

# Usar AES-GCM para encriptacion de datos
cipher AES-256-GCM

# Migrar de cifrados obsoletos
data-ciphers AES-256-GCM

# Medida para prevenir que un cliente use su certificado para hacerse pasar por un servidor
remote-cert-tls server

# Para certificados con el estandar X509v3 de la UIT
remote-cert-eku "TLS Web Server Authentication"

# Usar SHA512 para autenticar datos encriptados
auth SHA512

# Nivel de verbosidad de los logs
verb 3

# Intentar de resolver indefinidamente el hostname del servidor
resolv-retry infinite

# Permitir compresion y usar la ultima version de compresion disponible
allow-compression yes
compress lz4-v2

# No enlazarse a un puerto local especifico
nobind

# Degradar privilegios despues de la inicializacion (solo para clientes no-Windows)
user nobody
group nogroup

# Si el cliente no es sobre Windows y presenta problemas con la opcion "block-outside-dns", descomentar la siguiente opcion
ignore-unknown-option block-outside-dns

En este caso, lo habilitaremos las instancias de openvpn como un servicio, pues para el host “tservice” se trata de clientes y se debe autenticar en cada caso, con su contraseña del AD para el TUN10 y con la del usuario PAM creado en el “vpn” para el TUN11.

Reiniciamos openvpn:

service openvpn restart

Iniciando conexión VPN contra “ovpn10”:

openvpn /etc/openvpn/client/ovpn10.conf

Ponemos las credenciales y estaremos conectados con el TUN10.

Para iniciar la conexión el con el segundo túnel, necesitamos abrir una nueva consola ssh y hacer lo propio, pero para el “ovpn11”:

openvpn /etc/openvpn/client/ovpn11.conf

Al cerrar la consola se cerrará la conexión en cada túnel, por lo que las conexiones no debemos hacerla desde un cliente SSH, sino de forma local, usando la interfaz grafica de XFCE y abriendo dos consolas para ejecutar las instancias ovpn. Esto habrá que hacerlo cada vez que se reinicie el servidor. A continuación muestro una imagen con lo anteriormente dicho:

1.5.       Agregados opcionales

Si el host “tservice” accede a plataformas de virtualización basadas en tecnología de VMware ESXi, entonces es necesario preparar el host para que pueda visualizar correctamente el “vSphere Web Client”. En caso de que se cuente con versiones antiguas de ESXi, como pudieran ser las que necesitan Flash Player para poder visualizar bien el cliente web y el VMware Remote Console (VMRC) para ejecutar consolas de las maquinas virtuales desde el cliente web.

Usar Flash Player dentro del host “tservice” no supone un riesgo de seguridad, pues lo va a usar el navegador del host “tservice”, el cual será solamente ejecutado por el usuario “root” desde el entorno gráfico XFCE. Será necesario instalar el descontinuado y no recomendado programa, si no se desea actualizar la plataforma de virtualización o no se pueda en dicho momento. Acceder al entorno visual XFCE del host “tservice” solo será posible visualizarse si se conecta localmente al host o si se accede a través del TigerVNC, habiéndose autenticado previamente en el Guacamole.

Descargar el Flash Player del siguiente no oficial de Adobe (no se puede descargar del sitio oficial por estar EOL):

cd /tmp
wget https://github.com/Franco-Sparrow/franco-repos/raw/master/flash_player_npapi_linux.x86_64.tar.gz¨

Desempaquetamos el programa:

tar xf flash_player*

Movemos la extensión al directorio de plugins de Firefox:

mv libflashplayer.so /usr/lib/mozilla/plugins/

Copiamos lo siguiente:

cp -r usr/* /usr

Reiniciar el navegador y acceder al sitio con Flash Player. Habilitar el plugin cuando lo pida.

https://iuware.iu.edu/api/file/3518

Con lo anterior hecho, ya se puede acceder a versiones antiguas del vSphere Web Client.

Ahora se necesita instalar el VMRC. Para ello, primero descargamos el programa:

  • Sitio oficial de VMware (requiere estar registrado)

https://my.vmware.com/en/web/vmware/downloads/details?downloadGroup=VMRC1200&productId=974

  • Sitio alternativo

https://iuware.iu.edu/api/file/3518

En este caso usaremos el sitio alternativo:

cd /tmp
wget https://iuware.iu.edu/api/file/3518

Le damos permisos de ejecución al programa:

chmod +x VMware-Remote-Console-11.1.0-15913118.x86_64.bundle

Ejecutamos el instalador:

./VMware-Remote-Console-11.1.0-15913118.x86_64.bundle

Respondemos según convenga y finalizamos la instalación. Con lo anterior completado, el host “tservice” estará preparado para, desde el navegador, ejecutar el programa VMRC, siempre que lo requiera vSphere Web Client.

2.    Cliente OpenVPN en Windows

En este caso nos situaremos en el caso para los usuarios poseedores de un terminal móvil de la empresa, que accedan por el APN de la misma, ejecuten la VPN desde una PC, que está conectada por anclaje USB al terminal o por un hotspot. Aunque también es posible conectarse desde el propio terminal de la empresa (generalmente Android) usando la aplicación para móviles, seremos prácticos en este casso y es que, gestionar la red desde un móvil es un poco incómodo comparado con una estación de trabajo.

Lo primero será descargar el programa del siguiente enlace:

https://swupdate.openvpn.org/community/releases/OpenVPN-2.5.0-I601-amd64.msi

Ejecutamos el instalador y seguimos los pasos de las imágenes:

Tras la instalación, el programa nos alerta de que no poseemos ninguna configuración inicial:

Creamos el siguiente fichero “C:\Program Files\OpenVPN\config\client.ovpn” con permisos de administración y agregamos el siguiente contenido:

#     ____                 _    ______  _   __   _________            __
#    / __ \____  ___  ____| |  / / __ \/ | / /  / ____/ (_)__  ____  / /_
#   / / / / __ \/ _ \/ __ \ | / / /_/ /  |/ /  / /   / / / _ \/ __ \/ __/
#  / /_/ / /_/ /  __/ / / / |/ / ____/ /|  /  / /___/ / /  __/ / / / /_ 
#  \____/ .___/\___/_/ /_/|___/_/   /_/ |_/   \____/_/_/\___/_/ /_/\__/ 
#      /_/                                                              

# Especificar modo de funcionamiento
client

# Tipo de interfaz
dev tun

# Protocolo de transporte a usar
proto udp

# Servidor remoto
remote 192.168.130.103 11940

# No almacenar en RAM las credenciales de autenticacion
auth-nocache

# Autenticarse con el servidor por usuario y password
auth-user-pass

# Mantener estado de llave e interfaz, aun despues del reinicio
persist-key
persist-tun

# Rutas para CA, y certificado y llave del cliente, con las capas de TLS activadas
tls-client
ca ca.crt
cert franco.diaz.crt
key franco.diaz.key

# HMAC firewall con encriptacion de mensajes con llave pre-compartida
tls-crypt ta.key 1

# Usar AES-GCM para encriptacion de datos
cipher AES-256-GCM

# Migrar de cifrados obsoletos
data-ciphers AES-256-GCM

# Medida para prevenir que un cliente use su certificado para hacerse pasar por un servidor
remote-cert-tls server

# Para certificados con el estandar X509v3 de la UIT
remote-cert-eku "TLS Web Server Authentication"

# Usar SHA512 para autenticar datos encriptados
auth SHA512

# Nivel de verbosidad de los logs
verb 3

# Intentar de resolver indefinidamente el hostname del servidor
resolv-retry infinite

# Permitir compresion y usar la ultima version de compresion disponible
allow-compression yes
compress lz4-v2

# No enlazarse a un puerto local especifico
nobind

# Degradar privilegios despues de la inicializacion (solo para clientes no-Windows)
;user nobody
;group nogroup

Una vez copiados los certificados y llaves necesarias para la conexión al mismo directorio “config”, iniciamos la conexión. Veremos que nos pedirá autenticación para el usuario. Dicha contraña deberá coincidir con la especificada para el usuario de sistema en el servidor que lo albergue como usuario PAM:

Tras introducir correctamente la contraseña nos pedirá la contraseña para el certificado:

Una vez conectado al servidor, si nos paramos encima del icono del cliente en la barra del menú Inicio, nos mostrará el nombre del servidor al que nos hemos conectado, la fecha de conexión y la dirección IP obtenida:

Verificamos en el adaptador de red que se activa para la conexión VPN con el “ovpn10”:

Ignorar el siguiente mensaje de los logs del cliente:

# [...]
WARNING: Compression for sending and receiving enabled. Compression has been used in the past to break encryption. Allowing compression allows attacks that break encryption. Using "--allow-compression yes" is strongly discouraged for common usage. See --compress in the manual page for more information
# [...]

¿De cuánta utilidad te ha parecido este contenido?

¡Haz clic en una estrella para puntuar!

Promedio de puntuación 5 / 5. Recuento de votos: 5

Hasta ahora, ¡no hay votos!. Sé el primero en puntuar este contenido.

Sobre Franco Diaz Hurtado 27 artículos
Ing. Telecomunicaciones y Electrónica; 1er Especialista en Redes de ECASA Nivel Central

3 comentarios

  1. Firefox 67.0 Firefox 67.0 Windows 10 x64 Edition Windows 10 x64 Edition
    Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0

    Hola Franco, probé eso y no resolví. Como lo solucione fue eliminando en el MySQL la BD guacamole_db, el usuario y los privilegios creados. Luego repetí este paso y la importación de la BD: cat guacamole-auth-jdbc-1.3.0/mysql/schema/*.sql | mysql -u root -p guacamole_db
    Con esto me funcionó todo ok.

  2. Firefox 67.0 Firefox 67.0 Windows 10 x64 Edition Windows 10 x64 Edition
    Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0

    Hola Franco!! muy bueno y aclarador tu articulo, me ha servido de guia para montar un guacamole. Todo me ha funcionado excepto poder loguearme en la web con las credenciales por defecto guacadmin (guacadmin) recibo el error Usuario invalido, sin embargo si lo logro con cualquier usuario del AD. Alguna sugerencia? pues hay trabajo que hacer mediante la interfaz web y no logro entrar con privilegios administrativos a ella.

    • Firefox 87.0 Firefox 87.0 Windows 10 x64 Edition Windows 10 x64 Edition
      Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:87.0) Gecko/20100101 Firefox/87.0

      Hola Sandra, me alegro que el artículo le haya sido bastante aclarador. Debes crear el usuario «guacadmin» en el AD, con las mismas credenciales por defecto. Esto debe poder solucionar su problema.
      Saludos

Responder a Sandra Blain Cancelar la respuesta

Tu dirección de correo electrónico no será publicada.


*