Guia definitivo passbolt: do Docker ao Podman, segurança e gestão remota no Rocky Linux
Voltar para blog

Guia definitivo passbolt: do Docker ao Podman, segurança e gestão remota no Rocky Linux

07/06/2026 · 5 min · Infraestrutura

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.

O que é "ultimate trust" no GPG#

O GPG possui 6 níveis de confiança para chaves:

NívelCódigoSignificado
Unknown2Confiança desconhecida ou não definida
Not Trusted3Chave explicitamente não confiável
Marginally Trusted4Confiança marginal (requer múltiplas confirmações)
Fully Trusted5Totalmente confiável, verifica assinaturas de terceiros
Ultimate Trust6Confianç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érioPassboltVaultwarden
CriptografiaOpenPGP Individual (Padrão Militar)AES-256 (Padrão de Mercado)
Peso (RAM)Moderado (~512MB+)Ultra Leve (<100MB)
ComplexidadeAlta (Gestão de chaves GPG)Baixa (Plug and Play)
ArquiteturaPHP/Go/GPGRust (Bitwarden API-compatible)
Público AlvoDevOps e Times com AuditoriaUso Geral e Pequenos Projetos
RecuperaçãoImpossível sem chave privadaVia 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)#

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:

CC BY-NC

Este post está licenciado sob CC BY-NC.

Comentários

Participe da discussão abaixo.

0 comentários