Fallos de autenticación SASL en Postfix: trampas de configuración y orden de solución

¿Te fue útil?

Despliegas un servidor de correo que “básicamente funciona”, hasta que los usuarios pulsan Enviar y su cliente se encuentra de bruces con 535 5.7.8 Authentication credentials invalid. O peor: falla de forma intermitente, solo en algunos clientes, solo después de una actualización, solo los martes. Mientras tanto tus registros parecen una nota de rescate escrita por un comité.

Los fallos SASL en Postfix rara vez son “una sola opción mal”. Suelen ser una cadena: el estado de TLS afecta a si se anuncia AUTH, los permisos del socket deciden si Postfix puede preguntar a un demonio de autenticación, y una única prueba engañosa puede convencerte de que la capa equivocada está rota. Arreglar esto rápido es cuestión de orden: valida el listener, luego TLS, luego la tubería SASL, luego la autenticación de usuario y por último la política. Siempre en ese orden.

Guía rápida de diagnóstico

Esta es la guía “estoy de guardia y la cafeína no es un sistema de monitorización”. El objetivo es localizar el cuello de botella: red/listener, bloqueo por TLS, tubería SASL, backend de credenciales o restricciones de política.

Primero: confirma que estás probando el servicio y puerto correctos

  • Comprobar: ¿Estás autenticando en submission (587) o smtps (465), no en el puerto 25?
  • Por qué: Muchas implementaciones desactivan INTENCIONALMENTE AUTH en el puerto 25 para evitar convertir el MX en un objetivo de fuerza bruta.
  • Decidir: Si usas 25, para. Cambia el cliente a 587/465 y vuelve a probar.

Segundo: verifica que AUTH se anuncie bajo el mismo estado TLS que usa tu cliente

  • Comprobar: ¿El servidor anuncia AUTH solo después de STARTTLS? ¿O nunca?
  • Por qué: smtpd_tls_auth_only = yes es común y correcto, pero confunde pruebas que no hacen STARTTLS.
  • Decidir: Si AUTH aparece solo después de STARTTLS, asegúrate de que los clientes estén configurados para STARTTLS o TLS implícito en 465.

Tercero: identifica qué proveedor SASL está en juego (Dovecot vs Cyrus vs saslauthd)

  • Comprobar: ¿Postfix está configurado con smtpd_sasl_type = dovecot o cyrus?
  • Por qué: Los mensajes de error se solapan, pero la tubería es diferente: Dovecot usa un socket UNIX; Cyrus suele usar saslauthd o su propia base.
  • Decidir: Si está configurado el proveedor equivocado, arréglalo antes de tocar contraseñas, PAM, LDAP o cualquier cosa “de usuario”.

Cuarto: demuestra que Postfix puede alcanzar el socket/demonio de autenticación

  • Comprobar: Ruta del socket, permisos, SELinux/AppArmor, problemas de chroot.
  • Decidir: Si Postfix no puede conectarse, no pierdas tiempo con credenciales. Arregla la conectividad y los permisos primero.

Quinto: valida el backend de credenciales directamente

  • Comprobar: ¿Puede Dovecot autenticar al usuario? ¿Puede saslauthd autenticar vía PAM/LDAP?
  • Decidir: Si el backend falla, arréglalo; Postfix solo es el mensajero (y se culpa de todo).

Sexto: confirma que la política no rechaza “autenticado pero no permitido”

  • Comprobar: smtpd_sender_login_maps, restricciones de destinatario, restricciones de retransmisión, políticas milter SPF/DMARC.
  • Decidir: Si AUTH tiene éxito pero el correo aún es rechazado, tienes un bloqueo por política, no un bloqueo de autenticación.

Modelo mental para producción: quién autentica a quién

Postfix es un servidor SMTP y gestor de colas. No pretende ser tu proveedor de identidad. Cuando habilitas SMTP AUTH, Postfix delega la autenticación a una capa SASL. Esa capa SASL a su vez delega a algo que valida credenciales: una base de datos, LDAP, PAM, SQL, userdb/passdb de Dovecot, etc.

En la práctica hay dos formas comunes:

Forma A: Postfix + Dovecot SASL (más común en Linux moderno)

  • Postfix ejecuta el servicio SMTP (submission/smtps).
  • Postfix pide a Dovecot que autentique vía un socket UNIX (el servicio auth de Dovecot).
  • Dovecot verifica las credenciales usando su passdb/userdb configurada (SQL, LDAP, passwd-file, PAM, etc.).

Modos típicos de fallo: ruta de socket incorrecta, permisos, chroot mismatched, auth de Dovecot mal configurado, desajuste de mecanismos (PLAIN/LOGIN), bloqueo por TLS, o cliente usando el puerto equivocado.

Forma B: Postfix + Cyrus SASL (+ saslauthd o auxprop)

  • Postfix carga plugins de Cyrus SASL.
  • Cyrus SASL consulta saslauthd o su propio backend auxprop.
  • saslpasswd2 o PAM/LDAP decide si las credenciales son correctas.

Modos típicos de fallo: paquetes Cyrus SASL faltantes, no mechanism available, saslauthd no en ejecución, pwcheck_method equivocado, permisos del socket incorrectos, o desajuste en el nombre del servicio.

Independientemente de la forma, SMTP AUTH plantea dos preguntas separadas:

  1. ¿Pueden cliente y servidor negociar un mecanismo AUTH? (capacidades, requisitos TLS, mecanismos soportados)
  2. ¿Puede el proveedor de autenticar validar al usuario? (corrección del backend, contraseña, estado de la cuenta)

Muchos incidentes ocurren porque los equipos saltan la pregunta 1 y empiezan a “resetear contraseñas” como si fuera un ritual.

Hechos y contexto que puedes usar

  • SMTP AUTH no formaba parte del SMTP original. Llegó después como una extensión (ESMTP), porque Internet temprano asumía confianza dentro de redes.
  • El puerto 587 (submission) existe por una razón. Separa el envío de correo por usuarios (con AUTH) del relay MTA-a-MTA en el puerto 25.
  • El puerto 465 volvió a usarse. Fue “depreciado” en su día pero ahora se usa ampliamente para TLS implícito (“smtps”), porque a los clientes les resulta simple.
  • Postfix mantiene la autenticación externa a propósito. Es una elección de diseño: menos partes críticas de seguridad dentro de Postfix, actualizaciones más sencillas y separación de responsabilidades.
  • SASL es un framework, no un único demonio. Por eso “SASL está roto” rara vez es accionable; hay que nombrar el proveedor y el backend.
  • El anuncio de AUTH depende de TLS y restricciones. Con ajustes comunes, el servidor puede ocultar AUTH hasta que ocurra STARTTLS, haciendo que pruebas ingenuas mientan.
  • En Dovecot, el socket de auth es un servicio con permisos. Si el socket existe pero Postfix no puede acceder, obtendrás fallos que parecen “contraseña incorrecta”.
  • El chroot sigue importando en 2026. Postfix puede ejecutar algunos servicios en chroot; una ruta de socket fuera del chroot se convierte en “no encontrado” aun cuando exista.
  • Un “desajuste de cifrado TLS anónimo” puede manifestarse como “AUTH no ofrecido”. Si falla la negociación TLS, puede que nunca llegues al punto donde se anuncia AUTH.

Una cita, porque la gente de fiabilidad ya gritaba sobre esto antes de que fuera tendencia:

“La esperanza no es una estrategia.” — General Gordon R. Sullivan

Orden de solución (haz esto, no intuiciones)

Si cambias ajustes al azar, lo “arreglarás” tres veces y seguirás sin saber por qué falló. Usa un orden que aísle capas y te impida perseguir fantasmas.

0) Congela la escena

Antes de editar nada, captura: configuraciones actuales, versiones de paquetes y logs representativos. Los bugs de SMTP AUTH adoran desaparecer bajo el ruido de reconfiguración.

1) Identifica el punto de entrada exacto: servicio, puerto y nombre de host

¿El cliente está golpeando el host previsto (frontend de submission vs MX)? ¿Está en el puerto correcto? ¿Hay un balanceador que termina STARTTLS? Te sorprendería la frecuencia con la que “AUTH falla” es en realidad “conectaste al pool de MX que no anuncia AUTH por política”.

2) Confirma la negociación de capacidades (EHLO → STARTTLS → EHLO → AUTH)

No depures SASL antes de saber si AUTH se ofrece siquiera. Si AUTH no se ofrece, suele ser una de:

  • Servicio/puerto equivocado
  • smtpd_sasl_auth_enable no habilitado para ese servicio
  • TLS requerido (smtpd_tls_auth_only) pero no usas STARTTLS
  • Restricciones que ocultan AUTH
  • Proveedor SASL mal configurado impide listar mecanismos

3) Asegura la corrección de TLS

Arregla TLS antes que la autenticación. Si TLS falla, algunos clientes ni siquiera intentarán AUTH. Otros lo intentarán y filtrarán credenciales si permites AUTH en claro por accidente. No quieres eso en tu conciencia ni en tu log de auditoría.

4) Confirma el cableado del proveedor SASL (Dovecot o Cyrus)

Aquí es donde la mayoría de migraciones “funcionaba en el servidor antiguo” se rompen. Postfix necesita el tipo SASL correcto y sockets/parametros correctos. Si usas Dovecot, trata el socket auth como un endpoint de API: ruta, permisos y protocolo deben coincidir.

5) Valida el backend de autenticación fuera de SMTP

Prueba el auth de Dovecot directamente (o saslauthd) para aislar credenciales y configuración del backend. Si el backend falla, Postfix no puede arreglarlo con pensamiento positivo.

6) Aplica la política deliberadamente después de que AUTH funcione

Una vez que AUTH tenga éxito, entonces aplica tus reglas: los usuarios autenticados pueden relayer; los no autenticados no; restricciones de remitente; límites de tasa. Si aplicas política primero, confundirás “auth falló” con “auth tuvo éxito pero no está autorizado”.

Broma corta #1: Depurar SMTP AUTH es como la fontanería: la fuga nunca está donde está el charco.

Tareas prácticas: comandos, salidas, decisiones

Estas son las tareas que realmente ejecuto en producción. Cada una incluye: comando, qué significa la salida y la decisión que tomas después. Ejecútalas en el servidor que crees que maneja submission, no “en algún sitio cercano”.

Task 1: Confirmar que Postfix está en ejecución y qué servicios están habilitados

cr0x@server:~$ systemctl status postfix --no-pager
● postfix.service - Postfix Mail Transport Agent
     Loaded: loaded (/lib/systemd/system/postfix.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2026-01-02 09:12:44 UTC; 3h 18min ago
       Docs: man:postfix(1)
   Main PID: 1221 (master)
      Tasks: 5 (limit: 18996)
     Memory: 28.4M
        CPU: 2.114s
     CGroup: /system.slice/postfix.service
             ├─1221 /usr/lib/postfix/sbin/master -w
             ├─1230 pickup -l -t unix -u
             ├─1231 qmgr -l -t unix -u
             ├─1302 smtpd -n smtp -t inet -u -c
             └─1303 tlsmgr -t unix -u

Qué significa: El master está en ejecución; hay al menos un smtpd. Pero aún no sabes si submission (587) está habilitado.

Decisión: Comprueba listeners y master.cf a continuación.

Task 2: Verificar que el servidor escucha en los puertos correctos (25/587/465)

cr0x@server:~$ sudo ss -lntp | egrep ':(25|465|587)\s'
LISTEN 0      100          0.0.0.0:25       0.0.0.0:*    users:(("master",pid=1221,fd=13))
LISTEN 0      100          0.0.0.0:587      0.0.0.0:*    users:(("master",pid=1221,fd=16))
LISTEN 0      100          0.0.0.0:465      0.0.0.0:*    users:(("master",pid=1221,fd=18))

Qué significa: Postfix está escuchando en 587 y 465. Bien. Si 587/465 faltaran, tu problema no es SASL; es habilitación del servicio o firewall.

Decisión: Si 587/465 no están escuchando, arregla master.cf y el firewall antes de tocar SASL.

Task 3: Confirmar cómo está definido submission en master.cf

cr0x@server:~$ sudo postconf -Mf | egrep '^(submission|smtps)\b'
submission inet n       -       y       -       -       smtpd
smtps     inet  n       -       y       -       -       smtpd

Qué significa: Los servicios existen. Pero puede que haya overrides (como -o smtpd_sasl_auth_enable=yes) presentes o no.

Decisión: Vuelca el bloque de servicio exacto y verifica overrides de SASL/TLS.

Task 4: Mostrar parámetros efectivos de Postfix relevantes para SASL/TLS

cr0x@server:~$ sudo postconf -n | egrep '^(smtpd_sasl|smtpd_tls|broken_sasl_auth_clients|smtpd_recipient_restrictions|smtpd_relay_restrictions|smtpd_sender_login_maps|smtpd_sasl_security_options|smtpd_sasl_path|smtpd_sasl_type)\b'
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
broken_sasl_auth_clients = yes
smtpd_relay_restrictions = permit_mynetworks,permit_sasl_authenticated,defer_unauth_destination

Qué significa: Postfix está configurado para usar Dovecot SASL vía private/auth. AUTH se ofrecerá solo después de TLS debido a smtpd_tls_auth_only=yes. El relay está permitido para usuarios autenticados.

Decisión: Tus pruebas deben usar STARTTLS (587) o TLS implícito (465). Siguiente: demuestra que AUTH se anuncia tras TLS.

Task 5: Sondear capacidades sin TLS (espera que AUTH esté oculto)

cr0x@server:~$ printf 'EHLO test\r\nQUIT\r\n' | nc -w 3 127.0.0.1 587
220 mail01.example.net ESMTP Postfix
250-mail01.example.net
250-PIPELINING
250-SIZE 10240000
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250 SMTPUTF8
221 2.0.0 Bye

Qué significa: No se anuncia AUTH. Eso es consistente con smtpd_tls_auth_only=yes.

Decisión: Prueba con STARTTLS y vuelve a hacer EHLO.

Task 6: Sondear capacidades con STARTTLS (AUTH debería aparecer ahora)

cr0x@server:~$ openssl s_client -starttls smtp -crlf -connect 127.0.0.1:587 </dev/null
CONNECTED(00000003)
depth=2 C=US O=Example CA CN=Example Root CA
verify return:1
depth=1 C=US O=Example CA CN=Example Issuing CA
verify return:1
depth=0 CN=mail01.example.net
verify return:1
---
250-mail01.example.net
250-PIPELINING
250-SIZE 10240000
250-ETRN
250-AUTH PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250 SMTPUTF8

Qué significa: STARTTLS funciona y se anuncian mecanismos AUTH. Si tu cliente dice “el servidor no soporta autenticación”, o no está usando TLS o está en el host/puerto equivocado.

Decisión: Si AUTH no se anuncia incluso tras STARTTLS, salta a la tubería del proveedor SASL (socket/demonio/mecanismos).

Task 7: Enviar una prueba real de AUTH usando swaks (mejor relación esfuerzo/beneficio)

cr0x@server:~$ swaks --server 127.0.0.1 --port 587 --tls --auth LOGIN --auth-user alice@example.net --auth-password 'nottherightpassword' --quit-after AUTH
=== Trying 127.0.0.1:587...
=== Connected to 127.0.0.1.
<--  220 mail01.example.net ESMTP Postfix
 --> EHLO client.example
<--  250-mail01.example.net
<--  250-STARTTLS
 --> STARTTLS
<--  220 2.0.0 Ready to start TLS
=== TLS started with cipher TLS_AES_256_GCM_SHA384
 --> EHLO client.example
<--  250-AUTH PLAIN LOGIN
 --> AUTH LOGIN
<--  334 VXNlcm5hbWU6
 --> YWxpY2VAZXhhbXBsZS5uZXQ=
<--  334 UGFzc3dvcmQ6
 --> bm90dGhlcmlnaHRwYXNzd29yZA==
<--  535 5.7.8 Error: authentication failed: authentication failure

Qué significa: Obtienes un 535 claro. Eso no es una falla de tubería SASL; es credenciales/backend o reglas de auth de Dovecot. Si en su lugar viste 454 4.7.0 Temporary authentication failure, piensa en disponibilidad de socket/demonio.

Decisión: Con un 535 estable, prueba el backend de auth directamente (Dovecot). Con 454, comprueba permisos del socket/salud del demonio.

Task 8: Inspecciona las líneas de log de Postfix relacionadas con el fallo

cr0x@server:~$ sudo journalctl -u postfix -S "10 min ago" --no-pager | egrep -i 'sasl|auth|warning|fatal' | tail -n 30
Jan 03 10:41:12 mail01 postfix/smtpd[18422]: warning: SASL authentication failure: Password verification failed
Jan 03 10:41:12 mail01 postfix/smtpd[18422]: warning: unknown[127.0.0.1]: SASL LOGIN authentication failed: authentication failure

Qué significa: Postfix llegó a la capa SASL y obtuvo un “password verification failed” definitivo. Eso no es un socket perdido. Es un backend de auth o problema de credenciales.

Decisión: Pasa a los logs de Dovecot y a pruebas de auth de Dovecot.

Task 9: Confirma que el socket de auth de Dovecot está donde Postfix lo espera

cr0x@server:~$ sudo doveconf -n | egrep '^(service auth|  unix_listener|    mode|    user|    group|auth_mechanisms)'
auth_mechanisms = plain login
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
}

Qué significa: Este es el estándar de oro para Dovecot+Postfix: el socket vive bajo /var/spool/postfix/private para que el Postfix chrooted pueda alcanzarlo; es propiedad de postfix; el modo permite acceso.

Decisión: Si tu socket está en otro sitio (como /run/dovecot/auth-client), o muévelo o ajusta el comportamiento chroot de Postfix. No “chmod 777” nada.

Task 10: Verificar que el socket existe y los permisos son sensatos

cr0x@server:~$ sudo ls -l /var/spool/postfix/private/auth
srw-rw---- 1 postfix postfix 0 Jan  3 10:02 /var/spool/postfix/private/auth

Qué significa: Existe, es un socket y postfix puede accederlo.

Decisión: Si falta: Dovecot no está en ejecución, ruta equivocada o listener no configurado. Si los permisos son erróneos: arréglalo en la configuración de Dovecot y recarga Dovecot.

Task 11: Probar la autenticación de Dovecot directamente (evitar Postfix)

cr0x@server:~$ sudo doveadm auth test alice@example.net 'nottherightpassword'
passdb: alice@example.net auth failed
extra fields:
  user=alice@example.net

Qué significa: El backend dice que no. Eso es consistente con el 535. Si esto falla incluso con credenciales correctas, tu passdb está mal configurado (SQL/LDAP/PAM), la cuenta está deshabilitada, o estás usando el formato de nombre de usuario incorrecto.

Decisión: Arregla passdb/userdb de Dovecot o los datos de cuenta. No toques Postfix hasta que el auth de Dovecot pase.

Task 12: Mira los logs de auth de Dovecot para la razón real

cr0x@server:~$ sudo journalctl -u dovecot -S "10 min ago" --no-pager | egrep -i 'auth|passdb|userdb|pam|ldap' | tail -n 40
Jan 03 10:41:12 mail01 dovecot[903]: auth: passwd-file(alice@example.net): Password mismatch
Jan 03 10:41:12 mail01 dovecot[903]: auth: Error: passwd-file: Cannot open file /etc/dovecot/users: Permission denied

Qué significa: Ahora estamos avanzando: Dovecot no puede leer su passwd-file. Postfix no mentía; simplemente no tenía el contexto.

Decisión: Arregla permisos/propiedad/etiquetas SELinux de /etc/dovecot/users o ajusta Dovecot para leer desde un backend apropiado.

Task 13: Comprueba la trampa del chroot de Postfix (ruta del socket dentro de /var/spool/postfix)

cr0x@server:~$ sudo postconf -n | egrep '^(queue_directory|daemon_directory|command_directory)\b'
queue_directory = /var/spool/postfix
daemon_directory = /usr/lib/postfix/sbin
command_directory = /usr/sbin

Qué significa: La cola de Postfix está en /var/spool/postfix. Muchas distribuciones ejecutan algunos servicios en chroot allí. Si tu socket de Dovecot está fuera de ese árbol, Postfix puede no verlo.

Decisión: Prefiere el socket de Dovecot bajo /var/spool/postfix/private/ como se mostró antes.

Task 14: Si usas Cyrus SASL, lista mecanismos disponibles y detecta “no mechanism available”

cr0x@server:~$ sudo saslpluginviewer -c
Installed and properly configured SASL (Cyrus SASL) mechanisms are:
  PLAIN
  LOGIN

Qué significa: Existen mecanismos. Si la lista está vacía, Postfix a menudo registrará no mechanism available y los clientes verán fallos o la desaparición de AUTH.

Decisión: Instala los paquetes de mecanismos de Cyrus adecuados y confirma el nombre del servicio en la config (a menudo en /etc/postfix/sasl/smtpd.conf).

Task 15: Confirmar que saslauthd se ejecuta y es accesible (camino Cyrus)

cr0x@server:~$ systemctl status saslauthd --no-pager
● saslauthd.service - SASL authentication daemon
     Loaded: loaded (/lib/systemd/system/saslauthd.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2026-01-02 09:10:01 UTC; 3h 21min ago
   Main PID: 991 (saslauthd)
      Tasks: 5 (limit: 18996)
     Memory: 4.7M
        CPU: 1.221s
     CGroup: /system.slice/saslauthd.service
             ├─991 /usr/sbin/saslauthd -a pam -m /var/run/saslauthd
             ├─992 /usr/sbin/saslauthd -a pam -m /var/run/saslauthd
             └─993 /usr/sbin/saslauthd -a pam -m /var/run/saslauthd

Qué significa: Está vivo y usa PAM con directorio de sockets /var/run/saslauthd.

Decisión: Si Postfix no puede hablar con él, comprueba que el usuario postfix está en el grupo correcto (comúnmente sasl) y que los permisos del socket permiten acceso.

Task 16: Identificar “AUTH funciona pero relay denegado” vs “AUTH falló”

cr0x@server:~$ swaks --server 127.0.0.1 --port 587 --tls --auth LOGIN --auth-user alice@example.net --auth-password 'correctpassword' --to bob@external.example --from alice@example.net
...
<--  235 2.7.0 Authentication successful
...
<--  554 5.7.1 <bob@external.example>: Relay access denied

Qué significa: AUTH tuvo éxito (235) pero relay está denegado. Eso es autorización/política. A menudo se malinterpreta como “auth roto”. No lo está.

Decisión: Revisa smtpd_relay_restrictions y asegúrate de que permit_sasl_authenticated esté en el lugar correcto para el servicio submission, no sobrescrito por accidente.

Broma corta #2: Cada vez que alguien dice “es solo correo”, un demonio SMTP genera otro archivo de log.

Tres microhistorias corporativas desde el terreno

Microhistoria 1: Incidente causado por una suposición equivocada

La configuración: una empresa mediana con entorno híbrido. Tenían un servidor de submission Postfix para clientes y un pool MX separado para correo entrante. DNS y nombres estaban ordenados: smtp.example.net para submission, mx1/mx2 para entrantes. Sobre el papel, nadie debería confundirlos.

Entonces llegó un nuevo perfil MDM para dispositivos móviles. Alguien tecleó mal el campo del servidor y lo puso en el hostname del MX. Los hosts MX tenían el puerto 25 abierto (obviamente) y TLS habilitado (también obviamente), pero estaban configurados para no anunciar AUTH en el puerto 25. Esto es normal y sensato: el puerto 25 es la puerta de entrada desde Internet, no la de tus empleados.

En minutos llegaron tickets de soporte: “contraseña rechazada”. Los ingenieros sacaron logs de Postfix del servidor de submission y no vieron nada. Sacaron logs del MX y encontraron muchas conexiones, sin intentos de AUTH, y clientes quejándose de autenticación. La primera suposición del equipo fue “SASL está caído”. Reiniciaron Dovecot en el servidor de submission. Luego reiniciaron Postfix. Luego todo lo que pillaron a mano.

No cambió nada, porque no había nada roto en el servidor de submission. La suposición equivocada fue que el tráfico llegaba donde el equipo esperaba. Una vez confirmaron con captura de paquetes y los logs del MX que los clientes se conectaban al MX, la solución fue embarazosa y simple: actualizar el perfil MDM para apuntar a smtp.example.net y exigir puerto 587.

Dos lecciones: primero, siempre verifica host y puerto objetivo antes de depurar. Segundo, “AUTH no ofrecido” no es lo mismo que “AUTH falló”. Frecuentemente es “estás en la puerta equivocada”.

Microhistoria 2: La optimización que salió mal

Otro equipo quería endurecer la seguridad y reducir la superficie de ataque. Buena intención. Decidieron forzar TLS en todas partes y pusieron smtpd_tls_security_level=encrypt globalmente. También habilitaron smtpd_tls_auth_only=yes. En aislamiento, ambas cosas son razonables.

El efecto secundario vino de un detalle: tenían un job de monitorización interno y algunas aplicaciones legacy que enviaban correo al servicio de submission sin soporte STARTTLS. Esas apps estaban en una VLAN “confiable”, y históricamente el servicio de submission permitía conexiones en claro desde esa subred. No ideal, pero funcionaba y el riesgo estaba acotado. El cambio convirtió ese “riesgo acotado” en “caída total”, y nadie tenía inventario de esas apps legacy porque los dueños habían cambiado de equipo tres veces.

Los síntomas eran confusos. Algunos clientes funcionaban (MUAs modernos). Otros fallaban con mensajes que parecían fallos de auth o de handshake según la librería. El ingeniero de guardia se centró en SASL porque “envío de correo falla” suele llevar esa etiqueta.

El diagnóstico correcto fue la negociación de capacidades. Esas apps legacy nunca llegaban a AUTH; no podían establecer TLS. La solución no fue debilitar TLS globalmente. Fue aplicar política por servicio: mantener submission estricto, pero proveer un relay interno separado con restricciones de red explícitas y sin AUTH, o exigir que esas apps usen un relay local que maneje TLS aguas arriba.

Resultado: la seguridad mejoró, pero solo después de recordar dolorosamente que apretar tuercas en sistemas productivos sin inventario de clientes es solo arte performativo.

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

Una compañía relacionada con finanzas tenía una plataforma de correo donde “aburrido” era un cumplido. Mantenían un runbook que insistía en una cosa antes de tocar configs: reproducir con swaks y capturar la transcripción SMTP completa. Sin excepciones. La gente rodaba los ojos hasta que dejó de hacerlo.

Un viernes, tras una actualización rutinaria del SO, AUTH empezó a fallar para un subconjunto de usuarios, pero solo cuando se conectaban a través de un VIP particular. La sospecha inmediata fue rareza del balanceador, desajuste de certificados o un socket SASL roto. El ingeniero de guardia siguió el runbook, ejecutó swaks contra cada backend y contra el VIP, y comparó transcripciones lado a lado.

La transcripción mostró que un backend anunciaba solo AUTH PLAIN mientras que otros anunciaban AUTH PLAIN LOGIN. Algunos clientes estaban hardcodeados para intentar LOGIN primero y luego rendirse si LOGIN faltaba. No era teórico; era un cliente móvil antiguo desplegado a granel.

La causa raíz terminó siendo una deriva parcial de configuración: un único nodo tenía un ajuste distinto de Dovecot auth_mechanisms debido a una ejecución de automatización fallida semanas atrás. La actualización del SO simplemente disparó un reload que hizo visible la deriva.

La práctica aburrida—siempre capturar y comparar la transcripción SMTP—convirtió una posible caída larga en una corrección simple: “hacer consistentes los nodos”. Nadie escribió un mail de victoria. Todos se fueron a casa.

Errores comunes: síntoma → causa raíz → arreglo

Estos son los modos de fallo que se repiten en entornos. Si reconoces el síntoma, no improvises. Sigue el arreglo en orden.

1) Síntoma: “El servidor no admite autenticación” (UI del cliente)

Causa raíz: Estás en el puerto 25, o AUTH está oculto hasta STARTTLS, o estás golpeando el MX en lugar de submission.

Arreglo: Usa el puerto 587 con STARTTLS o el puerto 465 con TLS implícito. Verifica que AUTH aparece solo después de STARTTLS con openssl s_client -starttls smtp. Confirma hostname y ruteo del VIP.

2) Síntoma: AUTH desaparece tras habilitar ajustes TLS

Causa raíz: Fallo en el handshake TLS, por lo que el segundo EHLO nunca ocurre; o la política TLS requiere cifrado pero tu sonda no hace STARTTLS.

Arreglo: Arregla certificados/chain, establece correctamente smtpd_tls_cert_file/key_file, y vuelve a probar con STARTTLS. No pruebes en texto plano y concluyas que SASL está roto.

3) Síntoma: 454 4.7.0 Temporary authentication failure

Causa raíz: Postfix no puede alcanzar el proveedor SASL (socket de Dovecot ausente/permiso denegado) o el proveedor está caído.

Arreglo: Para Dovecot, asegúrate de que el socket service auth exista bajo /var/spool/postfix/private/auth, propiedad/modo correctos y Dovecot en ejecución. Para Cyrus, asegura que saslauthd esté activo y accesible.

4) Síntoma: 535 5.7.8 Authentication credentials invalid

Causa raíz: Contraseña mala, formato de nombre de usuario erróneo, backend desajustado, o cuenta deshabilitada/bloqueada.

Arreglo: Prueba con doveadm auth test (o herramientas de saslauthd) usando exactamente el nombre de usuario que envía el cliente. Arregla el backend. Evita “arreglar” Postfix.

5) Síntoma: Logs de Postfix warning: SASL: Connect to private/auth failed: No such file or directory

Causa raíz: Ruta de socket desajustada o chroot mismatch. Postfix espera private/auth relativo a su queue_directory; Dovecot dejó el socket en otro sitio.

Arreglo: Configura el socket de Dovecot en /var/spool/postfix/private/auth y pon permisos correctos. O ajusta smtpd_sasl_path de Postfix para coincidir, pero prefiere el layout estándar.

6) Síntoma: Logs de Postfix no mechanism available

Causa raíz: Plugins de Cyrus SASL no instalados, o mecanismos de Dovecot no habilitados.

Arreglo: Instala paquetes de mecanismos para Cyrus, o ajusta Dovecot auth_mechanisms = plain login. Confirma con el listado de mecanismos y la salida EHLO post-STARTTLS.

7) Síntoma: AUTH tiene éxito pero los mensajes son rechazados como relay denied

Causa raíz: Política de autorización: permit_sasl_authenticated faltante/sobrescrita en el servicio submission, o restricciones de relay mal configuradas.

Arreglo: Pon permit_sasl_authenticated en smtpd_relay_restrictions (o las restricciones apropiadas para tu versión de Postfix) para submission. Confirma con un envío desde swaks.

8) Síntoma: Funciona para algunos usuarios, falla para otros (mismo cliente)

Causa raíz: Inconsistencia del backend (lag de replicación, múltiples fuentes de auth), problemas de normalización de nombre de usuario, o políticas por usuario como sender login maps.

Arreglo: Valida autenticación y autorización por separado. Revisa el comportamiento de smtpd_sender_login_maps y la búsqueda passdb/userdb de Dovecot para cada usuario.

Listas de verificación / plan paso a paso

Checklist A: Hacer que AUTH aparezca de forma fiable en submission (587)

  1. Asegura que el servicio submission esté habilitado en master.cf y escuchando en 587.
  2. Configura overrides por servicio para submission (recomendado):
    • smtpd_tls_security_level=encrypt (o may si debes, pero entiende por qué)
    • smtpd_sasl_auth_enable=yes
    • smtpd_tls_auth_only=yes
  3. Verifica que STARTTLS funciona y que la cadena de certificados es correcta.
  4. Verifica que el EHLO post-STARTTLS anuncia AUTH PLAIN LOGIN (o los mecanismos que pretendes).

Checklist B: Cableado Dovecot SASL que no envejece mal

  1. En Postfix:
    • smtpd_sasl_type = dovecot
    • smtpd_sasl_path = private/auth
  2. En Dovecot:
    • auth_mechanisms = plain login (a menos que sepas que necesitas otros)
    • service auth { unix_listener /var/spool/postfix/private/auth { user=postfix group=postfix mode=0660 } }
  3. Confirma que el socket existe y es accesible.
  4. Usa doveadm auth test para un usuario conocido antes de probar SMTP AUTH.

Checklist C: Cableado Cyrus SASL (si insistes)

  1. Confirma que existen mecanismos (saslpluginviewer no vacío).
  2. Confirma que saslauthd se ejecuta y usa el backend que pretendes (PAM/LDAP/etc.).
  3. Asegura que Postfix pueda acceder al directorio de sockets de saslauthd (permisos/miembro de grupo).
  4. Confirma que la config del servicio Cyrus SASL (a menudo /etc/postfix/sasl/smtpd.conf) coincide con tu pwcheck_method deseado.

Plan paso a paso “orden de solución” que puedes seguir durante una caída

  1. Reproducir con swaks contra el hostname/puerto exacto que usan los usuarios. Guarda la transcripción.
  2. Comprobar listener con ss -lntp. Si no escucha, arregla eso primero.
  3. Comprobar capacidades EHLO antes y después de TLS. Si AUTH no aparece post-TLS, no toques contraseñas.
  4. Confirmar ajustes del proveedor SASL (postconf -n). Decide Dovecot vs Cyrus; elimina ambigüedad.
  5. Validar alcanzabilidad socket/demonio (socket existe, permisos, chroot, política MAC).
  6. Validar auth del backend directamente (doveadm auth test o herramientas de saslauthd).
  7. Sólo entonces ajusta restricciones de política y sender login maps.
  8. Volver a probar con swaks, luego con un cliente real.

Preguntas frecuentes

1) ¿Debo habilitar SMTP AUTH en el puerto 25?

Normalmente no. Mantén el puerto 25 para tráfico MTA-a-MTA. Pon AUTH en 587/465. Si debes habilitar AUTH en 25 para un caso especial, aísla por IP y aplica rate-limit agresivo.

2) ¿Por qué AUTH aparece solo después de STARTTLS?

Porque smtpd_tls_auth_only=yes indica a Postfix anunciar AUTH solo tras cifrado activo. Esto evita ofrecer credenciales en claro. Si tu prueba no hace STARTTLS, concluirás falsamente que AUTH está deshabilitado.

3) ¿Cuál es la diferencia entre 465 y 587 para clientes?

587 es submission con STARTTLS (conexión en claro, luego upgrade). 465 es TLS implícito desde el primer byte. Operativamente ambos pueden estar bien; muchos entornos ejecutan ambos porque el comportamiento del cliente es impredecible.

4) Veo 535. ¿Es siempre una contraseña equivocada?

Es “credenciales rechazadas” en alguna capa, pero no siempre la contraseña humana. Puede ser formato de usuario incorrecto, fallo en lookup del backend, cuenta bloqueada o base de auth desincronizada entre nodos. Prueba con doveadm auth test (o la comprobación nativa del backend) para asegurarte.

5) Veo 454 4.7.0 Temporary authentication failure. ¿Qué implica?

Normalmente es tubería: Postfix no puede hablar con el proveedor de auth, o el proveedor no llega a su backend. Piensa en socket ausente, permiso denegado, demonio caído, chroot/SELinux. Rara vez es “usuario tecleó mal la contraseña”.

6) Dovecot auth funciona, pero SMTP AUTH aún falla. ¿Cómo puede ser?

Razones comunes: Postfix apunta a la ruta de socket equivocada, Postfix está chrooted y no ve el socket, permisos incorrectos para el usuario postfix, o los overrides del servicio submission difieren de los defaults de main.cf. Valida smtpd_sasl_type, smtpd_sasl_path y la existencia de /var/spool/postfix/private/auth.

7) ¿Por qué fallan algunos clientes cuando no se ofrece LOGIN?

Algunos clientes antiguos no manejan bien la negociación de mecanismos. Si solo ofreces PLAIN, puede que no lo intenten (aunque PLAIN sobre TLS sea aceptable). Si necesitas compatibilidad amplia, ofrece tanto PLAIN como LOGIN sobre TLS.

8) ¿Sigue haciendo falta “broken_sasl_auth_clients”?

A veces. Existe para implementaciones cliente defectuosas que no siguen la especificación perfectamente. Si no lo necesitas, puedes eliminarlo, pero no lo quites en medio de un incidente salvo que hayas reproducido una falla ligada a él.

9) ¿Cómo distinguir “AUTH falló” de “AUTH tuvo éxito pero no se permite enviar como esa dirección”?

Busca primero 235 Authentication successful. Si obtienes 235 y luego rechazos como relay denied o sender access denied, estás en territorio de autorización/política: smtpd_sender_login_maps, restricciones o milters.

10) ¿Debería preferir Dovecot SASL o Cyrus SASL?

Si ya ejecutas Dovecot para IMAP/POP, usa Dovecot SASL. Menos partes móviles, menos sorpresas de paquetes/plugins y el modelo de socket es directo. Cyrus SASL puede funcionar bien, pero es más fácil montar una pila frágil accidentalmente.

Siguientes pasos que puedes desplegar

Los fallos de autenticación SASL en Postfix son solucionables rápidamente cuando dejas de adivinar y empiezas a aislar capas. Trátalo como cualquier otra cadena de dependencias en producción: verifica el punto de entrada, confirma la negociación, valida la tubería de auth, luego valida el backend y después aplica la política.

Pasos prácticos siguientes:

  1. Captura una transcripción conocida buena de swaks para tu entorno y guárdala en el runbook como referencia.
  2. Estandariza en un proveedor SASL (Dovecot si lo ejecutas) y una ruta de socket (/var/spool/postfix/private/auth).
  3. Haz explícita la política de submission en overrides de master.cf para que las actualizaciones no cambien el comportamiento “útilmente”.
  4. Añade una comprobación de monitorización que verifique: STARTTLS funciona, AUTH se anuncia tras TLS y un AUTH sintético tiene éxito para una cuenta de prueba.
← Anterior
Zumbido de bobina: por qué tu GPU chirría—y qué puedes (y no puedes) hacer
Siguiente →
Una actualización de controlador mató mis FPS: cómo diagnosticarlo correctamente

Deja un comentario