
Abrir un escritorio Windows, acceder a un Linux por SSH y trabajar en una sesión VNC usando únicamente el navegador: esa es la propuesta de Apache Guacamole. Centraliza el acceso remoto en un portal web, sin exigir un cliente específico en el equipo desde el que se accede.
En esta guía, vamos entender la arquitectura, montar un laboratorio con Docker Compose y PostgreSQL y hablar sobre autenticación local, LDAP/Active Directory, SSO, MFA, seguridad y operación. El foco es construir una base comprensible antes de poner una pasarela administrativa en la red.
Qué es Apache Guacamole (y qué no es)
O Apache Guacamole es una pasarela de acceso remoto clientless, compatible con protocolos como RDP, VNC y SSH. “Sin cliente” significa que el usuario utiliza un navegador moderno: en el servidor siguen existiendo componentes, configuración y dependencias. El proyecto es open source bajo Apache License 2.0.
No crea máquinas virtuales, no instala un escritorio en el servidor y no convierte cualquier máquina en un destino accesible. El servicio remoto debe existir, estar configurado y ser alcanzable por el gateway. En un Linux sin entorno gráfico, SSH sigue siendo una terminal, no un escritorio mágico dentro de la página.
Esto lo diferencia de phpVirtualBox: ese panel administra VMs de VirtualBox; Guacamole proporciona acceso a sesiones remotas. Son herramientas que pueden satisfacer necesidades complementarias.
Qué versión usar como referencia
En la consulta realizada el 14 de septiembre de 2026, el sitio y el archivo oficial de releases indicaban Guacamole 1.6.0, lanzado el 22 de junio de 2025, como versión actual. El tutorial fija esa versión en las dos imágenes del proyecto; no utiliza latest.
Las notas de la versión 1.6.0 destacan mejoras de renderizado, soporte Docker e importación de conexiones por lotes, entre otros cambios. Antes de repetir el procedimiento en el futuro, consulte también los avisos de seguridad y la documentación correspondiente a la versión elegida.
La aplicación web tiene backend en Java y entrega el cliente JavaScript al navegador. El tráfico de la sesión utiliza el protocolo Guacamole; el guacd y sus componentes de protocolo hacen de puente con los destinos remotos. No es el navegador hablando RDP directamente con Windows. Referencia: arquitectura oficial.
Navegador
↓ HTTPS / WebSocket (ou túnel HTTP)
Proxy reverso → aplicação Guacamole (Java/Tomcat)
├── banco: usuários, permissões e conexões
├── LDAP ou provedor de identidade, se configurado
↓ protocolo Guacamole
guacd
├── RDP → Windows ou servidor RDP
├── SSH → Linux/Unix
└── VNC → servidor VNC
Mi recomendación de diseño es separar dos preguntas: quién puede entrar en el portal y a qué destinos puede llegar el gateway. El firewall debe limitar la segunda con independencia de la primera. Un portal autenticado no justifica abrir toda la red interna al proceso de conexión.
El banco no transporta la imagen del escritorio: almacena datos administrativos según la extensión utilizada. La documentación de introducción también ayuda a distinguir la aplicación lista para usar de las APIs disponibles para integraciones propias.
Cuándo tiene sentido usarlo
- Laboratorios de Linux y Windows accedidos desde equipos distintos.
- Equipos que necesitan un punto central para conexiones administrativas.
- Entornos de formación con destinos y permisos definidos por usuario.
- Soporte remoto a sistemas ya alcanzables por la infraestructura del gateway.
La ganancia esperada es reducir la variedad de clientes en el endpoint y organizar el acceso. Esto no elimina la necesidad de una política de credenciales, monitorización y segmentación. Tampoco hay una cantidad universal de sesiones por servidor: resolución, protocolo, actividad gráfica y latencia cambian el consumo. Mida su escenario antes de dimensionar la producción.
Laboratorio Docker: alcance y requisitos previos
Necesita Docker Engine, Docker Compose, OpenSSL y acceso al registro de imágenes. El ejemplo utiliza tres servicios: PostgreSQL, guacd y aplicación Guacamole. Solo se publica el portal, y únicamente en el loopback del host. La base de datos y el puerto 4822 no reciben publicación externa. Consulte la instalación oficial con Docker.
Validación realizada: el Compose siguiente se inició localmente; la base de datos se inicializó, el portal respondió HTTP 200 y el inicio de sesión local con el backend PostgreSQL funcionó. El usuario SQL de la aplicación se comprobó sin privilegios de superusuario. RDP, VNC, LDAP/AD, SSO, MFA y TLS de producción no se validaron contra servicios reales en este laboratorio; esas secciones son orientación de configuración basada en el manual.
Cree una carpeta nueva. Los scripts de inicialización descritos aquí son para una base de datos vacía, no para migrar una instalación existente:
mkdir -p guacamole-lab/init
cd guacamole-lab
umask 077
printf 'DB_ADMIN_PASSWORD=%s\nGUAC_DB_PASSWORD=%s\n' \
"$(openssl rand -hex 32)" "$(openssl rand -hex 32)" > .env
printf '.env\n' > .gitignore
chmod 600 .env
Las contraseñas se generan localmente. No publique el .env. Los usuarios con acceso administrativo a Docker pueden inspeccionar variables de los contenedores; los permisos de archivo no convierten las variables de entorno en una caja fuerte de secretos.
1. Crear el Compose
Guárdelo como compose.yaml:
name: lp-guacamole-lab
services:
db:
image: postgres:17
restart: unless-stopped
environment:
POSTGRES_DB: guacamole_db
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${DB_ADMIN_PASSWORD:?defina DB_ADMIN_PASSWORD}
GUAC_DB_PASSWORD: ${GUAC_DB_PASSWORD:?defina GUAC_DB_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
- ./init:/docker-entrypoint-initdb.d:ro
healthcheck:
test: [CMD-SHELL, 'pg_isready -h 127.0.0.1 -U postgres -d guacamole_db']
interval: 5s
timeout: 3s
retries: 20
networks: [backend]
guacd:
image: guacamole/guacd:1.6.0
restart: unless-stopped
networks: [backend]
guacamole:
image: guacamole/guacamole:1.6.0
restart: unless-stopped
depends_on:
db:
condition: service_healthy
guacd:
condition: service_started
environment:
GUACD_HOSTNAME: guacd
POSTGRESQL_ENABLED: 'true'
POSTGRESQL_HOSTNAME: db
POSTGRESQL_DATABASE: guacamole_db
POSTGRESQL_USERNAME: guacamole_app
POSTGRESQL_PASSWORD: ${GUAC_DB_PASSWORD:?defina GUAC_DB_PASSWORD}
ports:
- '127.0.0.1:18080:8080'
networks: [backend]
volumes:
pgdata:
networks:
backend:
La aplicación utiliza guacamole_app, no la cuenta administrativa de PostgreSQL. El volumen pgdata preserva la base de datos cuando se recrean los contenedores. La red Docker no publica los servicios internos, pero aún permite la conectividad saliente; la restricción a los destinos autorizados debe planificarse en el cortafuegos.
La imagen postgres:17 fija la línea principal, no un resumen inmutable. Para una implementación reproducible, registre los resúmenes probados y planifique las actualizaciones. No cambie la versión principal de PostgreSQL solo modificando la etiqueta sobre el mismo volumen.
2. Inicializar el esquema y el usuario SQL
Guacamole proporciona el SQL de inicialización en su imagen. Genere el archivo antes de iniciar la base de datos:
docker pull guacamole/guacamole:1.6.0
docker run --rm guacamole/guacamole:1.6.0 \
/opt/guacamole/bin/initdb.sh --postgresql > init/001-schema.sql
test -s init/001-schema.sql
Guarde el siguiente contenido como init/002-app-user.sh. Crea la cuenta SQL de la aplicación y concede acceso a los datos necesarios, sin conceder la administración del servidor:
#!/bin/sh
set -eu
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" \
-v app_password="$GUAC_DB_PASSWORD" <<'SQL'
CREATE USER guacamole_app WITH PASSWORD :'app_password';
GRANT CONNECT ON DATABASE guacamole_db TO guacamole_app;
GRANT USAGE ON SCHEMA public TO guacamole_app;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO guacamole_app;
GRANT SELECT, USAGE ON ALL SEQUENCES IN SCHEMA public TO guacamole_app;
SQL
chmod 644 init/001-schema.sql init/002-app-user.sh
La preparación del esquema y los permisos se describen en el manual de PostgreSQL. Los archivos se procesarán en el primer inicio del volumen vacío. Editar el .env después no cambia automáticamente las contraseñas ya grabadas en la base de datos.
3. Desplegar y probar el portal
docker compose config --quiet
docker compose up -d
docker compose ps
docker compose logs --tail=100 db guacd guacamole
curl -I http://127.0.0.1:18080/guacamole/
Espere al inicio de Tomcat. La dirección local es http://127.0.0.1:18080/guacamole/. Si Docker está en otro servidor, puedes usar un túnel SSH temporal, ejecutado en tu equipo:
ssh -N -L 18080:127.0.0.1:18080 usuario@servidor
Sustituye usuario y servidor por tu entorno. Después abre la misma dirección local en el navegador. Esto mantiene la prueba fuera de la exposición pública.
El esquema inicial crea el acceso guacadmin / guacadmin. Accede únicamente mediante el acceso restringido, cambia inmediatamente la contraseña y prepara una cuenta administrativa individual antes de habilitar usuarios. No confundas este inicio de sesión del portal con las contraseñas SQL del .env. Referencia: autenticación por base de datos.
4. Configurar la primera conexión
En el área administrativa, crea una conexión y elige protocolo, dirección y credenciales adecuadas. Comienza con un destino desechable del laboratorio y da acceso solo a la cuenta de prueba. Verifica la conectividad desde la red del guacd, no solo desde tu portátil.
| Protocolo | Destino necesario | Verificación esencial |
|---|---|---|
| SSH | Servidor SSH configurado | Usuario, clave o contraseña e identidad del host. |
| RDP | Servidor RDP habilitado | Política de seguridad, certificado, cuenta y dominio cuando proceda. |
| VNC | Servidor VNC disponible | Autenticación, protección del transporte y puerto configurado en el destino. |
Funciones como audio, transferencia de archivos y portapapeles dependen del protocolo y de la configuración. No habilites todo por comodidad: elige lo que el usuario necesita. Evites convertir “omitir certificado” en una configuración permanente de RDP. Los parámetros están en la guía de configuración; para el acceso mediante clave, consulta también nuestro artículo sobre autenticación SSH.
HTTPS y proxy inverso: no expongas el laboratorio tal cual
Para uso compartido, coloque el portal detrás de HTTPS. El proxy debe preservar WebSocket y no acumular los datos del túnel en búferes. El ejemplo siguiente es un bloque de ubicación para un servidor nginx con TLS ya configurado, ejecutándose en el mismo host que Docker; no es una configuración TLS completa:
location /guacamole/ {
proxy_pass http://127.0.0.1:18080;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
access_log off;
}
El registro de acceso de esa ubicación se ha deshabilitado para no registrar tokens presentes en las URL. Si lo necesita, defina un formato saneado sin parámetros sensibles. Antes de activarlo, valide su configuración con nginx -t. Si nginx está en otro contenedor, el loopback anterior no representa al host: adapte la red y el upstream.
Para registrar correctamente el origen, el manual indica habilitar REMOTE_IP_VALVE_ENABLED y limitar los proxies de confianza con PROXY_ALLOWED_IPS_REGEX. No acepte cabeceras de origen de cualquier cliente. Referencia de proxy y TLS.
Autenticación: tres preguntas diferentes
- ¿Quién está entrando? Inicio de sesión local, directorio LDAP o proveedor SSO.
- ¿Qué puede acceder esa persona? Permisos sobre conexiones, grupos y administración.
- ¿Cómo entra la sesión en el destino? Credenciales aceptadas por Windows, Linux o servidor VNC.
No trate las tres etapas como una única contraseña. Una identidad autenticada en el portal no recibe automáticamente una cuenta en el sistema remoto. Esta separación también ayuda a investigar el caso típico: el inicio de sesión funciona, pero no aparece ninguna conexión.
LDAP y Active Directory: identidad centralizada
La extensión LDAP autentica mediante bind. Hay dos diseños: almacenar conexiones en el directorio con el esquema guacConfigGroup, o usar LDAP para identidad y base de datos para conexiones. El segundo evita modificar el esquema solo para guardar conexiones. La asociación entre cuentas y grupos depende de nombres coincidentes entre las fuentes. Documentación LDAP/AD.
Ejemplo ilustrativo para AD, a añadir al environment de guacamole, manteniendo PostgreSQL:
LDAP_ENABLED: "true"
LDAP_HOSTNAME: "dc01.example.org"
LDAP_PORT: "636"
LDAP_ENCRYPTION_METHOD: "ssl"
LDAP_USER_BASE_DN: "DC=example,DC=org"
LDAP_USERNAME_ATTRIBUTE: "sAMAccountName"
LDAP_SEARCH_BIND_DN: "CN=svc-guacamole,OU=Servicos,DC=example,DC=org"
LDAP_SEARCH_BIND_PASSWORD: ${LDAP_BIND_PASSWORD:?defina LDAP_BIND_PASSWORD}
Sustituya los valores por el directorio real. La cuenta de búsqueda resuelve el DN del usuario; no necesita ser administradora del dominio. LDAPS usa ssl; StartTLS usa starttls. La cadena de certificados debe ser de confianza para Java. No desactive la validación para ocultar un error de certificado.
Configurar LDAP no elimina automáticamente el inicio de sesión local de la base de datos: las extensiones pueden coexistir. Revise las cuentas locales para evitar una ruta alternativa no deseada tras bloquear a alguien en AD.
Mi lista de comprobación de homologación es probar usuario autorizado, usuario sin permiso, credencial no válida, cuenta bloqueada, certificado no válido e indisponibilidad del directorio. Para grupos, verifique bases y atributos antes de asociar permisos. No suponga que todos los grupos de AD se han convertido automáticamente en grupos autorizados del portal.
SSO: OpenID Connect, SAML y CAS
O Guacamole ofrece opciones de inicio de sesión único para delegar la autenticación. A diferencia del formulario LDAP, el SSO puede redirigir al usuario a un proveedor de identidad compartido con otras aplicaciones. El manual también contempla certificados y tarjetas inteligentes.
| Opción | Qué evaluar |
|---|---|
| OpenID Connect | Flujo soportado, emisor, claves públicas, cliente y URI de retorno. |
| SAML | Metadatos, identidad del proveedor, certificados e identificación del usuario. |
| CAS | Servidor CAS existente, URL de servicio y configuración de validación. |
En la documentación 1.6.0, la extensión OpenID Connect utiliza el flujo implicit. No asuma soporte para Authorization Code con PKCE porque el proveedor ofrezca ese flujo. Verifique la compatibilidad y la política de seguridad de la organización antes de elegir la integración. La extensión autentica; los datos de las conexiones deben proceder de otra extensión, como la de base de datos.
Para entornos ya estandarizados en estos protocolos, consulte las configuraciones específicas de SAML e CAS. No copie endpoints entre protocolos: los metadatos, las validaciones y la respuesta son diferentes.
Mi guion de despliegue comienza con una identidad de prueba y un identificador estable, combinado con permisos mínimos. Después vienen casos de rechazo, expiración, cierre de sesión y recuperación administrativa. Pruebe también lo que ocurre con una sesión ya abierta tras revocar al usuario: el bloqueo de nuevos inicios de sesión no demuestra el cierre instantáneo de todas las sesiones.
MFA: TOTP en el portal o política en el proveedor
La extensión TOTP añade un segundo factor y exige el almacenamiento de los datos de inscripción; PostgreSQL puede desempeñar ese papel. En Docker, la activación utiliza TOTP_ENABLED: "true". El usuario completa la inscripción con su autenticador.
Active primero con una cuenta de prueba y prepare un procedimiento de recuperación. Si el SSO exige MFA en el proveedor, valide la política aplicada a la aplicación Guacamole; no deduzca protección solo por existir un proveedor corporativo. Evite superponer desafíos sin necesidad y revise excepciones de usuarios y grupos.
Grabaciones y auditoría necesitan planificación
Guacamole ofrece grabación de sesiones y reproducción en el navegador mediante configuración. La extensión de reproducción localiza los archivos relacionados con el historial; la base de datos por sí sola no contiene necesariamente la grabación. Guía de grabación y reproducción.
El Compose de este artículo no habilita grabaciones. Si las añade, planifique volúmenes, permisos, espacio, retención y acceso al reproductor. Las sesiones pueden exponer datos sensibles: informe a los usuarios, limite quién revisa el material y no habilite la captura de teclas sin una necesidad explícita.
Copia de seguridad, actualización y diagnóstico
Realice una copia de seguridad de la base de datos, configuraciones, extensiones personalizadas y archivos persistentes adicionales. Para producir un volcado lógico del laboratorio:
umask 077
docker compose exec -T db pg_dump -U postgres -d guacamole_db -Fc \
> "guacamole-$(date +%F-%H%M%S).dump"
Guarde el volcado protegido y pruebe la restauración en otro entorno. Recrear el contenedor no equivale a restaurar datos. No ejecute docker compose down -v en producción: la opción elimina los volúmenes asociados y puede borrar la base de datos.
En la actualización, lea las notas y scripts de migración aplicables, preserve la compatibilidad de las extensiones y programe indisponibilidad. Si la migración crea tablas o secuencias, vuelva a aplicar los permisos necesarios a la cuenta SQL de la aplicación. Reiniciar la aplicación puede interrumpir sesiones. Nuestra guía de Uptime Kuma con Docker y nginx ayuda a complementar la monitorización del portal.
| Síntoma | Por dónde empezar |
|---|---|
| El portal no abre | Registros de la aplicación, puerto local, inicio de Tomcat y proxy. |
| Login local falla | Esquema inicializado, usuario SQL, contraseña y permisos. |
| El login funciona; no hay conexiones | Permisos y asociación de identidades entre orígenes. |
| Conexión remota falla | Registros de guacd, DNS, ruta, firewall y servicio en el destino. |
| LDAP falla | Base DN, atributo de usuario, bind y confianza TLS de Java. |
| SSO vuelve a error o bucle | URI pública, identificación del proveedor, mapeo y cabeceras del proxy. |
| La sesión se congela o va lenta | WebSocket, buffering, timeouts, latencia y carga real. |
Lista de comprobación antes de ponerlo a disposición del equipo
- Contraseña inicial sustituida y cuentas administrativas individuales.
- HTTPS y proxies de confianza configurados; acceso a guacd restringido.
- Destinos y permisos limitados, incluso en el firewall.
- Autenticación, MFA y rutas de recuperación homologadas.
- Credenciales, volcados y registros protegidos contra divulgación.
- Backups restaurados en prueba y rutina de actualización definida.
- Integraciones remotas probadas con cuentas de bajo privilegio.
Apache Guacamole puede hacer que el acceso remoto sea más organizado, pero también concentra el acceso a sistemas importantes. Comience por el laboratorio, comprenda cada capa y solo entonces extienda su uso. La referencia permanente es el manual oficial: instalar el portal es solo el comienzo de la operación segura.