La mayoría de la gente que abre las cabeceras de un correo se queda mirando el bloque Received como quien mira un jeroglífico: varias líneas aparentemente idénticas, cada una con nombres de servidor, direcciones IP y marcas de tiempo que no parecen guardar ningún orden lógico. La tentación es leer de arriba abajo, porque es lo que hacemos con todo el resto del texto. Ahí empieza el error. El bloque Received está apilado al revés: cada servidor que reenvía el mensaje añade su línea encima de las anteriores, de modo que la primera línea de la lista es el último salto y la última línea es el primero. Si lees de arriba abajo estás siguiendo la película hacia atrás.
Esta guía propone lo contrario: recorrer el bloque de abajo arriba, salto a salto, y sacar conclusiones de lo que aparece y, sobre todo, de lo que falta. Porque una traza no se interpreta solo por las líneas que contiene. Un salto con IP privada, un HELO genérico como “localhost”, una ausencia de Authentication-Results o un retraso de 40 minutos entre dos marcas de tiempo cuentan una historia muy concreta sobre relays internos, MTA mal configurados o receptores que no evaluaron SPF, DKIM ni DMARC. La tesis es simple: la cabecera Received es un registro forense, no decorativo, y casi todo lo que revela está en los detalles que pasan desapercibidos.
Al final del recorrido veremos qué tiene esto que ver con el enrutamiento real del buzón, incluido el caso del correo catch-all: un ajuste del servidor de correo que acepta cualquier mensaje dirigido a un dominio aunque la parte local no exista. La traza muestra con claridad cuándo un mensaje acabó en ese buzón comodín en lugar de rebotar con un 550 no such user, y esa diferencia importa más de lo que parece cuando se audita un dominio de correo.
Qué son las cabeceras Received y por qué se leen de abajo arriba
Cuando abres las cabeceras de un correo y ves seis u ocho líneas Received: apiladas, la tentación es leerlas de arriba abajo como quien lee un informe. Es el primer error. Cada servidor que toca el mensaje añade su propia línea encima de las anteriores, no debajo. El resultado es una pila en la que lo más reciente queda arriba y lo más antiguo, abajo. La Received inferior es la primera que se escribió: la que registró el servidor que recibió el mensaje originalmente. Esa es la que te interesa.
El mecanismo es simple y explica todo lo demás. Un MTA recibe el correo, inserta su línea Received al principio del bloque y lo entrega al siguiente salto. Ese siguiente salto hace lo mismo: inserta la suya por delante. Así, la cadena crece hacia arriba y el orden cronológico real es el inverso al que ves en pantalla. Si lees de arriba abajo estás leyendo la historia al revés, empezando por el último servidor que tocó el mensaje y terminando por el primero.
Veamos una traza realista con tres saltos. Los datos son inventados pero la estructura es exactamente la que encontrarás:
Received: from mx.destino.example (mx.destino.example [198.51.100.20])
by inbox.destino.example with ESMTPS id 4Xy2ab
for cliente@destino.example; Tue, 14 May 2024 10:02:41 +0200
Received: from relay.proveedor.example (relay.proveedor.example [203.0.113.5])
by mx.destino.example with ESMTP id 7Kp9cd
for cliente@destino.example; Tue, 14 May 2024 10:02:39 +0200
Received: from portatil.local (dsl-84-120-9-33.proveedor.example [84.120.9.33])
by relay.proveedor.example with ESMTPSA id 1Mn4ef
for cliente@destino.example; Tue, 14 May 2024 10:02:31 +0200
La línea de abajo es la original: el portátil del remitente conectó con el relay de su proveedor a las 10:02:31 desde la IP 84.120.9.33. El relay entregó a mx.destino.example dos segundos después. El servidor de destino lo pasó al buzón final a las 10:02:41. Si lees de arriba abajo verás primero la entrega final y acabarás en el origen, que es justo el orden que no quieres. Lee de abajo arriba y la secuencia tiene sentido: origen, tránsito, destino.
Cada línea tiene la misma anatomía: un from (el nombre con el que el emisor se anunció en el saludo HELO o EHLO), entre corchetes la IP real de la conexión, un by (el servidor que recibe), el protocolo empleado y la marca de tiempo del salto. El from entre paréntesis y la IP entre corchetes no siempre coinciden, y esa discrepancia es precisamente lo que conviene mirar. Los timestamps van en hora local del servidor con su desfase respecto a UTC, así que dos saltos pueden parecer desordenados si cruzan husos horarios.
Un detalle que despista: el campo for que aparece en muchas líneas indica el destinatario en el momento de ese salto. Puede ser tu dirección, una dirección del dominio o un buzón catch-all. Guarda ese dato, porque volveremos a él cuando hablemos de enrutamiento. Por ahora retén lo esencial: la Received de abajo manda, y el bloque se lee al revés de como se muestra.
Cómo reconstruir la ruta de un correo salto a salto
Leer cada salto: de, por, con, para y cuándo
Cada línea Received tiene la misma estructura: from (el nombre que el emisor dijo tener, su HELO), by (el servidor que la inserta), normalmente with (protocolo: ESMTP, ESMTPS, ESMTPSA) y for (destinatario, si el servidor lo revela). El timestamp final es el del reloj del servidor que escribe la línea, no una hora universal fiable. Empieza por la Received más baja, la que insertó el primer MTA que tocó el mensaje, y sube.
Un ejemplo típico de una traza real:
| Salto | from / by | IP | Hora | Retraso |
|---|---|---|---|---|
| 1 (abajo) | cliente / mx.dominio-emisor.com | 200.45.12.8 | 10:02:14 +0200 | – |
| 2 | mx.dominio-emisor.com / mx.destino.es | 200.45.12.8 | 10:02:15 +0200 | 1 s |
| 3 | mx.destino.es / antispam.destino.es | 10.0.4.21 | 10:02:41 +0200 | 26 s |
| 4 (arriba) | antispam.destino.es / buzon.destino.es | 10.0.5.9 | 10:07:03 +0200 | 4 min 22 s |
Restar timestamps consecutivos te da el tiempo que cada MTA retuvo el mensaje. Un salto de uno o dos segundos es normal; cuatro minutos en un filtro antispam es plausible; seis horas entre dos servidores del mismo dominio es una cola atascada o un reintento. Los relojes pueden estar desincronizados, así que un retraso negativo (un salto que “llega antes” que el anterior) no significa manipulación: significa NTP mal configurado en uno de los dos hosts.
Las anomalías que de verdad importan son otras. Si el from de un salto no coincide con el HELO que el servidor anterior declaró, hay suplantación o un relay mal identificado. Si la IP pública del salto 1 no pertenece al rango del dominio emisor y ese dominio publica SPF estricto, la traza cuenta una historia distinta a la que cuenta el SPF. Y si el número de saltos supera los cinco o seis habituales, o aparece un salto con un dominio que no pinta nada en la ruta, conviene revisar si hay un reenvío de correo o un alias que rompió la autenticación por el camino.
Cuando un usuario dice que “no le llega un correo”, la ruta reconstruida responde a tres preguntas: si el mensaje llegó al dominio, por qué servidor entró y cuánto tardó en cada tramo. Si la traza termina en un servidor que no es el buzón final, el problema está en el enrutamiento interno, no en el emisor. Fíjate también en el campo for: si la dirección que aparece ahí no coincide con la del destinatario que reclama el mensaje, ese buzón catch-all o ese alias puede estar recogiendo correo que iba dirigido a otra parte.
IP privada y HELO genérico: señales de relay interno o servidor mal configurado
Qué mirar en cada salto: IP privada, HELO y nombre de host
En una Received hay cuatro datos que delatan casi todo: la IP del emisor, el HELO/EHLO que anunció, el nombre de host que el receptor resolvió y el timestamp. Cuando en una Received aparece algo como from [192.168.1.20] (mail.interno.local [192.168.1.20]) by mx.dominio.com, no estás viendo un salto de internet: estás viendo un relay dentro de la red del emisor. Las IP de los rangos 10.0.0.0/8, 172.16.0.0/12 y 192.168.0.0/16 no son enrutables en internet, así que ese salto solo pudo producirse en la infraestructura interna del que envía o del que recibe.
Un HELO genérico refuerza la sospecha. Valores como localhost, localhost.localdomain, [127.0.0.1], windows o una IP literal entre corchetes indican un MTA que no se ha configurado con su nombre FQDN real. Los servidores serios anuncian algo como mail.empresa.com y ese nombre resuelve hacia la IP de origen. Si el HELO no coincide ni con la IP ni con el PTR, el receptor lo anotará en la traza y probablemente lo puntuará en spam.
La clave para distinguir un salto legítimo de uno problemático es la coherencia. Un relay interno bien montado produce una Received con IP privada y HELO correcto (el nombre del host interno), seguida de una Received con IP pública y HELO del mismo host o del gateway. https://allmail.one/es/what-is-catch-all-email/ aporta más contexto sobre este asunto. Un MTA mal configurado produce saltos donde el HELO no resuelve, la IP privada aparece mezclada con IPs públicas sin orden lógico, o el timestamp retrocede. Fíjate también en el retraso entre saltos: un salto interno con 0 segundos es normal; un salto con 40 minutos entre dos Received consecutivas apunta a cola atascada o a un relay intermedio que reintenta.
| Patrón en Received | Interpretación |
|---|---|
| IP privada + HELO = FQDN interno coherente | Relay interno legítimo |
| IP privada + HELO localhost o IP literal | MTA interno mal configurado |
| IP pública + HELO que no resuelve | Servidor de correo sin DNS inverso o suplantación |
| IP pública + HELO = dominio ajeno al PTR | Posible relay abierto o spam bot |
Ojo con un detalle que se pasa por alto: un HELO genérico en el primer salto (el más bajo) suele ser el cliente de correo del usuario final hablando con su propio servidor. Eso no es grave si el siguiente salto es el MTA del proveedor con una Received limpia. Lo preocupante es que el HELO genérico aparezca en un salto intermedio, ya en tránsito público: significa que ese MTA está actuando como relay sin presentarse correctamente, y su correo saliente acabará en cuarentena con más frecuencia de la que su administrador cree.
Authentication-Results ausente: cuando el receptor no evaluó la autenticación
Hay una creencia muy extendida según la cual, si un mensaje llega a la bandeja de entrada, alguien en el camino validó SPF, DKIM y DMARC. La cabecera Authentication-Results es la prueba documental de que eso ocurrió, y su ausencia dice justo lo contrario: el receptor no evaluó la autenticación o no dejó constancia de ello. Ese hueco cambia por completo la fiabilidad de la traza, porque convierte el resto de la cadena en una narración sin veredicto.
Conviene precisar qué registra esa cabecera. La añade el servidor que recibe y evalúa, normalmente el MTA frontera o el motor antispam, y contiene el identificador de quien valida, el resultado de SPF respecto a la IP de conexión, el de DKIM por firma y el de DMARC alineado con el dominio del From. Si aparece algo como Authentication-Results: mx.receptor.example; spf=pass smtp.mailfrom=ejemplo.com; dkim=pass header.d=ejemplo.com; dmarc=pass, tienes datos verificables. Si no aparece nada, no tienes ni un pass ni un fail: tienes silencio.
El silencio admite varias causas y ninguna es buena para el análisis:
- El receptor no implementa autenticación (raro en grandes proveedores, común en servidores pequeños o mal mantenidos).
- El mensaje se entregó internamente y nunca pasó por el filtro que evalúa SPF, DKIM y DMARC.
- El receptor evalúa pero no inserta la cabecera, o la elimina al reenviar.
- Un salto intermedio la borró, algo que también ocurre con otras cabeceras de trazabilidad.
El impacto práctico es directo. Sin Authentication-Results no puedes afirmar que el remitente esté autorizado, aunque la Received más baja muestre una IP coherente con los registros MX del dominio. Tampoco puedes descartar un spoofing: la parte local del From puede ser cualquiera y el dominio de correo puede no tener relación con la IP que conectó. La traza te cuenta el recorrido, no la legitimidad. Mezclar ambas cosas es el error más habitual al leer cabeceras.
Hay un matiz que suele pasarse por alto: la autenticación de correo protege el correo entrante en el punto donde se evalúa, pero no viaja firmada de extremo a extremo. Cada receptor decide si valida y si documenta. Por eso, cuando analizas un reenvío o un alias de correo, es normal encontrar Received nuevas sin Authentication-Results asociada, porque el salto que reenvía no es el que autentica. La regla catch-all del receptor se aplica después de que falla la búsqueda normal de dirección, y ese proceso de entrega interna tampoco genera evaluación SPF ni DKIM.
En la práctica, trato la ausencia de esta cabecera como una etiqueta de “no verificado” y ajusto el peso del resto de evidencias. Miro la IP del primer salto, comparo con los registros MX del dominio emisor, reviso el HELO y el timestamp, y si nada cuadra, asumo que la traza solo prueba el transporte. Cuando el mensaje es sospechoso y falta Authentication-Results, la conclusión honesta es que no hay datos para validar la autenticidad, no que el correo sea legítimo.
Del análisis de cabeceras al buzón catch-all: qué revela la traza sobre el enrutamiento
Un buzón catch-all (comodín de correo) acepta cualquier mensaje enviado a un dominio, aunque la parte local no exista. Para verlo en la práctica, basta con leer una traza. Cuando el servidor de correo no encuentra coincidencia en la tabla de cuentas, responde con un 550 no such user… salvo que exista una regla catch-all, que se aplica después de que falla la búsqueda normal de dirección. En ese momento el mensaje no rebota: se entrega a la cuenta comodín.
La cabecera Received no dice “esto es un catch-all”, pero deja pistas claras. Si envías una prueba a una dirección inventada, por ejemplo q7x9-inexistente@tudominio.com, y el mensaje aparece en la bandeja del comodín, la traza mostrará un salto final hacia el buzón configurado, no un rechazo. Compara esa Received con la de un mensaje enviado a una cuenta real: la ruta externa suele ser idéntica hasta el último MTA; la diferencia está en el destino interno que registra el servidor.
Hay un detalle que desmonta el mito más extendido: el catch-all no se activa en el DNS. El DNS no tiene ningún tipo de registro para activar catch-all; los registros MX solo indican qué hosts aceptan correo para el dominio, con su prioridad correspondiente. El catch-all es un ajuste en el servidor de correo o en el panel de hosting, no una entrada de zona. Si alguien te dice que “hay que añadir un MX comodín”, desconfía.
Al configurarlo, revisa estos puntos en la traza y en el panel:
- El salto final debe apuntar al buzón catch-all, no a una cuenta concreta. Si ves un reenvío a otra dirección, tienes un alias, no un catch-all.
- El buzón catch-all se recoge con un solo login POP3 o IMAP. Varias direcciones distintas comparten la misma bandeja, y eso complica separar destinatarios reales de ruido.
- SPF, DKIM y DMARC rigen el correo saliente del dominio, no el enrutamiento interno. Un catch-all no exime de publicar esas políticas; si respondes desde el comodín, la autenticación debe cuadrar.
- Comprueba los timestamps entre el penúltimo y el último salto: un retraso grande suele indicar entrega diferida o cola, no un fallo del comodín.
Conviene distinguir el correo catch-all de un alias, de un reenvío y del correo desechable. El alias y el reenvío exigen una dirección origen concreta; el catch-all captura todo lo que no coincide. El correo desechable es otra cosa: servicios externos que generan buzones temporales, sin relación con tu dominio ni con tus MX.
El precio de tenerlo activo es el ruido. Los escáneres y los bots prueban direcciones aleatorias contra tu dominio cada día, y todo eso acaba en la misma cuenta. Antes de activarlo, decide si vas a filtrar con reglas por parte local o si prefieres desactivarlo y dejar que el servidor devuelva el 550. La traza te dirá exactamente qué está entrando y por dónde; el panel, si merece la pena seguir aceptándolo.
La próxima vez que recibas un correo sospechoso, no te quedes mirando la primera línea del bloque Received. Copia las cabeceras completas, pégalas en un editor de texto y empieza por la última Received del final. Ahí tienes el primer servidor que tocó el mensaje, con su IP, su nombre y la hora exacta. Compara ese timestamp con los siguientes saltos: un retraso de más de 60 segundos entre dos Received consecutivos merece una explicación, y un salto con IP privada o HELO genérico te está diciendo que hay un relay interno o un MTA mal configurado. Si el bloque no incluye Authentication-Results, asume que el receptor no evaluó SPF, DKIM ni DMARC y que la traza no te sirve para certificar autenticidad, solo para reconstruir la ruta.
Haz la prueba con tu propio dominio: envía un mensaje a una dirección que no exista y revisa qué responde el servidor. Si ves un 550 no such user, no hay catch-all activo. Si el mensaje entra igualmente, tienes un buzón catch-all recogiendo todo lo que llega a cualquier parte local del dominio. A partir de ahí, la traza te muestra qué registro MX con mayor prioridad aceptó el correo y si el reenvío hacia tu login POP3 o IMAP añadió saltos extra. Ese detalle importa: un catch-all mal planteado reenvía también spam dirigido a direcciones inventadas, y lo verás reflejado en las Received como picos de tráfico hacia tu buzón. Configurar correo catch-all sin revisar la traza es abrir la puerta sin saber quién entra. Antes de activarlo en el panel de hosting, comprueba qué pasa con las direcciones no coincidentes, decide si quieres un alias o un reenvío real, y documenta los registros MX con su prioridad. Diez minutos de lectura de cabeceras te ahorran meses de correo basura en la bandeja principal.