
Abrir um desktop Windows, acessar um Linux por SSH e trabalhar em uma sessão VNC usando apenas o navegador: essa é a proposta do Apache Guacamole. Ele centraliza o acesso remoto em um portal web, sem exigir um cliente específico no computador de quem acessa.
Neste guia, vamos entender a arquitetura, montar um laboratório com Docker Compose e PostgreSQL e discutir autenticação local, LDAP/Active Directory, SSO, MFA, segurança e operação. O foco é construir uma base compreensível antes de colocar um gateway administrativo na rede.
O que é o Apache Guacamole — e o que ele não é
O Apache Guacamole é um gateway de acesso remoto clientless, com suporte a protocolos como RDP, VNC e SSH. “Sem cliente” significa que o usuário utiliza um navegador moderno: no servidor, continuam existindo componentes, configuração e dependências. O projeto é open source sob Apache License 2.0.
Ele não cria máquinas virtuais, não instala um desktop no servidor e não transforma qualquer máquina em um destino acessível. O serviço remoto precisa existir, estar configurado e ser alcançável pelo gateway. Em um Linux sem ambiente gráfico, SSH continua sendo terminal, não um desktop mágico dentro da página.
Isso o diferencia do phpVirtualBox: aquele painel administra VMs do VirtualBox; o Guacamole fornece acesso a sessões remotas. São ferramentas que podem atender a necessidades complementares.
Qual versão usar como referência
Na consulta realizada em 14 de setembro de 2026, o site e o arquivo oficial de releases indicavam Guacamole 1.6.0, lançado em 22 de junho de 2025, como versão atual. O tutorial fixa essa versão nas duas imagens do projeto; não utiliza latest.
As notas da versão 1.6.0 destacam melhorias de renderização, suporte Docker e importação de conexões em lote, entre outras mudanças. Antes de repetir o procedimento no futuro, consulte também os avisos de segurança e a documentação correspondente à versão escolhida.
A aplicação web tem backend em Java e entrega o cliente JavaScript ao navegador. O tráfego da sessão utiliza o protocolo Guacamole; o guacd e seus componentes de protocolo fazem a ponte com os destinos remotos. Não é o navegador falando RDP diretamente com o Windows. Referência: arquitetura 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
Minha recomendação de desenho é separar duas perguntas: quem pode entrar no portal e quais destinos o gateway pode alcançar. O firewall deve limitar a segunda independentemente da primeira. Um portal autenticado não justifica liberar toda a rede interna para o processo de conexão.
O banco não transporta a imagem do desktop: ele armazena dados administrativos conforme a extensão utilizada. A documentação de introdução também ajuda a distinguir a aplicação pronta das APIs disponíveis para integrações próprias.
Quando faz sentido usar
- Laboratórios de Linux e Windows acessados de computadores diferentes.
- Equipes que precisam de um ponto central para conexões administrativas.
- Ambientes de treinamento com destinos e permissões definidos por usuário.
- Suporte remoto a sistemas já alcançáveis pela infraestrutura do gateway.
O ganho esperado é reduzir a variedade de clientes no endpoint e organizar o acesso. Isso não elimina a necessidade de política de credenciais, monitoramento e segmentação. Também não há uma quantidade universal de sessões por servidor: resolução, protocolo, atividade gráfica e latência mudam o consumo. Meça o seu cenário antes de dimensionar produção.
Laboratório Docker: escopo e pré-requisitos
Você precisa de Docker Engine, Docker Compose, OpenSSL e acesso ao registro de imagens. O exemplo usa três serviços: PostgreSQL, guacd e aplicação Guacamole. Somente o portal é publicado, e apenas no loopback do host. Banco e porta 4822 não recebem publicação externa. Consulte a instalação oficial com Docker.
Validação realizada: o Compose abaixo foi iniciado localmente; o banco inicializou, o portal respondeu HTTP 200 e o login local com o backend PostgreSQL funcionou. O usuário SQL da aplicação foi conferido sem privilégios de superusuário. RDP, VNC, LDAP/AD, SSO, MFA e TLS de produção não foram validados contra serviços reais neste laboratório; essas seções são orientação de configuração baseada no manual.
Crie uma pasta nova. Os scripts de inicialização descritos aqui são para um banco vazio, não para migrar uma instalação 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
As senhas são geradas localmente. Não publique o .env. Usuários com acesso administrativo ao Docker podem inspecionar variáveis dos contêineres; permissões de arquivo não transformam variáveis de ambiente em um cofre de segredos.
1. Criar o Compose
Salve 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:
A aplicação usa guacamole_app, não a conta administrativa do PostgreSQL. O volume pgdata preserva o banco quando contêineres são recriados. A rede Docker não publica os serviços internos, mas ainda permite conectividade de saída; a restrição aos destinos autorizados deve ser planejada no firewall.
A imagem postgres:17 fixa a linha principal, não um digest imutável. Para uma implantação reproduzível, registre os digests testados e planeje atualizações. Não troque a versão principal do PostgreSQL apenas alterando a tag sobre o mesmo volume.
2. Inicializar o esquema e o usuário SQL
O Guacamole fornece o SQL de inicialização em sua imagem. Gere o arquivo antes de iniciar o banco:
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
Salve o conteúdo abaixo como init/002-app-user.sh. Ele cria a conta SQL da aplicação e concede acesso aos dados necessários, sem conceder administração do 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
A preparação do esquema e as permissões são descritas no manual de PostgreSQL. Os arquivos serão processados na primeira inicialização do volume vazio. Editar o .env depois não troca automaticamente senhas já gravadas no banco.
3. Subir e testar o 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 a inicialização do Tomcat. O endereço local é http://127.0.0.1:18080/guacamole/. Se o Docker estiver em outro servidor, você pode usar um túnel SSH temporário, executado no seu computador:
ssh -N -L 18080:127.0.0.1:18080 usuario@servidor
Substitua usuário e servidor pelo seu ambiente. Depois abra o mesmo endereço local no navegador. Isso mantém o teste fora da exposição pública.
O esquema inicial cria o acesso guacadmin / guacadmin. Entre apenas pelo acesso restrito, altere imediatamente a senha e prepare uma conta administrativa individual antes de liberar usuários. Não confunda esse login do portal com as senhas SQL do .env. Referência: autenticação por banco.
4. Configurar a primeira conexão
Na área administrativa, crie uma conexão e escolha protocolo, endereço e credenciais adequados. Comece com um destino descartável do laboratório e dê acesso apenas à conta de teste. Verifique a conectividade a partir da rede do guacd, não apenas do seu notebook.
| Protocolo | Destino necessário | Verificação essencial |
|---|---|---|
| SSH | Servidor SSH configurado | Usuário, chave ou senha e identidade do host. |
| RDP | Servidor RDP habilitado | Política de segurança, certificado, conta e domínio quando aplicável. |
| VNC | Servidor VNC disponível | Autenticação, proteção do transporte e porta configurada no destino. |
Recursos como áudio, transferência de arquivos e área de transferência dependem do protocolo e da configuração. Não libere todos por conveniência: escolha o que o usuário precisa. Evite transformar “ignorar certificado” em configuração permanente de RDP. Os parâmetros estão no guia de configuração; para acesso por chave, veja também nosso artigo sobre autenticação SSH.
HTTPS e proxy reverso: não exponha o laboratório como está
Para uso compartilhado, coloque o portal atrás de HTTPS. O proxy deve preservar WebSocket e não acumular os dados do túnel em buffers. O exemplo abaixo é um bloco de localização para um servidor nginx com TLS já configurado, rodando no mesmo host do Docker; não é uma configuração 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;
}
O log de acesso dessa localização foi desabilitado para não registrar tokens presentes em URLs. Se precisar dele, defina um formato sanitizado sem parâmetros sensíveis. Antes de ativar, valide sua configuração com nginx -t. Se o nginx estiver em outro contêiner, o loopback acima não representa o host: adapte rede e upstream.
Para registrar corretamente a origem, o manual orienta habilitar REMOTE_IP_VALVE_ENABLED e limitar os proxies confiáveis com PROXY_ALLOWED_IPS_REGEX. Não aceite cabeçalhos de origem de qualquer cliente. Referência de proxy e TLS.
Autenticação: três perguntas diferentes
- Quem está entrando? Login local, diretório LDAP ou provedor SSO.
- O que essa pessoa pode acessar? Permissões sobre conexões, grupos e administração.
- Como a sessão entra no destino? Credenciais aceitas pelo Windows, Linux ou servidor VNC.
Não trate as três etapas como uma senha única. Uma identidade autenticada no portal não recebe automaticamente uma conta no sistema remoto. Essa separação também ajuda a investigar o caso clássico: o login funciona, mas nenhuma conexão aparece.
LDAP e Active Directory: identidade centralizada
A extensão LDAP autentica por bind. Há dois desenhos: armazenar conexões no diretório com o esquema guacConfigGroup, ou usar LDAP para identidade e banco para conexões. O segundo evita alterar o esquema somente para guardar conexões. A associação entre contas e grupos depende de nomes correspondentes entre as fontes. Documentação LDAP/AD.
Exemplo ilustrativo para AD, a adicionar ao environment de guacamole, mantendo 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}
Troque os valores pelo diretório real. A conta de busca resolve o DN do usuário; não precisa ser administradora do domínio. LDAPS usa ssl; StartTLS usa starttls. A cadeia de certificados precisa ser confiável para o Java. Não desligue a validação para esconder um erro de certificado.
Configurar LDAP não elimina automaticamente o login local do banco: as extensões podem coexistir. Revise contas locais para evitar um caminho alternativo indesejado após bloquear alguém no AD.
Meu checklist de homologação é testar usuário autorizado, usuário sem permissão, credencial inválida, conta bloqueada, certificado inválido e indisponibilidade do diretório. Para grupos, confira bases e atributos antes de associar permissões. Não suponha que todos os grupos do AD viraram automaticamente grupos autorizados do portal.
SSO: OpenID Connect, SAML e CAS
O Guacamole oferece opções de single sign-on para delegar a autenticação. Diferentemente do formulário LDAP, o SSO pode encaminhar o usuário a um provedor de identidade compartilhado com outras aplicações. O manual também contempla certificados e smart cards.
| Opção | O que avaliar |
|---|---|
| OpenID Connect | Fluxo suportado, emissor, chaves públicas, cliente e URI de retorno. |
| SAML | Metadados, identidade do provedor, certificados e identificação do usuário. |
| CAS | Servidor CAS existente, URL de serviço e configuração de validação. |
Na documentação 1.6.0, a extensão OpenID Connect utiliza o fluxo implicit. Não presuma suporte a Authorization Code com PKCE porque o provedor oferece esse fluxo. Verifique a compatibilidade e a política de segurança da organização antes de escolher a integração. A extensão autentica; os dados das conexões precisam vir de outra extensão, como a de banco.
Para ambientes já padronizados nesses protocolos, consulte as configurações específicas de SAML e CAS. Não copie endpoints entre protocolos: metadados, validações e retorno são diferentes.
Meu roteiro de implantação começa por uma identidade de teste e um identificador estável, combinado com permissões mínimas. Depois vêm casos de rejeição, expiração, logout e recuperação administrativa. Teste também o que acontece com uma sessão já aberta após revogar o usuário: bloqueio de novos logins não comprova encerramento instantâneo de todas as sessões.
MFA: TOTP no portal ou política no provedor
A extensão TOTP acrescenta um segundo fator e exige armazenamento dos dados de inscrição; PostgreSQL pode cumprir esse papel. No Docker, a ativação utiliza TOTP_ENABLED: "true". O usuário conclui a inscrição com seu autenticador.
Ative primeiro com uma conta de teste e prepare um procedimento de recuperação. Se o SSO exigir MFA no provedor, valide a política aplicada à aplicação Guacamole; não deduza proteção apenas por existir um provedor corporativo. Evite sobrepor desafios sem necessidade e revise exceções de usuários e grupos.
Gravações e auditoria precisam de planejamento
O Guacamole oferece gravação de sessões e reprodução no navegador mediante configuração. A extensão de reprodução localiza os arquivos relacionados ao histórico; o banco sozinho não contém necessariamente a gravação. Guia de gravação e reprodução.
O Compose deste artigo não habilita gravações. Se você adicioná-las, planeje volumes, permissões, espaço, retenção e acesso ao player. Sessões podem expor dados sensíveis: informe os usuários, limite quem revisa o material e não habilite captura de teclas sem uma necessidade explícita.
Backup, atualização e diagnóstico
Faça backup do banco, configurações, extensões personalizadas e arquivos persistentes adicionais. Para produzir um dump lógico do laboratório:
umask 077
docker compose exec -T db pg_dump -U postgres -d guacamole_db -Fc \
> "guacamole-$(date +%F-%H%M%S).dump"
Guarde o dump protegido e teste restauração em outro ambiente. Recriar o contêiner não equivale a restaurar dados. Não execute docker compose down -v em produção: a opção remove volumes associados e pode apagar o banco.
Na atualização, leia as notas e scripts de migração aplicáveis, preserve a compatibilidade das extensões e programe indisponibilidade. Se a migração criar tabelas ou sequências, reaplique as permissões necessárias à conta SQL da aplicação. Reiniciar a aplicação pode interromper sessões. Nosso guia de Uptime Kuma com Docker e nginx ajuda a complementar o monitoramento do portal.
| Sintoma | Onde começar |
|---|---|
| Portal não abre | Logs da aplicação, porta local, inicialização do Tomcat e proxy. |
| Login local falha | Esquema inicializado, usuário SQL, senha e permissões. |
| Login funciona; não há conexões | Permissões e associação de identidades entre fontes. |
| Conexão remota falha | Logs do guacd, DNS, rota, firewall e serviço no destino. |
| LDAP falha | Base DN, atributo de usuário, bind e confiança TLS do Java. |
| SSO volta para erro ou loop | URI pública, identificação do provedor, mapeamento e cabeçalhos do proxy. |
| Sessão congela ou fica lenta | WebSocket, buffering, timeouts, latência e carga real. |
Checklist antes de disponibilizar para a equipe
- Senha inicial substituída e contas administrativas individuais.
- HTTPS e proxies confiáveis configurados; acesso ao guacd restrito.
- Destinos e permissões limitados, inclusive no firewall.
- Autenticação, MFA e caminhos de recuperação homologados.
- Credenciais, dumps e logs protegidos contra divulgação.
- Backups restaurados em teste e rotina de atualização definida.
- Integrações remotas testadas com contas de baixo privilégio.
O Apache Guacamole pode tornar o acesso remoto mais organizado, mas também concentra acesso a sistemas importantes. Comece pelo laboratório, compreenda cada camada e só então amplie o uso. A referência permanente é o manual oficial: instalar o portal é apenas o início da operação segura.