
Al migrar una cuenta de correo desde un servidor Linux con Dovecot hacia un proveedor externo mediante IMAP, es posible encontrarse con un error de autenticación similar al siguiente:
pam_unix(dovecot:auth): check pass; user unknown
pam_unix(dovecot:auth): authentication failure
ruser=usuario@dominio-origen.example
rhost=203.0.113.50
Este problema puede resultar confuso porque la contraseña puede ser correcta y el usuario existir realmente en el servidor.
En este artículo veremos cómo diagnosticar y resolver este error cuando Dovecot utiliza PAM para autenticar usuarios locales de Linux.
Escenario del problema
Supongamos que queremos importar el correo de:
usuario@dominio-origen.example
hacia una nueva cuenta:
usuario@dominio-destino.example
El proveedor de destino intenta conectarse mediante IMAP al servidor original utilizando como nombre de usuario la dirección completa:
usuario@dominio-origen.example
Sin embargo, en el servidor Linux la cuenta local solamente existe como:
usuario
Cuando Dovecot envía el nombre completo a PAM, Linux intenta encontrar literalmente un usuario llamado:
usuario@dominio-origen.example
Como ese usuario no existe en /etc/passwd, PAM genera:
user unknown
1. Comprobar que el usuario existe en Linux
Primero verificamos cómo está registrado realmente el usuario.
getent passwd usuario
También podemos utilizar:
id usuario
Una salida válida podría ser:
usuario:x:1001:1001::/home/usuario:/bin/bash
Esto confirma que la cuenta local se llama:
usuario
y no:
usuario@dominio-origen.example
2. Revisar cómo autentica Dovecot
Podemos consultar la configuración activa con:
doveconf -n
Para concentrarnos en la autenticación:
doveconf -n | grep -Ei '^(auth_username_format|auth_default_realm|passdb|userdb|disable_plaintext_auth|auth_mechanisms)'
En este caso encontramos una configuración similar a:
passdb {
driver = pam
}
userdb {
driver = passwd
}
Esto significa que:
- Dovecot utiliza PAM para validar la contraseña.
- Dovecot consulta la base de usuarios del sistema mediante
passwd. - El usuario debe existir como una cuenta válida de Linux.
3. Identificar el verdadero problema
El registro mostraba algo similar a:
ruser=usuario@dominio-origen.example
Pero Linux únicamente tenía:
usuario
Por tanto, necesitábamos indicarle a Dovecot que eliminara la parte del dominio antes de enviar el usuario a PAM.
Dovecot permite hacerlo mediante:
auth_username_format
4. Localizar dónde configurar auth_username_format
Antes de modificar archivos conviene revisar cómo está organizada la configuración.
Ejecutamos:
grep -RniE 'auth_username_format|auth_default_realm|^[[:space:]]*!include|^[[:space:]]*!include_try' \
/etc/dovecot/dovecot.conf /etc/dovecot/conf.d 2>/dev/null
En una instalación típica podemos encontrar:
/etc/dovecot/dovecot.conf:!include conf.d/*.conf
/etc/dovecot/dovecot.conf:!include_try local.conf
/etc/dovecot/conf.d/10-auth.conf:#auth_username_format = %Lu
Esto nos indica que podemos utilizar:
/etc/dovecot/local.conf
para agregar configuraciones personalizadas sin modificar directamente los archivos predeterminados de Dovecot.
5. Configurar Dovecot para eliminar el dominio
La solución consiste en utilizar:
auth_username_format = %Ln
El modificador %Ln hace dos cosas:
- convierte el nombre de usuario a minúsculas;
- utiliza solamente la parte local anterior a
@.
Por ejemplo:
Usuario@Dominio-Origen.Example
se convierte en:
usuario
Antes de modificar el archivo es recomendable crear un respaldo.
cp -a /etc/dovecot/local.conf \
/etc/dovecot/local.conf.bak_$(date +%Y%m%d_%H%M%S) 2>/dev/null || true
Después podemos agregar:
printf '\n# Aceptar usuario@dominio para cuentas locales\nauth_username_format = %%Ln\n' >> /etc/dovecot/local.conf
El archivo debería contener:
auth_username_format = %Ln
6. Validar la configuración
Antes de continuar verificamos que Dovecot pueda interpretar correctamente todos sus archivos:
doveconf -n
También podemos comprobar específicamente el nuevo parámetro:
doveconf auth_username_format
El resultado esperado es:
auth_username_format = %Ln
7. Recargar Dovecot
Si la configuración es válida podemos recargar el servicio:
systemctl reload dovecot
Después verificamos su estado:
systemctl is-active dovecot
La respuesta debe ser:
active
No suele ser necesario reiniciar completamente el servicio. Una recarga es suficiente para este tipo de cambio.
8. Probar manualmente la autenticación
Antes de volver a intentar una migración completa es conveniente probar directamente con doveadm.
Ejecutamos:
doveadm auth test 'usuario@dominio-origen.example'
Dovecot solicitará la contraseña:
Password:
Si la configuración es correcta veremos algo parecido a:
passdb: usuario@dominio-origen.example auth succeeded
extra fields:
user=usuario
original_user=usuario@dominio-origen.example
Esta salida es especialmente importante.
Nos confirma que Dovecot recibió:
usuario@dominio-origen.example
pero internamente lo convirtió en:
usuario
y PAM pudo autenticar correctamente la cuenta.
9. Supervisar los registros durante la importación
Una vez solucionada la autenticación podemos repetir la importación desde el proveedor de correo destino.
Mientras realizamos la prueba es recomendable supervisar los registros del servidor:
tail -F /var/log/maillog /var/log/secure
Dependiendo de la distribución de Linux, también puede resultar útil:
journalctl -u dovecot -f
Debemos buscar mensajes relacionados con:
dovecot
imap
auth
Login
Disconnected
Después de la corrección ya no debería aparecer:
pam_unix(dovecot:auth): user unknown
para la cuenta correspondiente.
¿Por qué ocurre este problema?
En servidores tradicionales es común que las cuentas de correo sean también usuarios locales del sistema.
Por ejemplo:
usuario
Sin embargo, muchos clientes de correo, herramientas de migración y proveedores modernos esperan utilizar el correo completo como nombre de usuario:
usuario@dominio.example
Si Dovecot utiliza:
passdb {
driver = pam
}
PAM intentará localizar exactamente el nombre que recibe.
Por ello:
usuario@dominio.example
y:
usuario
son dos nombres completamente diferentes para Linux.
auth_username_format = %Ln actúa como una capa de normalización entre ambos sistemas.
Advertencia si el servidor maneja varios dominios
Esta solución es apropiada cuando distintas direcciones de correo corresponden directamente a usuarios locales de Linux y el dominio no es necesario para identificar la cuenta.
Por ejemplo:
usuario@dominio.example → usuario
Sin embargo, hay que tener cuidado si el mismo servidor aloja varios dominios que pueden tener usuarios con el mismo nombre.
Por ejemplo:
ventas@empresa-a.example
ventas@empresa-b.example
Si eliminamos el dominio, ambas cuentas se transformarían en:
ventas
En un servidor virtual con múltiples dominios normalmente conviene utilizar una base de usuarios virtuales en lugar de cuentas locales mediante PAM.
Comandos de diagnóstico útiles
Comprobar si existe el usuario:
getent passwd usuario
Mostrar configuración activa:
doveconf -n
Mostrar configuración de autenticación:
doveconf -n | grep -Ei 'auth_username_format|auth_default_realm|passdb|userdb'
Consultar el formato de usuario activo:
doveconf auth_username_format
Probar autenticación:
doveadm auth test 'usuario@dominio.example'
Comprobar estado:
systemctl is-active dovecot
Observar registros:
journalctl -u dovecot -f
Resumen de la solución
El problema original era:
pam_unix(dovecot:auth): user unknown
Dovecot recibía:
usuario@dominio.example
mientras que PAM solamente conocía:
usuario
La corrección fue configurar:
auth_username_format = %Ln
Después de recargar Dovecot, una prueba con:
doveadm auth test 'usuario@dominio.example'
mostró:
auth succeeded
user=usuario
original_user=usuario@dominio.example
Esto confirmó que la normalización del nombre de usuario estaba funcionando correctamente.
Conclusión
Cuando una migración IMAP falla con pam_unix(dovecot:auth): user unknown, no debemos asumir inmediatamente que la contraseña es incorrecta.
Es importante comprobar primero qué nombre de usuario recibe realmente Dovecot y cómo está registrado ese usuario en Linux.
En configuraciones donde Dovecot utiliza PAM y usuarios locales, una diferencia entre:
usuario
y:
usuario@dominio.example
puede ser suficiente para impedir completamente la autenticación.
El parámetro:
auth_username_format = %Ln
permite resolver este escenario de forma sencilla, manteniendo compatibilidad con clientes y servicios que utilizan la dirección de correo completa como nombre de usuario.
