SPF con demasiadas consultas DNS: corregir el permerror de 10
Por qué SPF devuelve permerror tras 10 consultas DNS, qué mecanismos cuentan, cómo contar su registro a mano y las soluciones que duran más que el aplanado.
Publicado: · 8 min de lectura
Un registro SPF puede provocar la evaluación de como máximo diez términos que consultan el DNS por cada comprobación. Cuentan include, a, mx, exists, redirect y ptr, y también cuenta todo lo que hay dentro de los include anidados. ip4, ip6 y all no cuestan nada. La undécima consulta termina la evaluación con permerror, y un permerror no es un pass: a efectos de DMARC, SPF sencillamente no ha pasado. La solución duradera es tener menos servicios en el registro, no esconderlos con más ingenio.
La regla procede del RFC 7208, sección 4.6.4.
Qué cuenta y qué no
| Término | ¿Cuenta para las 10? | Nota |
|---|---|---|
include: |
Sí | Más cada término que cuente dentro del registro incluido, de forma recursiva |
a |
Sí | También a:host.example.com |
mx |
Sí | Tiene además un límite propio, véase más abajo |
exists: |
Sí | Se usa sobre todo con macros |
redirect= |
Sí | Es un modificador, pero desencadena una consulta |
ptr |
Sí | Desaconsejado por el propio RFC; elimínelo |
ip4:, ip6: |
No | Direcciones literales, no hace falta DNS |
all |
No | |
exp= |
No | Solo se consulta para construir un texto explicativo tras un fail |
El límite se aplica a una evaluación SPF en su conjunto. La descarga inicial de su propio registro TXT no se cuenta; todo lo que ese registro desencadena después, sí.
Dos límites más en la misma sección
- Expansión de
mxyptr. Evaluar un mecanismomxno debe dar lugar a más de diez consultas de dirección para los nombres MX que devuelve (el mismo tope se aplica a los nombres encontrados porptr). Un dominio con más de diez hosts MX produce permerror por esta puerta aunque el recuento total de términos sea bajo. - Consultas vacías. Una consulta que devuelve NXDOMAIN o una respuesta vacía es una "consulta vacía" (void lookup). El RFC dice que los receptores DEBERÍAN permitir como máximo dos por evaluación y devolver permerror a partir de ahí. Dos include muertos que quedaron de servicios cancelados pueden ser suficientes.
Y un clásico que no va de contar
Dos registros TXT que empiezan por v=spf1 en el mismo nombre también son un permerror. Ocurre cuando la guía de un proveedor nuevo dice "añada este registro SPF" y alguien hace exactamente eso. Fusione los mecanismos en un solo registro.
Por qué los fallos parecen intermitentes
Permerror significa "este registro no se puede interpretar". Lo que hace un receptor con él es política local: algunos lo tratan como un fail, otros como neutral. DMARC solo pregunta si SPF produjo un pass alineado, y un permerror no es un pass. Si su correo lleva además una firma DKIM alineada, DMARC sigue pasando y nadie se da cuenta del registro SPF roto durante meses. Hasta que un mensaje sin DKIM (un servidor de aplicaciones olvidado, un escáner) empieza a rebotar en un proveedor y a llegar en otro.
El orden de los mecanismos añade confusión. SPF evalúa de izquierda a derecha y se detiene en la primera coincidencia. Un remitente que coincide con su segundo mecanismo nunca llega a la undécima consulta; un remitente listado al final del registro, sí. Así que el mismo registro puede pasar para su proveedor de buzones y dar permerror para su herramienta de facturación.
Cuente su registro a mano
Empiece por el propio registro:
$ dig +short TXT example.com | grep spf1
"v=spf1 mx a include:_spf.mailprovider.example include:spf.newsletter.example include:spf.crm.example include:spf.helpdesk.example ip4:192.0.2.10 -all"
Después siga cada include, y cada include dentro de esos:
$ dig +short TXT _spf.mailprovider.example
"v=spf1 include:_netblocks1.mailprovider.example include:_netblocks2.mailprovider.example include:_netblocks3.mailprovider.example ~all"
$ dig +short TXT _netblocks1.mailprovider.example
"v=spf1 ip4:198.51.100.0/24 ip6:2001:db8:10::/48 ~all"
Anote una línea por cada término que cuente:
Término en example.com |
Coste propio | Coste anidado | Subtotal |
|---|---|---|---|
mx |
1 | 0 | 1 |
a |
1 | 0 | 1 |
include:_spf.mailprovider.example |
1 | 3 include | 4 |
include:spf.newsletter.example |
1 | 1 include | 2 |
include:spf.crm.example |
1 | 1 include + 1 a |
3 |
include:spf.helpdesk.example |
1 | 0 | 1 |
ip4:192.0.2.10 |
0 | 0 | 0 |
| Total | 12 |
Doce: permerror para cualquier remitente que no coincida pronto. Observe que el all dentro de un registro incluido no termina su evaluación; un include solo importa cuando produce un pass.
Soluciones, en el orden en que debería probarlas
1. Elimine lo que ya no usa
La mayoría de los registros que superan el límite contienen al menos un servicio cancelado hace años. Cada proveedor eliminado libera normalmente entre una y cuatro consultas. También cierra un agujero: un include autoriza las direcciones de envío de la plataforma para su dominio, y en infraestructura compartida esas direcciones también transportan el correo de otros clientes.
2. Sustituya a y mx por direcciones
mx y a son valores por defecto cómodos que muchos generadores añaden. Si su servidor web no envía correo, a es inútil. Si los hosts de sus registros MX no envían su correo saliente (lo habitual con correo alojado, donde el include del proveedor cubre el envío), mx también es inútil. Donde un servidor sí envía y su dirección es estable, escriba ip4:192.0.2.10 o ip6:2001:db8::25 en su lugar: cero consultas.
3. Compruebe si el servicio usa siquiera su dominio en el sobre
SPF comprueba el dominio del remitente del sobre (MAIL FROM, mostrado después como Return-Path), no la cabecera From que ve la gente. Muchos proveedores de servicios de correo usan ahí su propio dominio de rebotes. En ese caso el receptor consulta el registro SPF de ellos, nunca el suyo, y el include de ese servicio en su registro cuesta consultas sin hacer nada.
Abra un mensaje que el servicio haya enviado de verdad y lea las cabeceras:
Return-Path: <bounce-7f3a@bounces.newsletter.example>
From: Example Shop <news@example.com>
Return-Path no está bajo example.com, así que el include:spf.newsletter.example de su registro raíz puede desaparecer. Lo que hace que ese correo pase DMARC es una firma DKIM con d=example.com, o un return-path personalizado (paso siguiente).
4. Dé a cada servicio de envío su propio subdominio
El límite es por evaluación, y cada evaluación empieza en el dominio del sobre. Envíe los boletines desde news.example.com y el correo transaccional desde billing.example.com, y cada nombre tendrá su propio registro y su propio presupuesto de diez:
news.example.com. TXT "v=spf1 include:spf.newsletter.example -all"
billing.example.com. TXT "v=spf1 include:spf.invoicing.example -all"
La mayoría de las plataformas lo implementa como "return-path personalizado" o "dominio de rebotes personalizado": usted crea un CNAME como bounce.news.example.com que apunta al proveedor, y el registro SPF vive por completo en el lado de ellos. Con la alineación relajada (la predeterminada en DMARC), bounce.news.example.com se alinea con una dirección From en example.com. Los registros SPF no se heredan, así que un subdominio sin registro propio no tiene ninguno.
5. Apóyese en DKIM alineado
DMARC necesita un pass alineado, SPF o DKIM. Para cada servicio que pueda firmar con su dominio en d=, DKIM por sí solo basta, y además sobrevive al reenvío, cosa que SPF no hace (véase por qué el reenvío de correo rompe SPF). Eso es lo que hace seguro el paso 3.
6. Aplanado, solo con automatización
El "aplanado" (flattening) sustituye cada include por los rangos de IP a los que resuelve en este momento. El recuento de consultas baja a cero y el registro funciona hoy. El problema es mañana: los proveedores añaden y retiran rangos sin avisarle, y el día que lo hacen, parte de su correo legítimo empieza a fallar SPF con un registro que parece perfectamente válido. Si aplana, tiene que ser un proceso que vuelva a resolver los include con regularidad y republique el registro, y ese proceso hay que vigilarlo. Un registro aplanado a mano es una avería aplazada.
Los registros aplanados también se alargan. Una cadena de caracteres de un TXT admite como máximo 255 bytes; los registros más largos se dividen en varias cadenas, que los receptores concatenan sin añadir espacios, así que una división en el lugar equivocado pega dos mecanismos. Mantenga pequeña también la respuesta completa: las respuestas que superan el tamaño UDP tradicional de 512 bytes dependen de EDNS0 o de la alternativa por TCP, y el RFC aconseja quedarse por debajo.
7. Macros
Las macros SPF (exists:%{i}._spf.example.com) pueden condensar muchos remitentes en una sola consulta. Necesitan un backend DNS construido para ello y son difíciles de depurar: no son una solución de primera línea.
~all frente a -all no tiene nada que ver con todo esto: el calificador de all decide qué ocurre con los remitentes que no coinciden y no cuesta ninguna consulta en ningún caso.
Errores frecuentes
- Contar solo los include visibles en el registro de primer nivel y olvidar los anidados.
- Añadir
include:para un servicio cuyo Return-Path está en su propio dominio. - Dejar los include de servicios cancelados: cuestan consultas y, cuando el proveedor borra el nombre, consultas vacías.
- Publicar un segundo registro
v=spf1en lugar de editar el primero. - Dividir un registro largo en cadenas de 255 bytes y perder el espacio entre dos mecanismos en la unión.
Si está construyendo un registro desde cero, el generador SPF compone la sintaxis; el recuento sigue teniendo que hacerse contra los include reales.
Compruébelo con OrbitProbe
La verificación SPF de OrbitProbe consulta el registro SPF de un dominio y señala los problemas que más a menudo lo rompen: más de un registro, +all, un mecanismo all ausente y demasiadas consultas DNS. Ejecútela para el dominio raíz y después, por separado, para cada subdominio que envíe correo, porque cada nombre se evalúa por su cuenta. Una consulta DNS muestra lo que está publicado en ese momento; no puede mostrar si su correo está siendo aceptado, así que siga leyendo también sus informes DMARC. Para la visión de conjunto de cómo dependen entre sí los cuatro registros de correo, consulte MX, SPF, DKIM y DMARC explicados, y para una revisión completa de la entrega, la lista de comprobación DNS para correo que llega a spam.