No ecossistema de infraestrutura atual, a segurança de credenciais não é negociável. Recentemente, mergulhei no desafio de implementar e migrar gerenciadores de senhas robustos (Passbolt e Vaultwarden) em ambientes Rocky Linux, transitando do modelo Docker tradicional para a soberania do Podman.
Se você está buscando uma implementação resiliente, protegida e fácil de gerenciar remotamente, este guia reúne as lições aprendidas no "pé no barro" de ambos os mundos.
⚠️ Avisos de segurança antes de começar#
Sobre a chave privada GPG#
A chave privada GPG é o único artefato que descriptografa todas as senhas armazenadas no Passbolt.
- Se a chave privada for perdida, os dados são IRRECUPERÁVEIS. Não existe reset. Não existe suporte que recupere.
- Armazene a chave em local seguro fora do servidor (pen drive criptografado, cofre de senhas offline).
- Faça backup criptografado em múltiplos locais físicos independentes.
- Nunca envie a chave privada por e-mail ou chat, mesmo interno.
O que é "ultimate trust" no GPG#
O GPG possui 6 níveis de confiança para chaves:
| Nível | Código | Significado |
|---|---|---|
| Unknown | 2 | Confiança desconhecida ou não definida |
| Not Trusted | 3 | Chave explicitamente não confiável |
| Marginally Trusted | 4 | Confiança marginal (requer múltiplas confirmações) |
| Fully Trusted | 5 | Totalmente confiável, verifica assinaturas de terceiros |
| Ultimate Trust | 6 | Confiança absoluta - necessário para o Passbolt funcionar |
| Undefined | - | Sem validação (padrão para chaves importadas) |
O Passbolt exige nível 6 (Ultimate Trust) no chaveiro do usuário www-data. Se o nível estiver incorreto, o container não sobe e o healthcheck retorna FAIL. O valor 6 no formato FINGERPRINT:6: é o que o comando --import-ownertrust espera.
# Verificar trust level atual da chave
docker exec passbolt su -s /bin/bash -c \
"gpg --homedir /var/lib/passbolt/.gnupg --list-ownertrust" www-data
# Saída esperada com Ultimate Trust:
# 3AA5C34371567BD2:6:
# ^ este "6" é o Ultimate Trust
1. O embate inicial: passbolt vs. vaultwarden#
Antes de "sujar as mãos" com comandos, é preciso escolher a ferramenta certa para o seu cenário:
| Critério | Passbolt | Vaultwarden |
|---|---|---|
| Criptografia | OpenPGP Individual (Padrão Militar) | AES-256 (Padrão de Mercado) |
| Peso (RAM) | Moderado (~512MB+) | Ultra Leve (<100MB) |
| Complexidade | Alta (Gestão de chaves GPG) | Baixa (Plug and Play) |
| Arquitetura | PHP/Go/GPG | Rust (Bitwarden API-compatible) |
| Público Alvo | DevOps e Times com Auditoria | Uso Geral e Pequenos Projetos |
| Recuperação | Impossível sem chave privada | Via backup de banco + chave mestra |
Veredito: O Passbolt é a escolha lógica para quem exige auditoria granular e criptografia fim-a-fim via PGP. O Vaultwarden brilha pela eficiência extrema de recursos e simplicidade operacional.
2. Backup antes de qualquer operação#
# ---- Docker ----
# Backup do banco de dados MariaDB
docker exec passbolt-db mysqldump \
-u root -p'MARIADB_ROOT_PASSWORD' passbolt \
> /root/passbolt-db-backup-$(date +%Y%m%d-%H%M).sql
# Backup do chaveiro GPG (CRÍTICO - sem isso não há recuperação)
docker cp passbolt:/var/lib/passbolt/.gnupg /root/passbolt-gnupg-backup-$(date +%Y%m%d-%H%M)
# Backup do volume de dados completo
docker run --rm \
-v passbolt_data:/data \
-v /root:/backup \
alpine tar czf /backup/passbolt-volume-$(date +%Y%m%d-%H%M).tar.gz /data
# ---- Podman ----
# Backup do banco de dados MariaDB
podman exec passbolt-db mysqldump \
-u root -p'MARIADB_ROOT_PASSWORD' passbolt \
> /root/passbolt-db-backup-$(date +%Y%m%d-%H%M).sql
# Backup do chaveiro GPG
podman cp passbolt:/var/lib/passbolt/.gnupg /root/passbolt-gnupg-backup-$(date +%Y%m%d-%H%M)
# Verificar integridade dos backups
ls -lh /root/passbolt-*
# Tamanho esperado do .sql: mínimo alguns KB (se banco vazio), MB se com dados
# Tamanho do .gnupg: alguns KB (contém apenas a chave pública + metadados do ownertrust)
3. Implementação no Docker: o desafio do GPG#
Ao subir o Passbolt via Docker, o erro mais comum é o Healthcheck FAIL relacionado ao OpenPGP.
A investigação (o erro 500)#
O Passbolt depende que o motor GPG do Linux tenha a chave importada no chaveiro do usuário www-data com Ultimate Trust. Se as variáveis de ambiente não estiverem perfeitamente alinhadas, o container aborta o boot.
O "Pulo do Gato" Corretivo:
# 1. Limpe configurações residuais que ignoram novas variáveis
rm /etc/passbolt/passbolt.php
su -s /bin/bash -c "bin/cake cache clear_all" www-data
# 2. Garanta o 'Ultimate Trust' (Substitua SEU_FINGERPRINT)
echo "SEU_FINGERPRINT:6:" | su -s /bin/bash -c \
"gpg --homedir /var/lib/passbolt/.gnupg --import-ownertrust" www-data
# 3. Inicialize o chaveiro no banco
su -s /bin/bash -c "bin/cake passbolt keyring_init" www-data
Verificação do GPG após configuração#
# Verificar se a chave foi importada corretamente
docker exec passbolt su -s /bin/bash -c \
"gpg --homedir /var/lib/passbolt/.gnupg --list-keys" www-data
# Verificar se Ultimate Trust está configurado (deve mostrar :6:)
docker exec passbolt su -s /bin/bash -c \
"gpg --homedir /var/lib/passbolt/.gnupg --list-ownertrust" www-data
# Verificar permissões do chaveiro (deve ser 700 para o diretório .gnupg)
docker exec passbolt ls -la /var/lib/passbolt/.gnupg/
# Verificar ownership (deve ser www-data:www-data)
docker exec passbolt stat /var/lib/passbolt/.gnupg/
# Verificar se www-data consegue listar o chaveiro (teste real de acesso)
docker exec passbolt su -s /bin/bash -c \
"ls -la /var/lib/passbolt/.gnupg/" www-data
Verificação do MariaDB#
# Verificar se o container de banco está rodando
docker ps | grep passbolt-db
# Verificar conexão e listar databases
docker exec passbolt-db mysql \
-u root -p'MARIADB_ROOT_PASSWORD' \
-e "SHOW DATABASES;"
# Confirmar que o schema do Passbolt existe
docker exec passbolt-db mysql \
-u root -p'MARIADB_ROOT_PASSWORD' \
-e "SHOW TABLES FROM passbolt;" | head -20
4. A evolução: orquestrando passbolt com Podman no Rocky Linux#
Saindo do Docker para o Podman, ganhamos o modelo daemonless e a execução rootless, elevando a segurança da VPS.
4.1 resolvendo conflitos de portas privilegiadas#
No modo rootless, o Podman não pode bindar portas abaixo de 1024. O erro Error: rootlessport cannot expose privileged port 80 é clássico. A Solução: Use portas altas (ex: 9001) e mapeie corretamente no seu podman-compose.yaml.
services:
passbolt:
image: docker.io/passbolt/passbolt:latest-ce
ports:
- "9001:80"
environment:
- APP_FULL_BASE_URL=https://meudominio.com.br:9001
restart: always
4.2 limpeza de trava (locks) e persistência#
Se o container cair de forma abrupta, o Podman pode travar os arquivos de metadados (acquiring lock: file exists). O comando para destravar o ambiente é:
podman system renumber
Para garantir que o Passbolt volte após um reboot da VPS:
sudo systemctl enable podman.socket
sudo systemctl enable podman-restart.service
5. Configuração de firewall no Rocky Linux#
O Rocky Linux usa o firewalld por padrão. Sem a abertura da porta, o Passbolt é inacessível de fora do servidor.
# Verificar estado atual do firewall e regras ativas
sudo firewall-cmd --list-all
# Abrir a porta 9001 de forma permanente
sudo firewall-cmd --permanent --add-port=9001/tcp
sudo firewall-cmd --reload
# Confirmar que a porta foi adicionada
sudo firewall-cmd --list-ports
# Saída esperada: 9001/tcp
# Se usar iptables diretamente (alternativa)
sudo iptables -A INPUT -p tcp --dport 9001 -j ACCEPT
sudo iptables-save > /etc/sysconfig/iptables
6. Verificação SSL/TLS e conectividade#
Verificação do certificado SSL#
# Inspecionar certificado: validade, emissor e SANs
echo | openssl s_client -connect meudominio.com.br:9001 2>/dev/null \
| openssl x509 -noout -dates -issuer -subject
# Verificar negociação TLS ativa
curl -vI https://meudominio.com.br:9001/ 2>&1 | grep -iE "ssl|tls|cipher"
# Testar HTTP retornado (deve ser 200 ou 301/302 para login)
curl -sk https://meudominio.com.br:9001/ -o /dev/null -w "HTTP Status: %{http_code}\n"
Verificação de conectividade completa#
# Verificar disponibilidade da porta (TCP handshake)
nc -zv meudominio.com.br 9001
# Verificar resolução DNS
dig meudominio.com.br +short
# Testar resposta HTTP do serviço (primeiras linhas do HTML)
curl -sk https://meudominio.com.br:9001/ | head -10
7. Verificação pós-configuração (checklist completo)#
# --- Container Status ---
# Docker:
docker ps | grep passbolt
docker inspect --format='{{.State.Health.Status}}' passbolt
docker logs passbolt --tail 50
# Podman:
podman ps | grep passbolt
podman inspect --format='{{.State.Health.Status}}' passbolt
podman logs passbolt --tail 50
# --- Conectividade ---
curl -I https://meudominio.com.br:9001/
# Saída esperada do healthcheck: "healthy"
# Saída esperada do curl: HTTP/1.1 200 OK ou 302 Found (redirect para login)
8. Gestão de elite: conectando o Podman desktop à VPS#
Um analista moderno não quer depender apenas do terminal. Gerenciar os logs e status visualmente via Podman Desktop (no seu Linux local) é um divisor de águas.
O pulo do gato: root vs user no SSH#
Se você subiu o serviço como root na VPS, o seu usuário comum via SSH não verá os containers devido ao isolamento de UIDs do Podman.
Comando para estabelecer a conexão correta:
# Limpando chaves antigas se houver erro de mismatch
ssh-keygen -R meudominio.com.br
# Adicionando a conexão de sistema ao host remoto
podman system connection add ovh-vps --identity ~/.ssh/id_rsa ssh://[email protected]
podman system connection default ovh-vps
9. Atualização dos containers#
# ---- Docker ----
# 1. Fazer backup ANTES (veja Seção 2)
# 2. Pull da nova imagem
docker pull passbolt/passbolt:latest-ce
docker pull mariadb:10.11
# 3. Com docker-compose (recomendado - preserva volumes automaticamente)
docker-compose pull
docker-compose up -d
# O compose recria os containers com a nova imagem mantendo os volumes
# ---- Podman ----
podman pull docker.io/passbolt/passbolt:latest-ce
podman-compose pull
podman-compose up -d
# ---- Verificação pós-update ----
docker inspect --format='{{.State.Health.Status}}' passbolt
# Aguardar 30-60s até o healthcheck passar para "healthy"
10. Monitoramento automatizado#
# Criar o script de health check
cat > /usr/local/bin/check-passbolt.sh << 'EOF'
#!/bin/bash
# Health monitor para Passbolt (Docker ou Podman)
# Agendado via cron: */5 * * * * /usr/local/bin/check-passbolt.sh
RUNTIME="${1:-docker}" # docker ou podman
CONTAINER="passbolt"
ADMIN_EMAIL="[email protected]"
HEALTH=$($RUNTIME inspect --format='{{.State.Health.Status}}' "$CONTAINER" 2>/dev/null)
RUNNING=$($RUNTIME ps --filter "name=$CONTAINER" --format "{{.Status}}" 2>/dev/null)
if [ "$HEALTH" != "healthy" ] || [ -z "$RUNNING" ]; then
MSG="ALERTA: Passbolt status - Health: ${HEALTH:-N/A} | Running: ${RUNNING:-not found}"
echo "$MSG"
echo "$MSG" | mail -s "🚨 Passbolt Alert $(date +%Y-%m-%d\ %H:%M)" "$ADMIN_EMAIL"
fi
EOF
chmod +x /usr/local/bin/check-passbolt.sh
# Adicionar ao cron (verificação a cada 5 minutos)
(crontab -l 2>/dev/null; echo "*/5 * * * * /usr/local/bin/check-passbolt.sh docker") | crontab -
# Verificar se o cron foi adicionado
crontab -l | grep passbolt
11. Checklist de produção (lições de SRE)#
- SSL/HTTPS Total: APIs de criptografia modernas (
Web Crypto API) exigem contexto seguro. Sem HTTPS, o plugin do Passbolt nem inicializa. - Backup das Chaves: No Passbolt, se o usuário perder o arquivo de chave privada (
.asc), os dados são irrecuperáveis. Isso não é um bug, é uma feature de segurança. - MariaDB 10.11+: Use sempre o prefixo
MARIADB_para variáveis de ambiente (ex:MARIADB_ROOT_PASSWORD). - Firewall: Abra apenas a porta necessária (9001) no firewalld. Nunca exponha a porta 3306 do MariaDB publicamente.
- Monitoramento: Configure o health check automatizado (Seção 10) no primeiro dia de produção - não quando o serviço cair.
- Backups: Agende backups diários do banco MariaDB e do chaveiro GPG. Teste a restauração periodicamente.
Considerações práticas#
Implementar o Passbolt exige entender os detalhes sutis de permissões de chaveiro GPG e, na transição para o Podman, dominar os nomes de namespaces e portas rootless. Ter esse setup operando com gestão visual pelo desktop transforma um gerenciador de senhas em uma ferramenta de infraestrutura de classe mundial. E com os procedimentos de backup, verificação e monitoramento documentados neste guia, você tem um runbook completo - não apenas para o dia da instalação, mas para meses de operação segura em produção.
Este artigo foi útil?
Deixe uma reação rápida para apoiar o conteúdo:
Este post está licenciado sob CC BY-NC.



Comentários
Participe da discussão abaixo.
0 comentários