Puerto 25 bloqueado: cómo enviar correo igual (sin trucos sospechosos)

¿Te fue útil?

Provisiones una nueva VM. Despliegas tu aplicación. Disparas un correo de restablecimiento de contraseña. No llega nada.
Tus registros muestran reintentos, timeouts y una pequeña verdad silenciosa: TCP saliente en el puerto 25 está bloqueado.

Si estás pensando “simplemente abriré el puerto 25”, bienvenido a Internet moderno donde el abuso arruinó la fiesta.
La buena noticia es que aún puedes enviar correo de forma fiable—sin tunelizar por algo maldito y sin convertirte en tu propio equipo de entregabilidad.

Qué es el puerto 25 (y por qué está bloqueado)

El puerto 25 es el puerto SMTP clásico usado principalmente para la entrega de correo servidor a servidor:
tu agente de transferencia de correo (MTA) habla con el servidor MX del dominio destinatario y entrega el mensaje.
Ese modelo de “directo al MX” todavía existe, pero no es cómo deberías ejecutar correo desde cómputo aleatorio en 2026.

Los proveedores en la nube y muchos ISP bloquean el 25 saliente por defecto por una razón: el spam.
Los rangos de IP nuevos se abusan rápido. Bloquear el puerto 25 reduce el abuso, protege la reputación del proveedor y evita que su espacio IP acabe en listas negras.
No estás siendo atacado personalmente; vives en un barrio donde alguien sigue incendiando los sofás.

El patrón moderno es: tu servidor envía correo vía un endpoint de envío autenticado (normalmente puerto 587 con STARTTLS, o puerto 465 con TLS implícito),
o vía una API de envío de correo. El servicio de relé se encarga luego de la entregabilidad: reputación de IP, límites de velocidad, feedback loops, firmado DKIM, etc.

Una cita para pegar sobre tu monitor (idea parafraseada): Gene Kranz: “Sé duro y competente.” El trabajo de fiabilidad es sobre todo competencia bajo presión.

Guía rápida de diagnóstico

Cuando el correo falla, la gente inmediatamente discute SPF vs DKIM vs “el proveedor está caído.”
Para. Diagnostica como un SRE: estrecha el radio del problema y luego localiza el cuello de botella.

Primero: confirma que realmente es un bloqueo de red (no un bug de la app)

  • Desde el host que envía correo, prueba la conectividad TCP hacia un servidor SMTP conocido en 25, 587 y 465.
  • Comprueba si tu aplicación está intentando direct-to-MX, o usando un relé.
  • Busca “connection timed out” (bloqueo de red) vs “authentication failed” (credenciales) vs “rejected” (política/entregabilidad).

Segundo: identifica quién lo está bloqueando

  • ¿El proveedor en la nube está bloqueando el 25 saliente en el borde del hipervisor?
  • ¿Tu VPC/NACL/grupo de seguridad restringe el egress?
  • ¿Un firewall local (ufw/iptables/nftables) está bloqueando?

Tercero: elige la alternativa limpia

  • Si solo necesitas correo transaccional: usa envío SMTP en 587/465 hacia un relé reputado.
  • Si necesitas alto volumen o telemetría sólida: usa una API de correo (a menudo respaldada por SMTP internamente).
  • Si son notificaciones internas únicamente: enruta a un relé interno o a una herramienta de colaboración, no al Internet público.

Cuarto: verifica la entregabilidad, no solo “se conectó”

  • Comprueba que tu dominio From esté autenticado (SPF/DKIM/DMARC) y alineado con el emisor.
  • Confirma el manejo de rebotes. Las fallas silenciosas son las más caras.

Broma #1: El puerto 25 es como el microondas de la oficina—si lo dejas sin supervisión, alguien pondrá pescado y lo arruinará para todos.

Qué hacer en lugar de usar el puerto 25

Opción A (recomendada para la mayoría): relé SMTP autenticado en puerto 587 (STARTTLS)

Esta es la configuración “aburrida y correcta”. Tu host envía correo a un relé usando credenciales.
El relé habla SMTP con el resto del mundo, gestiona la reputación y maneja las partes feas.

Usa el puerto 587 con STARTTLS a menos que el proveedor indique explícitamente 465. El 587 es el puerto de submission según estándares,
y funciona bien con las políticas de seguridad modernas.

Opción B: relé SMTP en puerto 465 (TLS implícito)

El puerto 465 está ampliamente soportado y, en la práctica, funciona. Es “SMTPS” donde TLS se establece de inmediato.
Si estás en un entorno muy restringido que bloquea STARTTLS o lo manipula, 465 puede ser más simple.

Opción C: API de correo del proveedor (HTTP)

Si tu entorno bloquea SMTP saliente por completo, o quieres instrumentación e idempotencia más limpias,
una API HTTPS suele ser más sencilla. También evita las semánticas vagas y “amables” de errores de SMTP.

La pega: estás acoplando la lógica de la app a una API de proveedor. Está bien si la tratas como cualquier otra dependencia externa:
timeouts, reintentos con backoff, circuit breakers y colas.

Opción D: relé interno + gateway de salida

En entornos corporativos, la respuesta correcta frecuentemente es “no envíes correo desde servidores de app”.
Envía a un relé interno (incluso por 25 dentro de la red) y deja que una puerta de enlace endurecida gestione la entrega externa.

Opción E: solicitar desbloqueo del puerto 25 (rara vez la mejor primera medida)

Algunos proveedores en la nube desbloquean el 25 saliente si demuestras que no eres una máquina de spam.
Esto puede justificarse para sistemas heredados o para operar un MTA real. No es un atajo hacia la entregabilidad.
La reputación de una IP nueva es brutal, y “abrimos el puerto 25” no es una estrategia de correo.

Tareas prácticas y comandos (con decisiones)

Aquí hay tareas operativas que puedes ejecutar hoy. Cada una incluye: comando, qué significa la salida y la decisión que tomas.
Están escritas para hosts Linux con Postfix, pero los diagnósticos aplican en general.

Tarea 1: Demostrar que TCP/25 está bloqueado (timeout vs refuse importa)

cr0x@server:~$ nc -vz -w 3 gmail-smtp-in.l.google.com 25
nc: connect to gmail-smtp-in.l.google.com port 25 (tcp) timed out: Operation now in progress

Significado: Un timeout normalmente indica una política de red que bloquea (borde del proveedor, firewall o filtrado de egress).
Un “refused” significaría que alcanzaste el host pero el puerto está cerrado (raro para MX públicos).

Decisión: No pierdas tiempo ajustando Postfix. Pasa a relé en 587/465 o arregla la política de egress.

Tarea 2: Comprobar si 587 funciona (tu vía de escape)

cr0x@server:~$ nc -vz -w 3 smtp.relay.example 587
Connection to smtp.relay.example 587 port [tcp/submission] succeeded!

Significado: Existe la ruta de red hacia el puerto de submission.

Decisión: Configura tu MTA/app para autenticarse con este relé en 587 con TLS.

Tarea 3: Validar la negociación STARTTLS (no asumas cifrado)

cr0x@server:~$ openssl s_client -starttls smtp -crlf -connect smtp.relay.example:587 -servername smtp.relay.example < /dev/null
CONNECTED(00000003)
---
250-STARTTLS
---
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_256_GCM_SHA384

Significado: El servidor anuncia STARTTLS y negociaste TLS moderno.

Decisión: Si falta STARTTLS o TLS falla, cambia a 465 o arregla problemas de inspección/proxy TLS.

Tarea 4: Ver si tu aplicación intenta direct-to-MX (mala configuración por defecto)

cr0x@server:~$ grep -R "smtp" -n /etc | head
/etc/postfix/main.cf:relayhost =
/etc/postfix/main.cf:inet_interfaces = loopback-only

Significado: relayhost vacío significa que Postfix intentará entrega directa a registros MX.

Decisión: Ajusta relayhost a tu smart host autenticado salvo que operes intencionalmente un MTA saliente.

Tarea 5: Inspeccionar la cola de Postfix (¿el correo está atascado?)

cr0x@server:~$ mailq
-Queue ID-  --Size-- ----Arrival Time---- -Sender/Recipient-------
3F1A12C0A9     1542 Fri Jan  3 10:41:12  alerts@yourdomain.example
(connect to gmail-smtp-in.l.google.com[142.250.0.27]:25: Connection timed out)
                                         user@gmail.com

-- 1 Kbytes in 1 Request.

Significado: Postfix está intentando direct-to-MX por 25 y da timeouts.

Decisión: Detén la hemorragia: configura relayhost y vacía la cola tras confirmar credenciales.

Tarea 6: Identificar quién bloquea el egress (comprobación de firewall local)

cr0x@server:~$ sudo nft list ruleset | sed -n '1,120p'
table inet filter {
  chain output {
    type filter hook output priority 0;
    policy accept;
  }
}

Significado: La política de la cadena output es accept; el firewall local probablemente no está bloqueando.

Decisión: Si ves drops explícitos para tcp dport 25/587/465, arregla esas reglas o coordina con seguridad.

Tarea 7: Comprobar reglas de egress en la nube (security group / NACL equivalente via herramientas de instancia)

cr0x@server:~$ ip route
default via 10.0.0.1 dev eth0
10.0.0.0/16 dev eth0 proto kernel scope link src 10.0.12.34

Significado: Estás en una red privada; el egress probablemente atraviesa NAT o appliances de firewall.

Decisión: Valida que NAT/políticas de seguridad permitan 587/465. No supongas que “ruta por defecto” significa “Internet funciona para SMTP”.

Tarea 8: Configurar relayhost en Postfix (corrección central)

cr0x@server:~$ sudo postconf -e 'relayhost = [smtp.relay.example]:587'
cr0x@server:~$ sudo postconf -e 'smtp_tls_security_level = encrypt'
cr0x@server:~$ sudo postconf -e 'smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt'

Significado: Los corchetes fuerzan a Postfix a usar el host tal cual (sin lookup MX). Se especifica puerto 587. TLS requerido.

Decisión: Procede solo si puedes autenticarte (siguiente tarea). Si no, cambiarás timeouts por errores de auth.

Tarea 9: Habilitar autenticación SASL para el relé

cr0x@server:~$ sudo postconf -e 'smtp_sasl_auth_enable = yes'
cr0x@server:~$ sudo postconf -e 'smtp_sasl_security_options = noanonymous'
cr0x@server:~$ sudo postconf -e 'smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd'

Significado: Postfix autenticará usando credenciales almacenadas en /etc/postfix/sasl_passwd.

Decisión: Protege el fichero de contraseñas con permisos estrictos. Si no puedes protegerlo, no pongas credenciales SMTP en esa máquina.

Tarea 10: Crear el mapa de credenciales y verificar que compila

cr0x@server:~$ sudo bash -c 'printf "[smtp.relay.example]:587 username:app-specific-password\n" > /etc/postfix/sasl_passwd'
cr0x@server:~$ sudo chmod 0600 /etc/postfix/sasl_passwd
cr0x@server:~$ sudo postmap /etc/postfix/sasl_passwd
cr0x@server:~$ ls -l /etc/postfix/sasl_passwd*
-rw------- 1 root root  63 Jan  3 10:52 /etc/postfix/sasl_passwd
-rw------- 1 root root 122 Jan  3 10:52 /etc/postfix/sasl_passwd.db

Significado: El archivo .db es el mapa compilado que usa Postfix. Los permisos son estrictos.

Decisión: Si postmap falla, corrige el formato o la cadena de herramientas de hashing antes de reiniciar Postfix.

Tarea 11: Recargar Postfix y vigilar logs en vivo durante un envío de prueba

cr0x@server:~$ sudo systemctl reload postfix
cr0x@server:~$ sudo tail -f /var/log/mail.log
Jan  3 10:54:11 server postfix/smtp[22119]: 3F1A12C0A9: to=<user@gmail.com>, relay=smtp.relay.example[203.0.113.10]:587, delay=12, delays=0.1/0.02/2.1/9.8, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as ABC123)

Significado: El correo ahora se reenvía a través del smart host en 587 y fue aceptado (DSN 2.0.0).

Decisión: Vacía la cola si hay acumulación; luego monitoriza tasas de rebote y los paneles del proveedor.

Tarea 12: Vaciar la cola (solo después de arreglar la causa raíz)

cr0x@server:~$ sudo postfix flush
cr0x@server:~$ mailq | tail -n 3
Mail queue is empty

Significado: Los mensajes acumulados se reintentan de inmediato; la cola ahora está vacía.

Decisión: Si los mensajes vuelven a la cola con errores de auth, detente y corrige las credenciales. No atiborres el relé y provoques límites.

Tarea 13: Confirmar que no eres un relé abierto por accidente (sí, aún pasa)

cr0x@server:~$ sudo postconf mynetworks smtpd_recipient_restrictions | sed -n '1,3p'
mynetworks = 127.0.0.0/8 [::1]/128
smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination

Significado: Solo localhost está confiado; el relaying saliente no autenticado se rechaza. Bien.

Decisión: Si ves reglas permisivas (como amplios rangos RFC1918) en un host expuesto, arréglalo inmediatamente.

Tarea 14: Comprobar DNS para SPF (básico pero obligatorio)

cr0x@server:~$ dig +short TXT yourdomain.example
"v=spf1 include:spf.relay.example -all"

Significado: Existe SPF y delega al proveedor de relé.

Decisión: Si SPF falta o es demasiado permisivo, arréglalo antes de escalar volumen. La deuda de entregabilidad se acumula rápido.

Tarea 15: Comprobar la política DMARC (los raíles de seguridad de tu dominio)

cr0x@server:~$ dig +short TXT _dmarc.yourdomain.example
"v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.example; adkim=s; aspf=s"

Significado: DMARC existe y aplica alineación (estricta en este ejemplo).

Decisión: Si no tienes DMARC, empieza con p=none para observar, luego avanza hacia la aplicación una vez alineado.

Tarea 16: Confirmar que el servidor no intenta IPv6 y falla (sorprendentemente común)

cr0x@server:~$ postconf inet_protocols
inet_protocols = all

Significado: Postfix usará IPv4 e IPv6. Si el egress IPv6 está roto, podrías ver fallos SMTP intermitentes.

Decisión: Si los logs muestran timeouts por IPv6, arregla el enrutamiento/DNS IPv6 o pon temporalmente inet_protocols = ipv4.

Referencia de Postfix: relay a través de un smart host

Si estás ejecutando Postfix en el servidor (o tu aplicación entrega correo a localhost), la configuración de relé a un smart host es la solución más limpia.
El objetivo es simple: tu máquina no debería negociar con MX aleatorios en Internet. Debe hablar con un relé de confianza.

Una forma mínima sensata de main.cf

Estos son los ajustes que importan para este problema. Manténlo pequeño. Manténlo entendible. La complejidad es donde nacen las interrupciones.

cr0x@server:~$ sudo postconf -n | egrep '^(relayhost|smtp_tls|smtp_sasl|inet_interfaces|myhostname|myorigin)'
myhostname = server.yourdomain.example
myorigin = /etc/mailname
inet_interfaces = loopback-only
relayhost = [smtp.relay.example]:587
smtp_tls_security_level = encrypt
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

Algunas opiniones, porque estás aquí para decidir:

  • Fija inet_interfaces = loopback-only en servidores de app. No estás ofreciendo SMTP entrante al mundo. No te disfraces de MTA.
  • Usa smtp_tls_security_level = encrypt para no degradar silenciosamente a texto plano.
  • Encierra el relayhost entre corchetes para que Postfix no haga resolución MX. Quieres un destino explícito.
  • Almacena las credenciales de forma segura. Si el host es efímero, usa gestión de secretos y renderiza el mapa en el arranque.

No filtrifiques credenciales en logs o historial de shell

Usa contraseñas específicas de aplicación o claves API con permisos limitados. Rótalas. Trata las credenciales SMTP como credenciales de base de datos: robadas significan abuso, y abuso significa listas negras.

Envío desde la aplicación: SMTP vs API

Puedes enviar correo desde tu aplicación de dos maneras principales:
SMTP (a un relé) o una API HTTP (al mismo tipo de proveedores). Ninguna es moralmente pura.
Elige según tus modos de fallo y tu madurez operativa.

SMTP desde apps: directo, pero cuida timeouts y pooling

Las librerías SMTP varían mucho en cómo manejan STARTTLS, reutilización de conexión y fallos parciales.
Quieres:

  • Host/puerto explícito (587 o 465), nunca lógica “enviar al MX”.
  • Timeouts de conexión y lectura razonables (no infinitos).
  • Reintentos con backoff para respuestas 4xx transitorias.
  • Colas (incluso una cola local simple) si el correo es crítico.

API de correo: mejor observabilidad, menos casos borde del protocolo

Con una API normalmente obtienes IDs de mensaje, respuestas de error estructuradas y webhooks para rebotes/quejas.
Es más fácil implementar idempotencia (“no enviar correos duplicados de restablecimiento de contraseña”) y es más sencillo instrumentar.

La trampa: si tratas la API como “siempre disponible”, tu app colapsará cuando el proveedor tenga un mal día.
Usa una cola, fija un presupuesto de reintentos y degrada de forma elegante.

Conceptos básicos de entregabilidad que no puedes ignorar

El bloqueo del puerto 25 es un problema de transporte. Pero una vez arreglado el transporte, la entregabilidad será tu próxima interrupción.
Aquí es donde los equipos se sorprenden: los mensajes están “enviados” (aceptados por el relé) pero nunca los ve la gente.

Usa un remitente de sobre real y maneja los rebotes

Configura un dominio/dirección de rebotes que monitorices. Si ignoras los rebotes, seguirás enviando a direcciones muertas,
tu tasa de quejas subirá y el proveedor te limitará o suspenderá.

SPF, DKIM, DMARC: la alineación vence a la superstición

  • SPF indica qué servidores pueden enviar en nombre de tu dominio.
  • DKIM firma los mensajes para que los receptores verifiquen que no fueron alterados.
  • DMARC unifica con reglas de alineación y reportes.

La regla operativa: el dominio en el encabezado From debe alinearse con SPF y/o DKIM, y DMARC debe expresar una política intencional.
Si tu relé firma DKIM por ti, perfecto—publica los registros del selector que te den y verifica su propagación.

Existen límites de tasa; no son personales

Incluso los buenos relés aplican límites por cuenta y por dominio. Trata las respuestas SMTP/API como parte del contrato.
Si atas el relé con un bucle de reintentos, descubrirás el límite a la mala.

Broma #2: Los códigos de error SMTP son el único lugar donde verás un servidor decir educadamente “No puedo hacer eso” mientras te juzga activamente.

Mini-historias corporativas desde el terreno

Mini-historia 1: El incidente causado por una suposición equivocada

Una empresa SaaS de tamaño medio migró cargas desde un colo a una gran nube. La app enviaba correos de registro y restablecimiento a través de una instancia Postfix local.
En el colo tenían un rango IP estático con buena reputación y el 25 saliente estaba abierto. En la nube, el equipo asumió lo mismo.

Llegó la semana de lanzamiento. La app funcionaba, la base de datos estaba bien, el tráfico subió—y la cola de soporte se incendió.
Los usuarios no podían verificar cuentas, no podían restablecer contraseñas y la pérdida de clientes empezó en horas.
El ingeniero on-call vio crecimiento en la cola de Postfix y asumió “el MX destinatario está lento.”

Escalaron la máquina de Postfix. Dos veces. La cola creció más rápido, porque cada nueva instancia también estaba bloqueada en 25.
La suposición equivocada no fue solo “el puerto 25 está abierto”. Fue “el correo es lógica de la app, no infraestructura.”

La solución fue aburrida: configurar relayhost a un relé autenticado reputado en 587, publicar SPF/DKIM, vaciar la cola y añadir una prueba de integración que verifique la conectividad de submission SMTP en cada despliegue.
La recomendación del postmortem fue aún más aburrida: trata el correo como una dependencia externa con SLOs explícitos y alertas por profundidad de cola.

Mini-historia 2: La optimización que salió mal

Un equipo empresarial quiso reducir latencia en correos transaccionales. Alguien propuso mantener una conexión SMTP persistente desde cada pod de la app al proveedor de relé,
reutilizándola para cientos de mensajes para ahorrar handshakes TCP y TLS. En el diagrama parecía elegante.

En la práctica, creó un nuevo modo de fallo: cuando el relé rotó certificados o impuso timeouts por inactividad, los pods siguieron escribiendo en sockets muertos.
Algunas librerías SMTP reportaban éxito hasta el flush final; otras lanzaban excepciones opacas; algunas simplemente se colgaban.
La latencia mejoró hasta que dejó de hacerlo, y entonces las entregas se volvieron no determinísticas.

El equipo también descubrió que su “optimización” amplificaba picos de límites de tasa. Cuando un job por lotes arrancaba, cada pod volcaba mensajes tan rápido como podía sobre una conexión caliente.
El relé respondió con diferimientos 4xx transitorios, que su lógica de reintento interpretó como “intenta otra vez de inmediato”, produciendo una pequeña auto-DDOS.

Revirtieron a un servicio de envío con cola controlada, concurrencia limitada, timeouts explícitos y backoff exponencial.
La arquitectura final fue menos ingeniosa y mucho más predecible. La predictabilidad es el objetivo.

Mini-historia 3: La práctica aburrida pero correcta que salvó el día

Una plataforma de servicios financieros ejecutaba pruebas semanales de recuperación de desastres. Parte de la lista: confirmar el correo saliente vía relé desde la región DR, incluyendo la autenticación basada en DNS.
No era trabajo glamoroso. También fue lo primero que la gente intentó saltarse cuando el calendario se apretaba.

Un trimestre, la prueba DR falló: los correos eran aceptados por el relé, pero llegaban sin firmas DKIM.
El equipo rastreó el problema hasta una cuenta de relé mal configurada en el entorno DR: podía enviar, pero la configuración de firmado no estaba asociada a ese conjunto de credenciales.

Arreglaron la configuración antes de que importara, y más tarde ese año un incidente regional real forzó el tráfico al DR.
Cuando salieron las notificaciones a clientes, se entregaron limpias. Sin corajes de última hora. Sin “¿por qué está en spam?”

La lección: los sistemas más fiables se construyen con pasos pequeños, verificables y aburridos. Si tu ruta de correo no está en tu plan DR, no tienes un plan DR—tienes un deseo.

Errores comunes: síntoma → causa raíz → solución

1) Síntoma: la cola de correo crece; logs muestran timeouts a MX destinatario en puerto 25

Causa raíz: 25 saliente bloqueado; Postfix intentando entrega direct-to-MX.

Solución: Configurar relayhost a un smart host autenticado en 587/465; exigir TLS; vaciar la cola al final.

2) Síntoma: “SASL authentication failed” o “535 Authentication credentials invalid”

Causa raíz: Usuario/contraseña incorrectos, puerto equivocado, o el proveedor requiere contraseña específica de app.

Solución: Verifica el formato de credenciales en /etc/postfix/sasl_passwd, vuelve a ejecutar postmap, confirma que usas el endpoint de submission del proveedor y los requisitos TLS.

3) Síntoma: mensajes aceptados por el relé, pero van a spam (o no se ven)

Causa raíz: SPF o DKIM faltantes/incorrectos, From mal alineado, o envío desde un dominio sin reputación.

Solución: Publica SPF incluyendo al relé; habilita firmado DKIM; añade DMARC; asegúrate que el From se alinea con el dominio firmado.

4) Síntoma: timeouts intermitentes; logs muestran direcciones IPv6 fallando

Causa raíz: Egress/ruteo IPv6 roto, pero el sistema prefiere a veces registros AAAA.

Solución: Arregla la ruta IPv6 o configura temporalmente inet_protocols = ipv4 como mitigación.

5) Síntoma: fallos de handshake TLS con STARTTLS

Causa raíz: Proxy de inspección TLS, bundle de CA faltante, o proveedor que exige SNI/TLS moderno.

Solución: Valida con openssl s_client; actualiza certificados CA; usa puerto 465 si STARTTLS se ve interferido; asegúrate que -servername funciona.

6) Síntoma: “Relay access denied” o “unauthorized sender”

Causa raíz: El proveedor exige verificar el envelope sender o el dominio From, o estás enviando desde un dominio no aprobado.

Solución: Verifica el dominio emisor en el proveedor; alinea el From; configura myorigin/myhostname sensatamente; evita direcciones From aleatorias.

7) Síntoma: puedes enviar desde el host, pero la aplicación no

Causa raíz: La app usa sus propias configuraciones SMTP (direct-to-MX, puerto equivocado), o políticas de red en contenedores bloquean el egress.

Solución: Estandariza: o la app envía a Postfix local, o la app envía directamente al relé en 587/465. No mezcles en silencio.

8) Síntoma: alta latencia, duplicados ocasionales

Causa raíz: Lógica de reintentos sin idempotencia; reutilización de conexión SMTP fallida; falta de cola.

Solución: Pone el envío de correo detrás de una cola; usa IDs de mensaje y claves de deduplicación; limita concurrencia y reintentos.

Listas de verificación / plan paso a paso

Plan paso a paso: de “bloqueado” a “envío fiable”

  1. Confirma el bloqueo: prueba TCP a 25/587/465 desde el host que envía.
  2. Elige un modelo de envío: submission SMTP (587/465) a un relé, o API por HTTPS.
  3. Detén la entrega direct-to-MX: configura relayhost de Postfix o el host SMTP de la app.
  4. Exige TLS: STARTTLS en 587 o TLS implícito en 465.
  5. Habilita auth: credenciales SASL o clave API.
  6. Protege: escucha solo en loopback para Postfix; permisos en archivos de credenciales; cuentas con mínimo privilegio.
  7. Envía una prueba: vigila logs para status=sent y un ID de cola del proveedor.
  8. Arregla autenticación DNS: SPF, DKIM, DMARC alineados con el dominio From.
  9. Implementa manejo de rebotes/quejas: buzón o webhook; alerta ante picos.
  10. Operacionaliza: monitoriza profundidad de cola, códigos de error, diferimientos del proveedor y latencia de entrega.

Checklist on-call: cuando los correos vuelvan a fallar

  • ¿Es alcanzable el relé en 587/465 desde los hosts afectados?
  • ¿Siguen válidas las credenciales (rotadas? expiradas?)
  • ¿El proveedor devuelve diferimientos 4xx (límite de tasa) o rechazos 5xx (política)?
  • ¿La resolución DNS está sana para el endpoint del relé y tus registros de dominio?
  • ¿Algo cambió: firewall, proxy de egress, bundle CA, sincronización horaria?

Checklist de seguridad: evita convertir el correo en un incidente

  • Almacena credenciales SMTP en un gestor de secretos; renderízalas en tiempo de ejecución; rótalas regularmente.
  • No permitas SMTP entrante desde Internet a menos que intentes operar un MTA.
  • Usa subdominios dedicados para distintos flujos de correo (transaccional vs marketing) cuando sea posible.
  • Configura alertas sensatas: un pico repentino en volumen enviado puede indicar credenciales comprometidas.

Hechos interesantes y contexto histórico

  • SMTP es anterior a Internet comercial: fue estandarizado a principios de los años 80, cuando la confianza entre hosts se asumía más que se verificaba.
  • El puerto 587 existe por una razón: es el puerto de submission pensado para que clientes envíen correo a un MSA (Mail Submission Agent), normalmente con autenticación.
  • El puerto 465 tuvo una historia rara: se usó temprano para TLS implícito, luego fue deprecado y finalmente “regresó” porque funciona y los clientes lo soportan.
  • El bloqueo del puerto 25 se normalizó con el broadband: a medida que las máquinas domésticas se infectaron y el spam explotó, los ISP empezaron a bloquear 25 saliente desde redes residenciales.
  • Los proveedores en la nube bloquean por defecto para proteger reputación IP: un único subnet abusado puede envenenar la entregabilidad de miles de inquilinos legítimos.
  • SPF nació por dolor operativo: surgió en los 2000 para reducir dominios remitentes forjados, pero solo autentica la ruta de envelope, no la integridad del mensaje.
  • La idea central de DKIM es responsabilidad criptográfica: un dominio firma el correo para que los receptores lo verifiquen, desplazando la confianza solo de la reputación de IP.
  • DMARC añadió política y reporting: indica a los receptores qué hacer cuando falla la autenticación y aporta bucles de retroalimentación por informes agregados.
  • El correo sigue siendo uno de los últimos protocolos federados globales: es un sistema abierto donde cualquiera puede ejecutar un servidor—genial para resiliencia, duro para el abuso.

Preguntas frecuentes

1) ¿Por qué está bloqueado el puerto 25 en mi VM?

Normalmente porque tu proveedor lo bloquea saliente por defecto para prevenir spam y proteger la reputación de su rango IP.
A veces es tu propio firewall o política de egress, pero en la nube suele aplicarse arriba en la cadena.

2) ¿Puedo solicitar que desbloqueen el puerto 25?

A veces sí. Pero seguirás heredando trabajo de entregabilidad: calentamiento de IP, reverse DNS, manejo de abusos, monitorización de listas negras.
Si solo necesitas correo transaccional, usar un relé en 587/465 suele ser la mejor decisión de negocio.

3) ¿Cuál es la diferencia entre el puerto 25 y el 587?

El puerto 25 es tradicionalmente para entrega MTA a MTA. El puerto 587 es para submission autenticada desde clientes/apps a un relé (MSA),
típicamente con STARTTLS y credenciales.

4) ¿Debería usar 465 o 587?

Por defecto usa 587 con STARTTLS. Usa 465 si tu entorno rompe STARTTLS o tu proveedor recomienda 465.
Lo clave es: usa TLS y autenticación en cualquiera de los dos casos.

5) Mi relé acepta correo, pero Gmail lo pone en spam. ¿Sigue siendo el puerto 25 el problema?

No. Eso es entregabilidad: SPF/DKIM/DMARC faltantes o mal alineados, dominio remitente nuevo sin reputación, problemas de contenido o altas tasas de rebote/queja.
El puerto 25 es transporte; la colocación en spam es reputación y autenticación.

6) ¿Es seguro almacenar credenciales SMTP en el servidor?

Puede serlo, si las tratas como cualquier otro secreto: mínimo privilegio, permisos estrictos, sin logging y rotación regular.
Prefiere gestores de secretos y credenciales de corta duración cuando estén disponibles.

7) ¿Necesito Postfix? ¿Mi app puede enviar directamente al relé?

Puedes hacer cualquiera de las dos. Postfix es útil como buffer local y punto de políticas (colas, reintentos, logs estandarizados).
Envío directo app-a-relé puede ser suficiente para sistemas simples—solo asegúrate de implementar reintentos sensatos y timeouts.

8) ¿Y si SMTP saliente está bloqueado en todos los puertos?

Usa una API de correo por HTTPS, o enruta el correo a través de un gateway interno que tenga egress permitido.
También verifica si tu red requiere un proxy explícito para tráfico saliente a Internet.

9) ¿Cómo sé si el problema es DNS?

Si ves errores de “host not found”, fallos intermitentes hacia distintos destinos, o tus consultas SPF/DKIM/DMARC fallan,
probablemente tengas problemas de resolución DNS. Prueba con dig, verifica la configuración del resolver y busca sorpresas de split-horizon.

10) ¿Puedo ejecutar mi propio servidor de correo y evitar relés?

Puedes, y mucha gente aún lo hace, pero es un compromiso operativo. Necesitas reputación IP estable, reverse DNS correcto, manejo de abusos,
monitorización y ajuste constante. Si el correo no es tu producto, no lo conviertas en tu hobby.

Conclusión: próximos pasos que no te despertarán a las 3 a. m.

Cuando el puerto 25 está bloqueado, la decisión correcta no es ponerse ingenioso. La decisión correcta es dejar de hacer entrega direct-to-MX desde servidores de aplicación.
Usa submission autenticada en 587/465, o una API de correo, y deja que un relé adecuado maneje el lado público y enmarañado de SMTP.

Pasos prácticos siguientes:

  1. Ejecuta las pruebas de conectividad para confirmar dónde está el bloqueo (25 vs 587/465).
  2. Elige un relé o enfoque API y estandarízalo entre entornos.
  3. Configura Postfix (o tu app) para enviar solo a ese relé con TLS + auth.
  4. Publica y verifica la alineación SPF/DKIM/DMARC para el dominio From.
  5. Añade monitorización: profundidad de cola, diferimientos del relé, tasas de rebote/queja.

El correo es un problema de fiabilidad disfrazado de comunicación. Trátalo como infraestructura de producción y se comportará.

← Anterior
ZFS para respaldos: instantáneas y envío/recepción sin lágrimas
Siguiente →
Por qué 640×480 se sintió eterno: estándares que no sueltan

Deja un comentario