Pass, GPG e um backup que não depende de uma máquina só
Hoje terminei uma parte importante da organização das minhas senhas: exportei uma cópia do meu cofre do KeePassXC e coloquei os dados no pass, o gerenciador de senhas simples do mundo Unix.
O motivo principal não foi abandonar o KeePassXC imediatamente. Foi experimentar uma integração melhor com o terminal. Como eu já passo bastante tempo no shell, queria conseguir consultar senhas, copiar credenciais e gerar códigos OTP sem sair desse ambiente.
Por enquanto vou manter os dois fluxos: o KeePassXC continua sendo a referência principal e o pass fica como uma segunda cópia em estudo. Ainda estou avaliando a melhor forma de sincronizar os dois cofres sem criar conflitos ou perder alterações.
A ideia do pass é direta: cada entrada vira um arquivo de texto criptografado com GPG. O nome da entrada organiza o cofre e a senha fica na primeira linha.
A saída do KeePassXC
O ponto de partida foi o meu cofre do KeePassXC. O KeePassXC permite exportar as entradas para CSV, então fiz essa exportação antes de começar a migração.
O CSV é útil para transportar os dados, mas não é um formato adequado para deixar espalhado por aí: ele contém as senhas em texto puro. Por isso tratei o arquivo como uma etapa temporária e restrita, sem colocá-lo no Git, no servidor remoto ou na nuvem.
Depois da exportação, criei uma versão sanitizada do arquivo. Nessa etapa eu:
- conferi as colunas e a quantidade de registros;
- preservei usuário, senha, URL, notas e tokens TOTP;
- normalizei os grupos para nomes mais simples;
- removi acentos dos identificadores;
- troquei espaços nos nomes por pontos;
- verifiquei títulos duplicados e caminhos que poderiam virar nomes inválidos.
O arquivo intermediário foi:
~/caminho/para/senhas.sanitized.csv
Só depois dessa normalização o conteúdo foi importado para o pass. Ao final, o CSV continuou protegido com permissões restritas e não foi adicionado ao repositório de configurações.
Do CSV para o cofre
Eu tinha um arquivo com minhas senhas em CSV. Ele tinha usuários, senhas, URLs, anotações e alguns tokens de autenticação em dois fatores.
Antes de importar, organizei os nomes dos grupos. Em vez de caminhos longos como meu cofre/família/pessoa, passei a usar nomes mais curtos:
familia.pessoa
familia.outro
empresa.exemplo
empresa.outro
Também substituí espaços nos nomes dos itens por pontos. Assim, uma entrada ficou parecida com:
empresa.exemplo/ambiente.de.stage
familia.pessoa/banco.inter
O processo ficou assim:
Foram importadas 223 entradas. Depois conferi se todas podiam ser descriptografadas e se as senhas estavam na primeira linha, que é o formato esperado pelo pass.
OTP sem gambiarra
Também instalei a extensão pass-otp. Ela usa as URIs padrão otpauth:// para gerar códigos de autenticação de dois fatores.
Na primeira importação, eu tinha colocado a URI assim:
TOTP: otpauth://totp/...
Parecia organizado, mas a extensão não encontrava o token. O formato correto é deixar a URI em uma linha própria:
otpauth://totp/...
Depois de ajustar o CSV, zerei o cofre e importei tudo novamente. O resultado foi melhor: as entradas com OTP passaram a funcionar com o comando:
pass otp "empresa.exemplo/servico.otp"
Ou copiando o código diretamente para a área de transferência:
pass otp -c "empresa.exemplo/servico.otp"
Adicionando novas senhas
Para criar uma nova entrada, uso pass insert:
pass insert empresa.exemplo/nova-senha
O pass pede a senha no terminal e salva o resultado criptografado. Para guardar também usuário, URL e outras informações, uso o modo multiline:
pass insert --multiline empresa.exemplo/nova-senha
O formato fica assim:
minha-senha
Username: meu.usuario
URL: https://servico.example
Notes: alguma observação
A senha fica na primeira linha. Isso permite usar pass -c para copiar somente a senha:
pass -c empresa.exemplo/nova-senha
Adicionando novos OTPs
Para adicionar um token de autenticação, uso a extensão pass-otp:
pass otp insert empresa.exemplo/nova-senha
O comando pede uma URI no formato otpauth://. Normalmente ela vem do QR Code exibido pelo serviço ao ativar o segundo fator.
Se eu já tenho uma entrada de senha e quero adicionar o OTP nela, uso append:
pass otp append empresa.exemplo/nova-senha
Depois posso gerar o código com:
pass otp empresa.exemplo/nova-senha
Ou copiá-lo para a área de transferência:
pass otp -c empresa.exemplo/nova-senha
A URI do OTP é armazenada como uma linha própria dentro da entrada, começando diretamente com otpauth://.
O cofre também é um repositório Git
Meu ~/.password-store já era um repositório Git com um servidor remoto configurado. Isso significa que o pass consegue criar commits quando uma entrada é adicionada ou atualizada.
Depois da reorganização, os nomes antigos foram removidos e as entradas novas ficaram nos grupos empresa.* e familia.*. Fiz a consolidação em um commit e enviei para o servidor remoto.
O fluxo ficou assim:
O servidor remoto recebe somente os arquivos criptografados. Mesmo assim, o repositório não substitui o backup da chave GPG. Sem a chave privada, os arquivos .gpg continuam inacessíveis.
O problema da máquina única
Foi aí que veio a próxima pergunta: e se esta máquina quebrar?
A chave GPG não deve ficar somente em um computador. Também não é uma boa ideia colocar uma cópia sem proteção em um serviço de nuvem.
Em vez de copiar todo o ~/.gnupg, preparei um script genérico no meu repositório de configurações pessoais:
scripts/backup-gnupg.sh
O script exporta somente o que importa para recuperar a identidade:
- chave pública;
- chave privada;
- subchaves privadas;
ownertrust;- certificados de revogação;
- configurações GPG existentes.
Ele não copia sockets, cache, locks nem arquivos temporários do agente GPG.
O resultado é um arquivo 7-Zip criptografado com uma senha própria:
A senha do arquivo 7-Zip é diferente da senha da chave GPG. Isso é importante: são duas camadas diferentes de proteção.
O que ficou versionado
O repositório dotfiles é o lugar das minhas configurações pessoais e dos pequenos scripts que ajudam a recuperar o ambiente.
Para este setup, versionei o script genérico de backup seletivo do GPG e sua documentação. O backup criado não foi colocado no repositório. O Git guarda o script que sabe criar o backup, não o arquivo com as minhas chaves privadas.
Fechando o dia
O mais importante de hoje não foi somente trocar um gerenciador de senhas. Foi experimentar um fluxo mais próximo do terminal sem abandonar o KeePassXC antes de entender bem a sincronização.
Por enquanto, os dois cofres convivem. Foi uma migração controlada, não uma troca definitiva.
Também consegui separar melhor as coisas:
- o KeePassXC continua como referência principal;
- o
passguarda uma cópia criptografada e acessível pelo terminal; - o Git registra as mudanças;
- o servidor remoto guarda uma cópia dos arquivos criptografados;
- o GPG protege e recupera a identidade;
- a nuvem pessoal e a mídia física guardam um backup criptografado;
- o repositório
dotfilesdocumenta como refazer o setup.
Ainda quero testar a restauração completa em uma máquina virtual. Backup bom não é o que existe. É o que foi restaurado com sucesso pelo menos uma vez.