Postfix y Dovecot juntos forman un servidor de correo completo: Postfix intercambia correo con otros servidores por SMTP, y Dovecot lo almacena, lo sirve a los clientes de correo por IMAP y comprueba las contraseñas de ambos. En este tutorial montarás ese conjunto en Ubuntu 24.04 con buzones virtuales, es decir, cuentas de correo como admin@your_domain que no son usuarios de Linux. Postfix entrega el correo entrante a Dovecot por LMTP, Dovecot autentica a los clientes para IMAP y para el envío por el puerto 587, y añadir un usuario o un dominio completo se reduce a editar dos archivos de texto.
Requisitos previos
Para seguir este tutorial necesitas:
- Un servidor recién instalado con Ubuntu 24.04 LTS y una IPv4 pública, por ejemplo un VPS de CubePath, y un usuario no root con privilegios
sudo. - Un dominio (
your_domain) con estos registros DNS: un registro A paramail.your_domainque apunte ayour_server_ip, un registro MX deyour_domainque apunte amail.your_domain, un registro SPF (v=spf1 mx ~all) y un registro DMARC en_dmarc.your_domain. - El DNS inverso (PTR) de
your_server_ipconfigurado comomail.your_domain, a través de tu proveedor de hosting. - El puerto TCP 25 de salida abierto. En CubePath, como en la mayoría de proveedores cloud, está cerrado por defecto; solicítalo con un ticket de soporte que describa el uso que harás del correo.
La guía "Cómo montar un servidor de correo Postfix en Ubuntu 24.04" explica en detalle los registros DNS, la comprobación del puerto 25 y la firma DKIM. Este tutorial se centra en las partes en las que Postfix y Dovecot se conectan.
Así encajan las piezas:
| Tráfico | Puerto | Quién lo gestiona |
|---|---|---|
| Correo de otros servidores | 25 | smtpd de Postfix, y después LMTP hacia Dovecot |
| Correo que envían tus usuarios | 587 (STARTTLS) | smtpd de Postfix, con la contraseña comprobada por el SASL de Dovecot |
| Clientes que leen el correo | 993 (IMAPS) | IMAP de Dovecot |
| Entrega de Postfix a Dovecot | Socket Unix private/dovecot-lmtp | LMTP de Dovecot |
| Autenticación de Postfix contra Dovecot | Socket Unix private/auth | Servicio auth de Dovecot |
Paso 1: Configurar el nombre del servidor y obtener un certificado
Asigna al servidor el nombre que aparece en tu registro MX:
sudo hostnamectl set-hostname mail.your_domain
Añade el nombre a /etc/hosts para que se resuelva localmente:
sudo nano /etc/hosts
127.0.1.1 mail.your_domain mail
Activa el cortafuegos con SSH y los puertos que necesita este servidor. Certbot usa el puerto 80 para demostrar que controlas el dominio:
sudo ufw allow OpenSSH
sudo ufw allow 25/tcp
sudo ufw allow 80/tcp
sudo ufw allow 587/tcp
sudo ufw allow 993/tcp
sudo ufw enable
Instala Certbot y obtén un certificado para mail.your_domain en modo standalone:
sudo apt update
sudo apt install certbot
sudo certbot certonly --standalone -d mail.your_domain
Postfix y Dovecot solo leen el certificado al arrancar, así que hay que recargarlos tras cada renovación. Certbot ejecuta todos los ejecutables de su directorio de hooks deploy después de una renovación correcta:
sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-mail.sh
#!/bin/sh
systemctl reload postfix dovecot
sudo chmod 755 /etc/letsencrypt/renewal-hooks/deploy/reload-mail.sh
Comprueba que la renovación funciona:
sudo certbot renew --dry-run
Paso 2: Instalar Postfix y Dovecot
Instala Postfix, el núcleo de Dovecot, el servidor IMAP y el servidor LMTP:
sudo apt install postfix dovecot-core dovecot-imapd dovecot-lmtpd
Cuando el instalador de Postfix pregunte, elige Internet Site y escribe mail.your_domain como System mail name. En una configuración de buzones virtuales, your_domain lo sirve Dovecot, así que no debe tratarse como el dominio local del sistema.
Comprueba que ambos servicios están en marcha:
systemctl is-active postfix dovecot
active
active
Paso 3: Crear el usuario de almacenamiento del correo
Todos los buzones virtuales se guardan bajo un mismo directorio y pertenecen a un único usuario del sistema sin privilegios, vmail. Crea el grupo y el usuario con el ID fijo 5000:
sudo groupadd --system --gid 5000 vmail
sudo useradd --system --uid 5000 --gid vmail --home-dir /var/mail/vhosts --no-create-home --shell /usr/sbin/nologin vmail
Crea el directorio de almacenamiento y asígnalo a vmail:
sudo mkdir -p /var/mail/vhosts
sudo chown vmail:vmail /var/mail/vhosts
sudo chmod 770 /var/mail/vhosts
El correo de usuario@dominio se guardará en /var/mail/vhosts/dominio/usuario/ en formato Maildir. Dovecot crea las carpetas de cada dominio y usuario en la primera entrega.
Paso 4: Configurar Postfix para dominios virtuales
Haz una copia del archivo de configuración principal:
sudo cp /etc/postfix/main.cf /etc/postfix/main.cf.orig
Define el nombre del servidor y limita mydestination a los nombres propios de la máquina. Si incluyeras your_domain aquí, Postfix lo entregaría a usuarios de Linux en lugar de a Dovecot:
sudo postconf -e "myhostname = mail.your_domain"
sudo postconf -e "mydestination = \$myhostname, localhost.localdomain, localhost"
Indica a Postfix qué dominios y direcciones son virtuales y que los entregue a Dovecot por LMTP. La ruta del socket es relativa al directorio de spool de Postfix, /var/spool/postfix:
sudo postconf -e "virtual_mailbox_domains = hash:/etc/postfix/vdomains"
sudo postconf -e "virtual_mailbox_maps = hash:/etc/postfix/vmailbox"
sudo postconf -e "virtual_alias_maps = hash:/etc/postfix/virtual"
sudo postconf -e "virtual_transport = lmtp:unix:private/dovecot-lmtp"
Usa Dovecot para la autenticación SASL:
sudo postconf -e "smtpd_sasl_type = dovecot"
sudo postconf -e "smtpd_sasl_path = private/auth"
Configura TLS con el certificado de Let's Encrypt. may ofrece STARTTLS en el puerto 25 sin rechazar a los pocos servidores que no pueden usarlo:
sudo postconf -e "smtpd_tls_cert_file = /etc/letsencrypt/live/mail.your_domain/fullchain.pem"
sudo postconf -e "smtpd_tls_key_file = /etc/letsencrypt/live/mail.your_domain/privkey.pem"
sudo postconf -e "smtpd_tls_security_level = may"
sudo postconf -e "smtp_tls_security_level = may"
Añade comprobaciones básicas a las conexiones entrantes:
sudo postconf -e "smtpd_helo_required = yes"
sudo postconf -e "disable_vrfy_command = yes"
sudo postconf -e "smtpd_helo_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname"
sudo postconf -e "smtpd_sender_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_non_fqdn_sender, reject_unknown_sender_domain"
El valor por defecto de smtpd_relay_restrictions en Ubuntu (permit_mynetworks permit_sasl_authenticated defer_unauth_destination) ya impide el relay abierto, así que déjalo como está.
Crear las tablas de búsqueda
Crea la lista de dominios virtuales. El valor que sigue al dominio se ignora, pero es obligatorio poner uno:
sudo nano /etc/postfix/vdomains
your_domain OK
Crea la lista de buzones. Cada dirección apunta a sí misma: virtual_mailbox_maps solo necesita que exista la clave, y el valor se reutiliza en el paso 5 para decidir qué usuario puede enviar como qué dirección:
sudo nano /etc/postfix/vmailbox
admin@your_domain admin@your_domain
Crea los alias. Todo dominio necesita postmaster y abuse, y aquí ambos van a admin:
sudo nano /etc/postfix/virtual
postmaster@your_domain admin@your_domain
abuse@your_domain admin@your_domain
Postfix lee versiones compiladas de estos archivos. Genéralas con postmap:
sudo postmap /etc/postfix/vdomains
sudo postmap /etc/postfix/vmailbox
sudo postmap /etc/postfix/virtual
Redirige el correo de las cuentas locales del sistema, como root (tareas cron, actualizaciones de seguridad), al buzón de administración:
sudo nano /etc/aliases
postmaster: root
root: admin@your_domain
sudo newaliases
Paso 5: Activar el puerto de envío
Los usuarios envían correo por el puerto 587, donde la autenticación es obligatoria. Abre la tabla de servicios de Postfix:
sudo nano /etc/postfix/master.cf
El archivo de Ubuntu incluye un bloque submission comentado. Sustitúyelo por este. Las líneas que empiezan por -o deben ir sangradas:
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_tls_auth_only=yes
-o smtpd_sender_login_maps=hash:/etc/postfix/vmailbox
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o smtpd_sender_restrictions=reject_sender_login_mismatch
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
Qué hacen estas opciones:
smtpd_tls_security_level=encryptexige STARTTLS antes de cualquier otro comando.smtpd_sasl_auth_enable=yesactiva la autenticación solo en este puerto. El puerto 25 nunca acepta contraseñas.smtpd_sender_login_mapsjunto conreject_sender_login_mismatchimpide que un usuario autenticado envíe en nombre de otro. Comovmailboxasocia cada dirección consigo misma,admin@your_domainsolo puede enviar comoadmin@your_domain.
Comprueba la configuración de Postfix:
sudo postfix check
Si no muestra nada, no hay errores. Postfix se reinicia en el paso 7, cuando Dovecot ya ofrezca los sockets que necesita.
Paso 6: Configurar Dovecot
La configuración de Dovecot está en /etc/dovecot/conf.d/. Vas a modificar cinco archivos.
Ubicación del correo
Abre los ajustes de correo:
sudo nano /etc/dovecot/conf.d/10-mail.conf
Establece como ubicación el árbol de buzones virtuales. %d es el dominio y %n la parte de usuario del login:
mail_location = maildir:/var/mail/vhosts/%d/%n
Autenticación
Abre los ajustes de autenticación:
sudo nano /etc/dovecot/conf.d/10-auth.conf
Establece las opciones siguientes. Al final del archivo, comenta el backend de usuarios del sistema y activa el de archivo de contraseñas:
disable_plaintext_auth = yes
auth_mechanisms = plain login
#!include auth-system.conf.ext
!include auth-passwdfile.conf.ext
Ahora define ese backend. Abre su archivo y sustituye todo su contenido:
sudo nano /etc/dovecot/conf.d/auth-passwdfile.conf.ext
passdb {
driver = passwd-file
args = scheme=SHA512-CRYPT username_format=%u /etc/dovecot/users
}
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}
El passdb comprueba las contraseñas contra /etc/dovecot/users, usando como clave la dirección completa (%u). El userdb asigna a todas las cuentas el mismo propietario del sistema, vmail, y un directorio personal derivado de la dirección, así no tienes que repetirlo para cada usuario. Dovecot sigue usando el archivo de contraseñas para comprobar que un usuario existe antes de aceptar correo para él.
TLS
Abre los ajustes de SSL:
sudo nano /etc/dovecot/conf.d/10-ssl.conf
ssl = required
ssl_cert = </etc/letsencrypt/live/mail.your_domain/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.your_domain/privkey.pem
ssl_min_protocol = TLSv1.2
El < delante de cada ruta indica a Dovecot que lea el contenido del archivo.
Sockets para Postfix
Abre las definiciones de servicios:
sudo nano /etc/dovecot/conf.d/10-master.conf
Sustituye el bloque service lmtp para que el socket LMTP se cree dentro del spool de Postfix, donde pueden alcanzarlo los procesos de Postfix que se ejecutan en chroot:
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}
En el bloque service auth, descomenta y completa el socket de autenticación para Postfix:
service auth {
unix_listener auth-userdb {
#mode = 0666
#user =
#group =
}
# Postfix smtp-auth
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
}
Carpetas por defecto
Abre las definiciones de buzones:
sudo nano /etc/dovecot/conf.d/15-mailboxes.conf
Añade auto = subscribe a los bloques Drafts, Junk, Trash y Sent para que todas las cuentas nuevas los tengan. Por ejemplo:
mailbox Sent {
auto = subscribe
special_use = \Sent
}
Paso 7: Crear el primer buzón y arrancar los servicios
Genera el hash de la contraseña de admin@your_domain. El comando pide la contraseña dos veces y muestra el hash:
sudo doveadm pw -s SHA512-CRYPT
Enter new password:
Retype new password:
{SHA512-CRYPT}$6$Xk2Qb0yY3m6n5R9s$Qm8...
Crea el archivo de contraseñas:
sudo nano /etc/dovecot/users
Añade una línea por buzón: la dirección completa, dos puntos y el hash que acabas de generar:
admin@your_domain:{SHA512-CRYPT}$6$Xk2Qb0yY3m6n5R9s$Qm8...
Solo Dovecot debe poder leerlo:
sudo chown root:dovecot /etc/dovecot/users
sudo chmod 640 /etc/dovecot/users
Comprueba la configuración de Dovecot. doveconf -n termina con un mensaje de error si algún archivo tiene un fallo:
sudo doveconf -n > /dev/null && echo "Dovecot config OK"
Reinicia primero Dovecot, para que existan los sockets, y después Postfix:
sudo systemctl restart dovecot
sudo systemctl restart postfix
Confirma que se han creado los dos sockets con el propietario correcto:
sudo ls -l /var/spool/postfix/private/auth /var/spool/postfix/private/dovecot-lmtp
srw-rw---- 1 postfix postfix 0 Sep 25 12:10 /var/spool/postfix/private/auth
srw------- 1 postfix postfix 0 Sep 25 12:10 /var/spool/postfix/private/dovecot-lmtp
Paso 8: Probar el flujo completo
Prueba cada eslabón de la cadena por separado, para que un fallo apunte a un único componente.
Autenticación y búsqueda de usuario
Comprueba la contraseña y los datos de usuario que usará Dovecot:
sudo doveadm auth test admin@your_domain
sudo doveadm user admin@your_domain
passdb: admin@your_domain auth succeeded
extra fields:
user=admin@your_domain
field value
uid 5000
gid 5000
home /var/mail/vhosts/your_domain/admin
Entrega local por LMTP
Envía un mensaje al alias postmaster. Postfix debería expandirlo a admin@your_domain y pasárselo a Dovecot:
printf 'Subject: Prueba LMTP\n\nLa entrega funciona.\n' | sendmail postmaster@your_domain
Revisa el log:
sudo grep -E 'lmtp|saved mail' /var/log/mail.log | tail -n 3
postfix/lmtp[7021]: 4XbS0q2Hc1z9sWg: to=<admin@your_domain>, orig_to=<postmaster@your_domain>, relay=mail.your_domain[private/dovecot-lmtp], delay=0.08, dsn=2.0.0, status=sent (250 2.0.0 <admin@your_domain> 8cB2FIr7c2ZtGwAAqL9Tyg Saved)
dovecot: lmtp(admin@your_domain)<7023><8cB2FIr7c2ZtGwAAqL9Tyg>: msgid=<[email protected]_domain>: saved mail to INBOX
Confirma el número de mensajes del buzón:
sudo doveadm mailbox status -u admin@your_domain messages INBOX
INBOX messages=1
Leer el correo por IMAP
Abre una sesión IMAP sobre TLS e inicia sesión con la dirección completa. Sustituye your_password por la contraseña real:
openssl s_client -connect mail.your_domain:993 -quiet
a LOGIN admin@your_domain your_password
b SELECT INBOX
c LOGOUT
a OK [CAPABILITY ...] Logged in
* 1 EXISTS
...
b OK [READ-WRITE] Select completed.
Enviar por el puerto de envío
Instala swaks, una herramienta de pruebas SMTP de línea de comandos, y envía un mensaje a un buzón externo por el puerto 587. Te pedirá la contraseña:
sudo apt install swaks
swaks --to [email protected] --from admin@your_domain --server mail.your_domain --port 587 --tls --auth LOGIN --auth-user admin@your_domain
<- 250 2.0.0 Ok: queued as 4XbS3d5Kq1z9sWh
-> QUIT
<- 221 2.0.0 Bye
Prueba a enviar como una dirección que no te pertenece para confirmar que la comprobación del remitente funciona:
swaks --to [email protected] --from ceo@your_domain --server mail.your_domain --port 587 --tls --auth LOGIN --auth-user admin@your_domain
<** 553 5.7.1 <ceo@your_domain>: Sender address rejected: not owned by user admin@your_domain
Por último, envía un mensaje desde Gmail u Outlook a admin@your_domain y comprueba que llega con doveadm mailbox status como antes. Así confirmas que el registro MX, el puerto 25 y la entrega por LMTP funcionan de extremo a extremo.
Paso 9: Añadir usuarios y dominios
Para añadir un buzón, genera un hash con sudo doveadm pw -s SHA512-CRYPT y después:
- Añade una línea
usuario@your_domain:{SHA512-CRYPT}...a/etc/dovecot/users. Dovecot detecta el cambio por sí solo. - Añade
usuario@your_domain usuario@your_domaina/etc/postfix/vmailboxy ejecutasudo postmap /etc/postfix/vmailbox.
Para añadir otro dominio, por ejemplo example.net:
- Crea sus registros A, MX, SPF y DMARC.
- Añade
example.net OKa/etc/postfix/vdomainsy ejecutasudo postmap /etc/postfix/vdomains. - Añade sus alias
postmasteryabusea/etc/postfix/virtualy ejecutasudo postmap /etc/postfix/virtual. - Añade sus buzones como se describe arriba.
Postfix detecta automáticamente las tablas hash: regeneradas, así que no hace falta recargarlo. Para eliminar un buzón, borra sus líneas de ambos archivos, vuelve a ejecutar postmap y elimina /var/mail/vhosts/dominio/usuario cuando ya no necesites su correo.
Paso 10: Bloquear intentos de adivinar contraseñas con Fail2ban
Tanto el puerto 587 como el 993 recibirán intentos de adivinar contraseñas. Instala Fail2ban:
sudo apt install fail2ban
Activa sus jails incluidas para Dovecot y el SASL de Postfix:
sudo nano /etc/fail2ban/jail.d/mail.local
[dovecot]
enabled = true
[postfix-sasl]
enabled = true
Reinicia el servicio y comprueba que las jails están activas:
sudo systemctl restart fail2ban
sudo fail2ban-client status
Status
|- Number of jail: 3
`- Jail list: dovecot, postfix-sasl, sshd
Solución de problemas
connect to transport private/dovecot-lmtp: No such file or directory: falta el socket LMTP. Revisa el bloqueservice lmtpde10-master.conf, reinicia Dovecot y lista/var/spool/postfix/private/.status=bounced (... User doesn't exist: user@your_domain): Postfix aceptó la dirección, pero Dovecot no la conoce. La dirección está envmailboxpero falta en/etc/dovecot/users, o está escrita de forma distinta en cada archivo.Recipient address rejected: User unknown in virtual mailbox table: la dirección no está en/etc/postfix/vmailbox, o no ejecutastepostmapdespués de editarlo.Error: open(/var/mail/vhosts/...) failed: Permission denied:/var/mail/vhostsdebe pertenecer avmail:vmail. Corrígelo consudo chown -R vmail:vmail /var/mail/vhosts.SASL LOGIN authentication faileden el log de Postfix con una contraseña correcta: comprueba la parte de Dovecot consudo doveadm auth test user@your_domainy leesudo grep 'auth' /var/log/mail.log | tail.- El correo saliente se queda en la cola con
Connection timed out: el puerto 25 de salida está bloqueado. Compruébalo connc -vz -w 5 gmail-smtp-in.l.google.com 25.
Conclusión
Tienes un servidor de correo en el que Postfix acepta y reenvía el correo, Dovecot lo guarda en carpetas Maildir por dominio y autentica a los usuarios de IMAP y SMTP, y los buzones o dominios nuevos se añaden editando dos archivos. Antes de usarlo con correo real, añade la firma DKIM con OpenDKIM como se explica en la guía de Postfix, porque Gmail y Outlook la esperan. Después, plantéate filtrar el spam con Rspamd, añadir cuotas y filtros Sieve con dovecot-sieve, y hacer copias de seguridad periódicas de /var/mail/vhosts, /etc/postfix, /etc/dovecot y /etc/opendkim.
