Postfix es el agente de transferencia de correo (MTA) que usan por defecto Debian y Ubuntu: acepta correo de otros servidores en el puerto 25, lo entrega en los buzones locales y envía el correo saliente al resto de internet. En este tutorial configurarás Postfix en Ubuntu 24.04 para que reciba el correo de your_domain en buzones Maildir, envíe correo que supere las comprobaciones SPF, DKIM y DMARC de Gmail y Outlook, y use un certificado de Let's Encrypt para TLS. Los clientes de correo (IMAP y envío autenticado por el puerto 587) se añaden con Dovecot en la guía siguiente.
Requisitos previos
Para seguir este tutorial necesitas:
- Un servidor con Ubuntu 24.04 LTS y una dirección IPv4 pública, por ejemplo un VPS de CubePath. Lo mejor es un servidor limpio; no instales Postfix junto a otro MTA.
- Un usuario no root con privilegios
sudo. Esta guía usayour_usercomo el buzón que recibe el correo. - Un dominio que controles (
your_domain) y acceso a su zona DNS. - La posibilidad de configurar el registro DNS inverso (PTR) de la IP del servidor.
- El puerto TCP 25 de salida abierto. En CubePath, como en la mayoría de proveedores cloud, el puerto 25 de salida está cerrado por defecto para evitar el spam; abre un ticket de soporte describiendo el uso que harás del correo para solicitarlo. El paso 1 explica cómo comprobarlo.
A lo largo de la guía, sustituye your_domain por tu dominio, mail.your_domain por el nombre del servidor de correo y your_server_ip por su IPv4 pública.
Paso 1: Configurar el nombre del servidor y comprobar el puerto 25
Los servidores de correo se identifican por su nombre en cada conversación SMTP, y los servidores que reciben comprueban que el nombre, la IP y el DNS inverso coinciden. Asigna al servidor su nombre completo:
sudo hostnamectl set-hostname mail.your_domain
Añádelo a /etc/hosts para que el servidor resuelva su propio nombre sin depender del DNS:
sudo nano /etc/hosts
127.0.1.1 mail.your_domain mail
Comprueba el resultado:
hostname -f
mail.your_domain
Ahora comprueba que el puerto 25 de salida está abierto conectando con el servidor de correo entrante de Gmail:
nc -vz -w 5 gmail-smtp-in.l.google.com 25
Connection to gmail-smtp-in.l.google.com (142.250.x.x) 25 port [tcp/smtp] succeeded!
Si el comando agota el tiempo de espera, el SMTP saliente está bloqueado. Puedes terminar la instalación y recibir correo, pero no podrás entregarlo a otros servidores hasta que se abra.
Paso 2: Crear los registros DNS
Crea estos registros en la zona DNS de tu dominio. El registro DKIM se añade más adelante, en el paso 7, cuando exista la clave.
| Tipo | Nombre | Valor | Para qué sirve |
|---|---|---|---|
| A | mail.your_domain | your_server_ip | Resuelve el servidor de correo |
| MX | your_domain | 10 mail.your_domain | Indica a otros servidores dónde entregar el correo del dominio |
| TXT | your_domain | v=spf1 mx ~all | SPF: solo los servidores MX pueden enviar en nombre del dominio |
| TXT | _dmarc.your_domain | v=DMARC1; p=none; rua=mailto:postmaster@your_domain | Política e informes DMARC |
Configura el registro PTR (DNS inverso) de your_server_ip para que apunte a mail.your_domain. El DNS inverso pertenece a quien gestiona la dirección IP, así que se configura a través de tu proveedor de hosting y no en la zona de tu dominio. Sin un PTR que coincida, Gmail y Outlook rechazan tu correo o lo mandan a spam.
~all (fallo suave) y p=none son valores seguros para empezar mientras haces pruebas. Cuando los informes DMARC muestren que todo el correo legítimo pasa las comprobaciones, endurécelos a -all y a p=quarantine o p=reject.
Comprueba los registros desde el servidor. Los cambios de DNS pueden tardar unos minutos en propagarse:
dig +short MX your_domain
dig +short A mail.your_domain
dig +short -x your_server_ip
dig +short TXT your_domain
10 mail.your_domain.
your_server_ip
mail.your_domain.
"v=spf1 mx ~all"
Paso 3: Instalar Postfix
Actualiza el índice de paquetes e instala Postfix:
sudo apt update
sudo apt install postfix
El instalador hace dos preguntas:
- General mail configuration type: elige
Internet Site. - System mail name: escribe
your_domain(nomail.your_domain). Este valor se guarda en/etc/mailnamey se convierte en el dominio del correo que envían los usuarios locales, de modo queyour_userenvía comoyour_user@your_domain.
Postfix arranca automáticamente. Comprueba que escucha en el puerto 25:
sudo ss -ltnp | grep ':25 '
LISTEN 0 100 0.0.0.0:25 0.0.0.0:* users:(("master",pid=2215,fd=13))
LISTEN 0 100 [::]:25 [::]:* users:(("master",pid=2215,fd=14))
Si te has equivocado en alguna opción, ejecuta sudo dpkg-reconfigure postfix para responder de nuevo.
Paso 4: Obtener un certificado TLS
Los demás servidores de correo cifran la conexión con STARTTLS cuando el tuyo lo ofrece, y Gmail marca el correo de los servidores que no usan TLS. Obtén un certificado gratuito para mail.your_domain con Let's Encrypt. El modo standalone de Certbot levanta su propio servidor web temporal en el puerto 80, así que antes permite SSH y HTTP en el cortafuegos:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 25/tcp
sudo ufw enable
Instala Certbot y solicita el certificado. El hook de despliegue recarga Postfix tras cada renovación automática para que use los archivos nuevos:
sudo apt install certbot
sudo certbot certonly --standalone -d mail.your_domain --deploy-hook "systemctl reload postfix"
Certbot guarda el certificado en /etc/letsencrypt/live/mail.your_domain/ e instala un temporizador de systemd que lo renueva. Prueba la renovación:
sudo certbot renew --dry-run
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/mail.your_domain/fullchain.pem (success)
Paso 5: Configurar Postfix
Los ajustes principales de Postfix están en /etc/postfix/main.cf. En lugar de editar el archivo a mano, usa postconf -e, que cambia un único parámetro y evita líneas duplicadas. Primero haz una copia del original:
sudo cp /etc/postfix/main.cf /etc/postfix/main.cf.orig
Define el nombre del servidor y los dominios para los que acepta correo:
sudo postconf -e "myhostname = mail.your_domain"
sudo postconf -e "mydestination = \$myhostname, your_domain, localhost.localdomain, localhost"
Entrega el correo en una carpeta Maildir dentro del directorio personal de cada usuario. Maildir guarda un archivo por mensaje y es el formato que usará Dovecot en la guía siguiente. Vaciar mailbox_command garantiza que ningún programa de entrega externo lo sustituya:
sudo postconf -e "home_mailbox = Maildir/"
sudo postconf -e "mailbox_command ="
Indica a Postfix el certificado de Let's Encrypt y activa TLS oportunista en ambos sentidos:
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"
may es lo correcto para el correo entre servidores en el puerto 25: se usa TLS siempre que el otro extremo lo admita, y el correo de los pocos servidores que no lo admiten se sigue aceptando.
Añade restricciones básicas que rechazan remitentes claramente mal configurados o falsificados antes de aceptar el mensaje:
sudo postconf -e "smtpd_helo_required = yes"
sudo postconf -e "disable_vrfy_command = yes"
sudo postconf -e "smtpd_helo_restrictions = permit_mynetworks, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname"
sudo postconf -e "smtpd_sender_restrictions = permit_mynetworks, 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 que el servidor sea un relay abierto: solo los procesos locales pueden enviar a dominios externos. Déjalo como está.
Si el servidor tiene más de una IPv4 pública, fija el correo saliente a la que tiene el PTR mail.your_domain:
sudo postconf -e "smtp_bind_address = your_server_ip"
Comprueba que la configuración no tiene errores y recarga:
sudo postfix check
sudo systemctl reload postfix
postfix check no muestra nada cuando todo está bien. Revisa todos los ajustes que difieren de los valores por defecto con:
postconf -n
Paso 6: Configurar alias y recibir correo
El correo para postmaster@your_domain y root@your_domain tiene que llegar a una persona: ahí van los informes DMARC y los avisos de rebote. Abre el archivo de alias:
sudo nano /etc/aliases
postmaster: root
root: your_user
Regenera la base de datos de alias:
sudo newaliases
Ahora envía un mensaje desde una cuenta externa, como Gmail, a your_user@your_domain y sigue el log mientras llega:
sudo tail -f /var/log/mail.log
Una entrega correcta termina con una línea como esta:
postfix/local[3120]: 4XbQ2K1d7Wz9sWb: to=<your_user@your_domain>, relay=local, delay=0.12, delays=0.08/0.01/0/0.03, dsn=2.0.0, status=sent (delivered to maildir)
Pulsa Ctrl+C para dejar de seguir el log. El mensaje queda guardado como archivo en el Maildir del usuario:
ls ~/Maildir/new/
Postfix crea el directorio Maildir en la primera entrega, así que no existe antes de que llegue el primer mensaje.
Paso 7: Firmar el correo saliente con DKIM
DKIM añade una firma criptográfica a cada mensaje saliente, y los servidores que lo reciben la verifican con una clave pública publicada en DNS. Junto con SPF, es lo que permite que DMARC dé un resultado positivo. OpenDKIM firma el correo y Postfix le pasa los mensajes a través de la interfaz milter.
Instala OpenDKIM:
sudo apt install opendkim opendkim-tools
Genera un par de claves de 2048 bits con el selector default:
sudo mkdir -p /etc/opendkim/keys/your_domain
sudo opendkim-genkey -b 2048 -d your_domain -D /etc/opendkim/keys/your_domain -s default -v
sudo chown -R opendkim:opendkim /etc/opendkim/keys
Esto crea default.private (la clave privada) y default.txt (el registro DNS). Abre la configuración de OpenDKIM:
sudo nano /etc/opendkim.conf
Busca la línea existente Socket local:/run/opendkim/opendkim.sock y coméntala con #. Después añade estas líneas al final del archivo:
Domain your_domain
Selector default
KeyFile /etc/opendkim/keys/your_domain/default.private
Socket inet:8891@localhost
Un socket TCP en localhost evita problemas de permisos con Postfix, que en Ubuntu ejecuta su servidor SMTP dentro de un chroot. Reinicia OpenDKIM y comprueba que escucha:
sudo systemctl restart opendkim
sudo ss -ltnp | grep 8891
LISTEN 0 4096 127.0.0.1:8891 0.0.0.0:* users:(("opendkim",pid=4012,fd=3))
Conecta Postfix con OpenDKIM. non_smtpd_milters hace que también se firme el correo enviado localmente con sendmail, y milter_default_action = accept mantiene el flujo de correo si OpenDKIM está caído:
sudo postconf -e "milter_default_action = accept"
sudo postconf -e "smtpd_milters = inet:localhost:8891"
sudo postconf -e "non_smtpd_milters = \$smtpd_milters"
sudo systemctl reload postfix
Publica la clave pública. Muestra el registro generado:
sudo cat /etc/opendkim/keys/your_domain/default.txt
El archivo divide la clave en varias cadenas entre comillas. En tu panel DNS, crea un registro TXT llamado default._domainkey.your_domain cuyo valor sea todas esas cadenas unidas, sin comillas ni espacios entre ellas, empezando por v=DKIM1; h=sha256; k=rsa; p= seguido de la clave.
Cuando el registro se haya propagado, compruébalo:
sudo opendkim-testkey -d your_domain -s default -vvv
opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: checking key 'default._domainkey.your_domain'
opendkim-testkey: key not secure
opendkim-testkey: key OK
key not secure solo significa que la zona no está firmada con DNSSEC. La línea que importa es key OK.
Paso 8: Probar el correo saliente
Envía un mensaje de prueba a un buzón externo que puedas leer, como una dirección de Gmail. El comando sendmail lo proporciona Postfix:
printf 'Subject: Prueba de Postfix\n\nHola desde mail.your_domain.\n' | sendmail -f your_user@your_domain [email protected]
Busca el resultado en el log:
sudo grep 'status=' /var/log/mail.log | tail -n 3
postfix/smtp[4410]: 4XbQ7m2Hc1z9sWd: to=<[email protected]>, relay=gmail-smtp-in.l.google.com[142.250.x.x]:25, delay=1.2, delays=0.05/0.01/0.4/0.7, dsn=2.0.0, status=sent (250 2.0.0 OK ...)
status=sent con dsn=2.0.0 significa que el servidor de destino aceptó el mensaje. En Gmail, abre el mensaje, elige Mostrar original y comprueba que SPF, DKIM y DMARC aparecen como PASS.
Solución de problemas
connect to ...:25: Connection timed outen el log: el puerto 25 de salida está bloqueado. Compruébalo como en el paso 1 y solicita su apertura a tu proveedor. Los mensajes se quedan en la cola y se reintentan automáticamente; consúltalos conmailqy fuerza un reintento consudo postqueue -f.- El correo se rechaza o llega a spam: comprueba que el registro PTR coincide con
myhostname(dig +short -x your_server_ip) y lee en Mostrar original qué comprobación falla. Si el servidor también tiene IPv6, el PTR y el SPF deben cubrir también la dirección IPv6, o limita Postfix a IPv4 consudo postconf -e "inet_protocols = ipv4"seguido desudo systemctl restart postfix. Relay access deniedal recibir: el dominio de la dirección de destino no está enmydestination.status=bounced (unknown user: ...): no existe ningún usuario de Linux ni alias con ese nombre. Crea el usuario o añade un alias en/etc/aliasesy ejecutasudo newaliases.- DKIM no firma: busca líneas de
opendkimen/var/log/mail.log. Si los mensajes salientes no generan una líneaDKIM-Signature field added, lo habitual es que el dominio delFromno coincida con el valor deDomainen/etc/opendkim.conf.
Conclusión
Tu servidor acepta ahora correo para your_domain en el puerto 25, lo guarda en Maildir y envía correo por TLS con un registro PTR válido, SPF, DKIM y DMARC. El siguiente paso es instalar Dovecot para que los usuarios lean el correo por IMAP y envíen a través del servidor desde un cliente de correo en el puerto 587 con autenticación. Después, plantéate añadir filtrado de spam con Rspamd y pasar la política DMARC a p=quarantine cuando los informes estén limpios.
