Migrar un servidor de correo es más delicado que migrar una web: mientras los DNS se propagan, parte del correo sigue llegando al servidor antiguo y no puede perderse ningún mensaje. En este tutorial moverás una instalación de Postfix y Dovecot con buzones Maildir a un servidor nuevo con Ubuntu 24.04. Copiarás la configuración, los certificados, las claves DKIM y los buzones, harás el cambio de DNS y dejarás el servidor antiguo reenviando al nuevo el correo que aún le llegue.

Requisitos previos

  • El servidor de correo actual (origen) con Postfix y Dovecot funcionando y buzones en formato Maildir.
  • Un servidor nuevo (destino) con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con una IP pública fija.
  • Un usuario no root con privilegios sudo en ambos servidores y acceso SSH desde el destino al origen.
  • Acceso al panel DNS del dominio para cambiar los registros A, MX y SPF.
  • Posibilidad de configurar el registro PTR (DNS inverso) de la nueva IP y de enviar tráfico saliente por el puerto 25. Muchos proveedores bloquean el puerto 25 en cuentas nuevas; confírmalo antes de empezar.

En esta guía se usan estos marcadores: mail.your_domain es el nombre del servidor de correo, your_domain el dominio, old_server_ip y new_server_ip las IP de origen y destino, y your_user tu usuario con sudo. Sustitúyelos por tus valores.

Paso 1: Inventariar el servidor de origen

Antes de copiar nada, anota cómo está montado el servidor actual. En el origen, guarda la configuración efectiva de Postfix y Dovecot (solo los valores distintos de los predeterminados):

sudo postconf -n > ~/postfix-n.txt
sudo doveconf -n > ~/dovecot-n.txt

Localiza los parámetros que definen qué dominios acepta el servidor y dónde guarda los buzones:

sudo postconf myhostname mydestination virtual_mailbox_domains virtual_mailbox_base
sudo doveconf mail_location
myhostname = mail.your_domain
mydestination = localhost
virtual_mailbox_domains = your_domain
virtual_mailbox_base = /var/vmail
mail_location = maildir:/var/vmail/%d/%n

Anota también de dónde salen los usuarios (passdb y userdb en ~/dovecot-n.txt): un archivo de contraseñas, usuarios del sistema o una base de datos MySQL. Comprueba el tamaño de los buzones para calcular el tiempo de copia, y si existe el usuario vmail, anota su UID y GID:

sudo du -sh /var/vmail
id vmail

Por último, revisa si el servidor firma con OpenDKIM:

systemctl is-active opendkim

Si responde active, tendrás que migrar también /etc/opendkim.conf y /etc/opendkim/.

Paso 2: Bajar el TTL de los registros DNS

Con un TTL alto, los remitentes seguirán usando la IP antigua durante horas después del cambio. Al menos 24 horas antes de la migración, baja a 300 segundos el TTL de los registros A de mail.your_domain y MX de your_domain en tu panel DNS.

Consulta los registros actuales para tenerlos anotados:

dig +noall +answer MX your_domain
dig +noall +answer A mail.your_domain
dig +short TXT your_domain
dig +short TXT default._domainkey.your_domain
your_domain.		300	IN	MX	10 mail.your_domain.
mail.your_domain.	300	IN	A	old_server_ip
"v=spf1 mx a ip4:old_server_ip -all"
"v=DKIM1; k=rsa; p=MIIBIjANBgkq..."

Cambia default por el selector DKIM que uses. Cuando el TTL mostrado sea 300, puedes continuar.

Paso 3: Preparar el servidor de destino

En el servidor nuevo, establece el nombre de host para que coincida con el del servidor de correo:

sudo hostnamectl set-hostname mail.your_domain

Instala Postfix, Dovecot y las herramientas que usarás en la migración. Añade postfix-mysql y dovecot-mysql solo si los usuarios están en MySQL:

sudo apt update
sudo apt install postfix dovecot-core dovecot-imapd dovecot-lmtpd rsync certbot swaks

Si el origen firma con OpenDKIM, instálalo también:

sudo apt install opendkim opendkim-tools

Cuando el instalador de Postfix pregunte por el tipo de configuración, elige Sin configuración, ya que vas a copiar la del origen.

Si el origen usa el usuario vmail, créalo con el mismo UID y GID que anotaste en el paso 1 (5000 en este ejemplo):

sudo groupadd -g 5000 vmail
sudo useradd -u 5000 -g vmail -d /var/vmail -s /usr/sbin/nologin vmail

Abre en el cortafuegos los puertos de SMTP, envío autenticado e IMAP:

sudo ufw allow OpenSSH
sudo ufw allow 25,465,587,993/tcp
sudo ufw enable

Añade 110,995 si ofreces POP3 y 143 si aún aceptas IMAP con STARTTLS.

Paso 4: Copiar la configuración, los certificados y las claves DKIM

Para leer archivos de root en el origen a través de SSH, rsync tiene que ejecutarse con sudo en ambos lados. En el origen, permite temporalmente a tu usuario lanzar rsync con sudo sin contraseña:

echo 'your_user ALL=(root) NOPASSWD: /usr/bin/rsync' | sudo tee /etc/sudoers.d/rsync-migracion
sudo chmod 440 /etc/sudoers.d/rsync-migracion

En el destino, crea una clave SSH con tu usuario y cópiala al origen:

ssh-keygen -t ed25519
ssh-copy-id your_user@old_server_ip

Como rsync se ejecutará con sudo en el destino, SSH buscaría las claves de root. Guarda en una variable el comando SSH que usa tu clave para reutilizarlo en todos los comandos:

SSH_CMD="ssh -i /home/your_user/.ssh/id_ed25519"

Desde el destino, guarda una copia de la configuración predeterminada y trae la del origen. La opción -R conserva las rutas completas y --rsync-path ejecuta rsync como root en el origen:

sudo cp -a /etc/postfix /etc/postfix.orig
sudo cp -a /etc/dovecot /etc/dovecot.orig
sudo rsync -aR --rsync-path="sudo rsync" -e "$SSH_CMD" \
  your_user@old_server_ip:/etc/postfix \
  your_user@old_server_ip:/etc/dovecot \
  your_user@old_server_ip:/etc/aliases \
  your_user@old_server_ip:/etc/mailname \
  your_user@old_server_ip:/etc/letsencrypt \
  /

Si el origen usa OpenDKIM, copia también su configuración y sus claves:

sudo rsync -aR --rsync-path="sudo rsync" -e "$SSH_CMD" \
  your_user@old_server_ip:/etc/opendkim.conf \
  your_user@old_server_ip:/etc/opendkim \
  /

Copiar /etc/letsencrypt completo mantiene los certificados válidos y la configuración de renovación, así que no hace falta emitir certificados nuevos antes de cambiar los DNS. Si los certificados vienen de otra ruta, cópiala del mismo modo.

Busca referencias a la IP antigua en la configuración copiada y cámbialas por la nueva:

sudo grep -rn "old_server_ip" /etc/postfix /etc/dovecot /etc/opendkim* 2>/dev/null

Si los usuarios virtuales están en MySQL, exporta la base de datos en el origen e impórtala en el destino, creando el mismo usuario de MySQL que aparece en los archivos /etc/postfix/mysql-*.cf y /etc/dovecot/dovecot-sql.conf.ext.

Reconstruye los mapas de Postfix y la base de alias, y comprueba que la configuración no tiene errores:

sudo postmap /etc/postfix/virtual 2>/dev/null
sudo newaliases
sudo postfix check
sudo doveconf -n > /dev/null && echo "Dovecot OK"

Ejecuta postmap sobre cada archivo hash: o lmdb: que aparezca en postconf -n. Si postfix check y doveconf no muestran errores, reinicia los servicios:

sudo systemctl restart postfix dovecot

Si usas OpenDKIM, reinícialo también con sudo systemctl restart opendkim.

Comprueba que escuchan en los puertos esperados:

sudo ss -tlnp | grep -E ':(25|465|587|993)\s'

Paso 5: Hacer la primera copia de los buzones

La primera copia es la más larga y se puede hacer con el servidor antiguo funcionando, porque en Maildir cada mensaje es un archivo independiente. Desde el destino:

sudo rsync -aHAX --numeric-ids --info=progress2 \
  --rsync-path="sudo rsync" -e "$SSH_CMD" \
  your_user@old_server_ip:/var/vmail/ /var/vmail/

La barra final de /var/vmail/ es importante: copia el contenido del directorio y no el directorio dentro de sí mismo. --numeric-ids conserva los UID y GID originales, por eso creaste vmail con los mismos números.

Si los buzones están en los directorios personales de usuarios del sistema (~/Maildir), crea esos usuarios en el destino con el mismo UID y copia /home del mismo modo.

Comprueba que Dovecot ve los mensajes de un buzón de prueba:

sudo doveadm mailbox status -u user@your_domain messages INBOX
messages=1824

Ejecuta el mismo comando en el origen; el número debe coincidir o ser muy parecido.

Paso 6: Probar el servidor nuevo antes del cambio

Todavía no cambies los DNS. Prueba el servidor nuevo conectando directamente a su IP. Primero, IMAP con TLS:

openssl s_client -connect new_server_ip:993 -servername mail.your_domain -quiet

Deberías ver el saludo * OK [CAPABILITY ...] Dovecot ready.. Escribe a LOGIN user@your_domain your_password para comprobar la autenticación y a LOGOUT para salir.

Después, envía un correo de prueba a través del puerto de envío con autenticación. Desde tu equipo o desde el propio servidor:

swaks --to user@your_domain --from user@your_domain \
  --server new_server_ip --port 587 --tls \
  --auth LOGIN --auth-user user@your_domain

swaks pedirá la contraseña. La última línea debe ser 250 2.0.0 Ok: queued as .... Revisa en el log que se entregó al buzón:

sudo grep "status=" /var/log/mail.log | tail -n 5

Si el mensaje aparece con status=sent, la entrega local funciona. Configura también un cliente de correo apuntando a new_server_ip y comprueba que ves las carpetas y los mensajes.

Paso 7: Preparar SPF y DNS inverso

El SPF debe autorizar la IP nueva antes de que el servidor empiece a enviar. Edita el registro TXT de your_domain para incluir las dos IP durante la transición:

v=spf1 mx a ip4:old_server_ip ip4:new_server_ip -all

Configura el registro PTR de new_server_ip para que resuelva a mail.your_domain y verifícalo:

dig +short -x new_server_ip
mail.your_domain.

Sin un PTR correcto, Gmail y Outlook rechazarán o marcarán como spam gran parte del correo saliente.

Paso 8: Hacer el cambio

Elige un momento de poco tráfico. En el origen, detén Dovecot para que los usuarios no lean, muevan ni borren mensajes durante la copia final. En Maildir, cambiar el estado de un mensaje (leído, respondido) renombra su archivo, así que con Dovecot parado los nombres de archivo dejan de cambiar. Postfix sigue en marcha para no rechazar correo:

sudo systemctl stop dovecot

Desde el destino, haz la copia final de los buzones. Si abriste una sesión nueva, vuelve a definir SSH_CMD como en el paso 4. Solo transfiere los cambios desde la primera copia, así que tarda poco. --delete elimina en el destino los mensajes que los usuarios borraron o renombraron en el origen:

sudo rsync -aHAX --numeric-ids --delete --info=progress2 \
  --rsync-path="sudo rsync" -e "$SSH_CMD" \
  your_user@old_server_ip:/var/vmail/ /var/vmail/

Inmediatamente después, configura Postfix en el origen para que reenvíe al servidor nuevo el correo de tu dominio en lugar de entregarlo localmente. Crea el mapa de transporte:

sudo nano /etc/postfix/transport
your_domain    smtp:[new_server_ip]:25

Los corchetes indican a Postfix que use la IP directamente sin consultar el MX. Activa el mapa, recarga Postfix y vacía la cola para que los mensajes pendientes salgan hacia el servidor nuevo:

sudo postmap /etc/postfix/transport
sudo postconf -e "transport_maps = hash:/etc/postfix/transport"
sudo postfix reload
sudo postqueue -f

Comprueba que la cola queda vacía:

sudo postqueue -p
Mail queue is empty

Entre la copia final y la recarga de Postfix pueden haber llegado unos pocos mensajes al origen. Recógelos con una última pasada sin --delete, para no borrar el correo que el servidor nuevo ya está recibiendo, y excluyendo los índices de Dovecot, que en el destino ya están al día:

sudo rsync -aHAX --numeric-ids --exclude='dovecot*' \
  --rsync-path="sudo rsync" -e "$SSH_CMD" \
  your_user@old_server_ip:/var/vmail/ /var/vmail/

Reconstruye los índices de Dovecot en el destino para que reflejen todos los archivos copiados:

sudo doveadm force-resync -A '*'

Por último, en tu panel DNS cambia el registro A de mail.your_domain a new_server_ip. Si el MX apunta a mail.your_domain, no hace falta tocarlo.

Paso 9: Verificar la migración

Comprueba que los DNS públicos ya devuelven la IP nueva:

dig +short A mail.your_domain @1.1.1.1

Envía un correo desde una cuenta externa (Gmail, por ejemplo) a un buzón del dominio y sigue su llegada en el destino:

sudo tail -f /var/log/mail.log

Responde desde el servidor nuevo a esa cuenta externa y revisa las cabeceras del mensaje recibido. Deben aparecer spf=pass, dkim=pass y dmarc=pass. Si DKIM falla, revisa que el selector y la clave copiados coinciden con el registro TXT publicado.

Durante las siguientes horas, vigila el log del origen. Todo el correo que aún llegue debe salir hacia el servidor nuevo:

sudo grep "relay=\[new_server_ip\]" /var/log/mail.log | tail

Cuando pasen 24 a 48 horas sin tráfico en el origen, retira la IP antigua del registro SPF y elimina en el origen el archivo /etc/sudoers.d/rsync-migracion.

Solución de problemas

  • Relay access denied en el servidor nuevo: el dominio no está en mydestination ni en virtual_mailbox_domains, o falta ejecutar postmap sobre algún mapa copiado. Revisa sudo postconf -n y sudo postfix check.
  • Los usuarios ven carpetas vacías: la ruta de mail_location no coincide con donde copiaste los buzones o los permisos no son de vmail. Comprueba sudo doveconf mail_location y ls -ln /var/vmail.
  • El correo saliente queda en cola con Connection timed out en el puerto 25: el proveedor bloquea el tráfico saliente por el puerto 25. Compruébalo con nc -vz gmail-smtp-in.l.google.com 25 y solicita el desbloqueo.
  • Certificado caducado tras unas semanas: la renovación de Certbot usa el mismo método que en el origen. Ejecuta sudo certbot renew --dry-run y ajusta el autenticador si el servidor nuevo no tiene servidor web.

Vuelta atrás

Si algo falla después del cambio, vuelve a apuntar el registro A de mail.your_domain a old_server_ip, elimina transport_maps en el origen con sudo postconf -X transport_maps, recarga Postfix y arranca Dovecot. Copia de vuelta con rsync (sin --delete) los mensajes que hayan llegado al servidor nuevo mientras tanto.

Conclusión

Has migrado Postfix y Dovecot a un servidor nuevo sin perder correo: la configuración, los certificados y DKIM se copiaron tal cual, los buzones se sincronizaron en dos pasadas y el servidor antiguo reenvía el correo rezagado. Mantén el origen encendido una o dos semanas antes de darlo de baja. Como siguientes pasos, publica una política DMARC más estricta cuando confirmes que todo el correo pasa SPF y DKIM, y programa copias de seguridad de /var/vmail en el servidor nuevo.