
Migrar e-mail não é só copiar a INBOX: é levar pastas, anexos e datas sem apagar a origem, conferir o resultado e buscar as mensagens que chegaram durante a mudança. O go-imapsync é uma ferramenta em Go para copiar caixas IMAP em uma direção, de host1 para host2, com distribuição em binário único e detecção de mensagens já copiadas por cabeçalhos.
O projeto se inspira no comportamento do imapsync de Gilles Lamiral, mas tem um escopo menor: não é um substituto com todas as opções do imapsync original. Este guia usa a versão 0.1.3 e apresenta uma sequência prática para testar, copiar e validar uma conta antes de migrar as demais.
Como a cópia funciona
O programa roda em uma máquina que consegue alcançar os dois servidores. Ele abre uma conexão IMAP com cada conta, lista as pastas, consulta os cabeçalhos existentes e transfere as mensagens ainda não reconhecidas no destino. Não precisa ser instalado dentro do servidor de e-mail e não usa SMTP para transportar as mensagens.

O fluxo é unidirecional. A origem não é apagada; o destino recebe pastas e mensagens. A ferramenta não cria usuários, não altera registros MX e não migra contatos, calendários, aliases ou regras de filtragem do servidor. Essas tarefas fazem parte do plano de migração, mas não da cópia IMAP.
Na inserção de uma mensagem, são enviados seu conteúdo, a data interna do IMAP e as flags suportadas pela implementação e pelo destino. Isso não significa manter duas caixas continuamente idênticas: mensagens reconhecidas como já existentes são puladas, inclusive sem uma etapa de atualização das flags que tenham mudado depois.
Antes de começar
- Autorização e contas: use somente caixas que você administra ou tem autorização para migrar. A conta de destino precisa existir.
- Quota: confira o espaço disponível no destino, incluindo Enviados, anexos e crescimento durante a migração.
- Autenticação: confirme que o provedor permite o método de login utilizado. A versão 0.1.3 não implementa XOAUTH2; não presuma compatibilidade com um serviço que exige OAuth.
- Conectividade: a máquina de migração precisa alcançar os endpoints IMAP, normalmente pela porta TCP 993 com TLS desde a conexão.
- Piloto: comece por uma conta pequena e representativa, com subpastas, mensagens lidas/não lidas e anexos.
- Preservação: mantenha uma cópia de segurança e acesso ao servidor antigo até a aceitação da migração.
Se o destino faz parte de uma instalação própria, a criação de contas e quotas pode ser administrada separadamente pelo go-postfixadmin. Copiar uma caixa não provisiona a infraestrutura que vai recebê-la.
Instalação no Linux
O exemplo abaixo é para Linux x86_64. A release 0.1.3 também oferece arquivos para macOS ARM64 e Windows AMD64. Não execute o pacote de outra arquitetura.
uname -m
mkdir -p "$HOME/Downloads/go-imapsync-0.1.3"
cd "$HOME/Downloads/go-imapsync-0.1.3"
curl -fL --retry 3 \
-o go-imapsync_0.1.3_linux_amd64.tar.gz \
https://github.com/jniltinho/go-imapsync/releases/download/v0.1.3/go-imapsync_0.1.3_linux_amd64.tar.gz
tar -tzf go-imapsync_0.1.3_linux_amd64.tar.gz
tar -xzf go-imapsync_0.1.3_linux_amd64.tar.gz
sudo install -m 0755 go-imapsync /usr/local/bin/go-imapsync
go-imapsync version
go-imapsync --help
O binário pronto não exige a instalação do Go para executar. Baixe apenas do repositório oficial e use o mecanismo de verificação disponibilizado na release, quando houver; calcular um hash local sem uma referência confiável não autentica o arquivo.
Para compilar a mesma versão, o go.mod declara Go 1.26.0. Com uma ferramenta Go compatível, Git e Make instalados:
git clone --branch v0.1.3 --depth 1 https://github.com/jniltinho/go-imapsync.git
cd go-imapsync
make build
make test
./dist/go-imapsync version
make build produz dist/go-imapsync; make test executa os testes com detector de condições de corrida. O Makefile da versão é a referência para os alvos de compilação.
Preparar credenciais sem colocá-las no histórico
Os próximos exemplos usam Bash. Informe as senhas interativamente: elas não ficam escritas no comando nem são exibidas durante a digitação. Execute tudo na mesma sessão do shell.
umask 077
mkdir -p "$HOME/go-imapsync-logs"
read -rsp 'Senha da origem: ' GOIMAPSYNC_PASSWORD1; printf '\n'
read -rsp 'Senha do destino: ' GOIMAPSYNC_PASSWORD2; printf '\n'
export GOIMAPSYNC_PASSWORD1 GOIMAPSYNC_PASSWORD2
# Substitua servidores e usuários pelos valores reais.
IMAP_ARGS=(
--host1 imap.origem.example --user1 alice@origem.example
--host2 imap.destino.example --user2 alice@destino.example
)
Variáveis de ambiente evitam a senha nos argumentos do programa, mas não são um cofre: processos e operadores com permissões suficientes podem acessá-las. Não use set -x, não imprima o ambiente e não envie logs sem revisão. O programa procura ocultar senhas nos próprios logs; isso não protege o histórico do shell, ferramentas externas ou uma captura de tela.
Quatro etapas: simular, criar pastas, planejar e copiar
Execute uma etapa por vez e confira o resultado antes da seguinte. A primeira não cria pastas nem insere mensagens:
go-imapsync "${IMAP_ARGS[@]}" --justfolders --dry
Verifique a árvore de pastas. Se os nomes ou a hierarquia estiverem incorretos, pare: não tente compensar criando dados no lugar errado. Depois crie apenas a estrutura no destino:
go-imapsync "${IMAP_ARGS[@]}" --justfolders
Agora simule a cópia das mensagens. O programa conecta aos servidores e consulta cabeçalhos, mas não executa CREATE ou APPEND no destino:
go-imapsync "${IMAP_ARGS[@]}" --dry \
--logfile "$HOME/go-imapsync-logs/plano.log"
Sem erros de autenticação, pastas ou conectividade, inicie a cópia real e capture imediatamente o código de saída:
go-imapsync "${IMAP_ARGS[@]}" \
--logfile "$HOME/go-imapsync-logs/copia.log"
rc=$?
printf 'Código de saída: %s\n' "$rc"
A CLI distingue sucesso (0), falha de execução (1) e erro de uso/configuração (2). Leia também o resumo de mensagens transferidas, puladas e falhas. Em uma simulação, a contagem de transferência representa o que seria feito, não mensagens realmente gravadas.
IMAPS e STARTTLS: não confunda as opções
O padrão é IMAPS com TLS desde o início, na porta 993. Quando um servidor exige STARTTLS na porta 143, desative o modo IMAPS e habilite explicitamente a negociação TLS para aquele lado. Exemplo com os dois servidores em STARTTLS:
# Acrescente estas opções antes das etapas de migração,
# somente se ambos os servidores exigirem STARTTLS:
IMAP_ARGS+=(--nossl1 --tls1 --port1 143 --nossl2 --tls2 --port2 143)
go-imapsync "${IMAP_ARGS[@]}" --justfolders --dry
Se só a origem usa STARTTLS, aplique apenas as opções terminadas em 1; mantenha o destino no padrão IMAPS. Use o nome de host correspondente ao certificado. Erro de certificado exige revisar hostname, validade e cadeia de confiança, não adicionar --insecuretls em produção.
A documentação de boas práticas detalha TLS, capacidade do destino, retomada e cuidados com credenciais.
Incremental não significa “impossível duplicar”
A comparação ocorre por pasta e usa, por padrão, os cabeçalhos Message-Id e Received, não o UID IMAP. Se a chave calculada já existe no destino, a mensagem é pulada. Essa decisão permite repetir a execução para buscar o que chegou depois, mas não compara o conteúdo completo byte a byte.
- Se nenhum dos cabeçalhos selecionados fornecer uma identidade, a mensagem pode voltar a ser transferida em outra execução.
- Se os cabeçalhos usados na identidade forem modificados entre servidores, a comparação pode não reconhecer a cópia anterior.
- Mensagens diferentes com a mesma identidade podem ser consideradas iguais; reduzir a comparação a menos campos exige avaliar esse risco.
- Mudar
--useheaderentre rodadas altera o critério de identificação. Faça testes em uma conta piloto, não por tentativa e erro em todas as caixas.
O detalhe está no cálculo da identidade e no fluxo de sincronização. Por isso, “pular mensagens reconhecidas” é uma descrição mais precisa do que garantir ausência absoluta de duplicados.
Como conferir e concluir a migração
Depois da cópia, execute outra simulação com os mesmos parâmetros:
go-imapsync "${IMAP_ARGS[@]}" --dry \
--logfile "$HOME/go-imapsync-logs/verificacao.log"
Em uma caixa sem novas entregas e com identidades estáveis, espera-se que não haja mensagens pendentes. Isso é uma conferência operacional, não uma validação criptográfica integral. Abra o webmail do destino e confira amostras em INBOX, Enviados e subpastas: corpo, anexos, datas e estado de leitura. Compare contagens por pasta investigando diferenças, em vez de assumir que totais iguais provam uma migração correta.
Planeje a mudança dos clientes e da entrega de e-mail separadamente. Uma estratégia operacional é fazer a cópia inicial, coordenar a virada e repetir a sincronização para capturar mensagens ainda recebidas no servidor antigo. Evite manter usuários alterando livremente as duas caixas: a ferramenta não reconcilia mudanças em duas direções.
Mantenha a origem disponível até validar o uso real. Se precisar voltar depois de receber mensagens no destino, essas mensagens novas também precisam de um plano de recuperação; apenas repontar os clientes pode ocultar parte do histórico. Ao terminar, remova as senhas da sessão:
unset GOIMAPSYNC_PASSWORD1 GOIMAPSYNC_PASSWORD2
unset IMAP_ARGS
Erros comuns e o que verificar
| Sintoma | Ação |
|---|---|
OVERQUOTA no destino |
Aumente a quota ou libere espaço com autorização. Depois repita a cópia e confira o resumo; não apague a origem para contornar o erro. |
| Conexão encerrada ou timeout | Confira rede, limites do servidor e logs. Resolva a causa antes de repetir; aumentar --timeout não corrige credenciais ou quota. |
| Falha no login | Confira usuário completo, senha e política do provedor. Acesso pelo webmail não prova que login IMAP por senha esteja habilitado. |
| Certificado inválido | Corrija o endpoint ou a confiança da CA. Não desative a verificação TLS como solução permanente. |
| Mensagens reaparecem a cada rodada | Investigue os cabeçalhos de identidade e possíveis transformações no destino antes de mudar --useheader. |
A ferramenta pode ser executada novamente depois de corrigir a falha. O que já foi copiado será reconhecido conforme o mesmo critério de cabeçalhos; isso não elimina as limitações descritas acima.
Executar com Docker
O repositório inclui um Dockerfile. Na árvore da versão escolhida, compile a imagem e confirme que ela executa. Para o teste de conexão, prepare novamente as variáveis de senha se já tiver usado unset:
make docker-build
docker run --rm go-imapsync:dev version
docker run --rm \
-e GOIMAPSYNC_PASSWORD1 \
-e GOIMAPSYNC_PASSWORD2 \
go-imapsync:dev \
--host1 imap.origem.example --user1 alice@origem.example \
--host2 imap.destino.example --user2 alice@destino.example \
--justfolders --dry
Não é necessário usar contêiner privilegiado. As senhas são fornecidas na execução, não no Dockerfile, mas usuários com acesso administrativo ao Docker podem inspecionar o ambiente do contêiner. Restrinja esse acesso e não persista credenciais em imagens.
Limites da versão e próximos passos
A versão 0.1.3 é um MVP focado em cópia IMAP. Filtros e mapeamento configurável de pastas, exclusões com --delete1/--delete2, XOAUTH2, tratamento específico de labels do Gmail e migração em massa por CSV aparecem como trabalho futuro no repositório, não como recursos entregues nem como promessa de prazo.
O código usa licença MIT. Nesta revisão, o binário da release teve versão e ajuda conferidas e a suíte da tag 0.1.3 passou com go test -race ./..., usando os testes locais do projeto. Isso não substitui um ensaio contra os servidores reais da sua migração.
O ganho é simplificar a execução da cópia; o cuidado continua sendo operacional: piloto, quota, TLS, logs e validação. Para arquivos e armazenamento em nuvem, o problema é diferente — veja o guia de rclone no Linux. Para e-mail, mantenha o procedimento focado nas caixas IMAP e só encerre o servidor antigo depois de conferir os dados.