Episodio I: Exim4 con MySQL y usuarios virtuales

Nota: Este post pertenece a una saga de configuración de correo, para entenderlo debes ir primero a saga de servidores de correo

Preparación del entorno

Crear un usuario virtual para el correo, por ejemplo vmail, es fácil: adduser –disabled-login vmail

También se deben instalar los siguientes paquetes: exim-daemon-heavy. Supongo que ya tienes instalado MySQL y phpMyAdmin

Tras la instalación del paquete en /etc/exim4/update-exim4.conf establezco algunas opciones:

  • Configuración en ficheros partidos con
  • Usar entrega en formato mail_dir
  • Activar la escucha en el puerto adicional  587

Sólo se muestran los cambios en el fichero /etc/exim4/update-exim4.conf

dc_local_interfaces='0.0.0.0.587 ; 0.0.0.0.25 ;  ::1'
dc_localdelivery='maildir_home'
dc_use_split_config='true'

Creación de las tablas

Tras crear una nueva base de datos, con el siguiente código creo las 4 tablas:

CREATE TABLE IF NOT EXISTS `mod_exim4_alias` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `alias` varchar(255) NOT NULL DEFAULT '',
 `destination` varchar(255) NOT NULL DEFAULT '',
 PRIMARY KEY (`id`)
 );
 
CREATE TABLE IF NOT EXISTS `mod_exim4_relays` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `domain` varchar(200) ,
 PRIMARY KEY (`id`),
 UNIQUE KEY `domain` (`domain`)
);

CREATE TABLE IF NOT EXISTS mod_exim4_mailboxes (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `email` varchar(128) NOT NULL DEFAULT '',
 `password` varchar(128) NOT NULL DEFAULT '',
 `maildir` varchar(128) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  UNIQUE KEY `email` (`email`)
);

CREATE TABLE IF NOT EXISTS `mod_exim4_domains` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `domain` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

Configuración MySQL en Exim4

La configuración descrita a continuación supone que tienes el modo de configuración de Exim4 partido en diferentes archivos en /etc/exim4/conf.d

El primer fichero contiene las opciones generales: /etc/exim4/conf.d/main/00_exim4-config_mypanel

# MyPanel configuration for virtual users with exim4
# MySQL connection

MYSQL_V_MAILDIR = SELECT maildir FROM mod_exim4_mailboxes WHERE email='${quote_mysql:$local_part@$domain}'
MYSQL_V_AUTH_PLAIN = SELECT email FROM mod_exim4_mailboxes WHERE  email='$2' and password=encrypt('$3',password)
MYSQL_V_AUTH_LOGIN = SELECT email FROM mod_exim4_mailboxes WHERE email='$1' and password=encrypt('$2',password)
MYSQL_V_ALIAS = SELECT destination FROM mod_exim4_alias WHERE  alias='${quote_mysql:$local_part@$domain}'
MYSQL_V_LOCAL_USER = SELECT email FROM mod_exim4_mailboxes where email='$local_part@$domain'

# Primary domains
MYSQL_V_DOMAINS = SELECT domain FROM mod_exim4_domains WHERE domain='$domain'

# Hosts Relay - Secondary MX records
MYSQL_V_RELAY = SELECT domain FROM mod_exim4_relays WHERE domain='$domain' 

hide mysql_servers = localhost/{$MY_DATABASE}/{$MYDB_USER}/{$MYDBL_PASSWORD}

## Domains
MAIN_LOCAL_DOMAINS = mysql;MYSQL_V_DOMAINS
MAIN_RELAY_TO_DOMAINS = mysql;MYSQL_V_RELAY

Nota: No te olvides de establecer correctamente el usuario y base de datos en la línea resaltada

Para configurar la autenticación contra la la base de datos MySQL hay que desactivar la configuración por defecto, por ejemplo renombrando el fichero:

mv /etc/exim4/conf.d/auth/30_exim4-config_examples /etc/exim4/conf.d/auth/30_exim4-config_examples.disabled

Ahora se crea  un nuevo fichero  /etc/exim4/conf.d/auth/20_exim4-config_mysql_mypanel con este contenido:

plain:
   driver = plaintext
   public_name = PLAIN
   server_condition =  ${lookup mysql{MYSQL_V_AUTH_PLAIN}{1}fail}
   server_set_id = $2
   server_prompts = :

login_server:
   driver = plaintext
   public_name = LOGIN
   server_prompts = "Username:: : Password::"
   server_condition = ${lookup mysql{MYSQL_V_AUTH_LOGIN}{1}fail}
   server_set_id = $1

Ahora se configuran dos routers, unos para la tabla de alias y otra para la tabla de usuarios virtuales, hay que crear dos nuevos ficheros con los contenidos mostrados

  1. Para los alias: /etc/exim4/conf.d/router/270_exim4-config_virtual_aliases_mypanel
  2. Para los usuarios virtuales: /etc/exim4/conf.d/router/275_exim4-config_virtual_local_user_mypanel
virtual_aliases:
  debug_print = "R: virtual_aliases for $local_part@$domain"
  driver = redirect
  domains = +local_domains
  allow_fail
  allow_defer
  data = ${lookup mysql{MYSQL_V_ALIAS}}
  file_transport = address_file
 directory_transport = address_directory
virtual_local_user:
  debug_print = "R: virtual_user for $local_part@$domain"
  driver = accept
  domains = +local_domains
  condition = ${lookup mysql{MYSQL_V_LOCAL_USER}}
  transport = virtual_local

La configuración del transporte para la entrega del correo en la carpeta de usuarios virtuales se realiza en un nuevo fichero en /etc/exim4/conf.d/transport/30_exim4-config_virtual_mypanel

virtual_local:
  debug_print = "T: virtual_local for $local_part@$domain"
  driver = appendfile
  directory= /home/vmail/${lookup mysql {MYSQL_V_MAILDIR}{$value}}/\
              ${if eq {$h_X-Spam-Flag:}{YES} {.SPAM/}}
  delivery_date_add
  envelope_to_add
  return_path_add
  maildir_format
  mode = 0660
  mode_fail_narrower = false
  user = vmail
  group = vmail

Este fichero ya tiene preparada la entrega del spam en la carpeta SPAM del cliente, solo hay que configurar correctamente spamassassin en posteriores episodios

Usando TLS

Continuo personalizando en el fichero con definiciones propias /etc/exim4/conf.d/00_exim4_config_mypanel añadiendo:

MAIN_TLS_ENABLE = 1

Actualmente obtengo los certificados de letsencrypt con certbot y con la configuración inicial del servidor los permisos de los ficheros dan problemas. La solución que utilizo es añadir al sistema un nuevo grupo al sistema llamado ssl . Tras esto, hay que añadir los servicios del sistema que necesitan acceder a las claves privadas al grupo ssl.

Para que todo opere correctamente hay que hacer una revisión de los permisos en el directorio /etc/letsencrypt estableciendo el grupo de manera recursiva a ssl. Finalmente, para no tener que estar revisando continuamente los permisos, activo el bit s  de grupo en todos los directorios de /etc/letsencrypt, así, los nuevos ficheros y directorios se creen pertenecerán automáticamente a este grupo.

Los comandos son los siguientes:

addgroup ssl
chown -R root:ssl /etc/letsencrypt
find /etc/letsencrypt -type d | xargs chmod g+s
chmod -R g+r /etc/letsencrypt

En principio con esta configuración los permisos deben operar correctamente para todos los servicios del sistema que estén añadidos al grupo ssl, por ello se debe añadir el usuario Debian-exim al grupo ssl con el comando:

adduser Debian-exim ssl

La obtención de los certificados no se trata en este post, así que suponiendo que se han obtenido hay que configurar exim4 estableciendo las variables que tiene predefinidas para este propósito que son MAIN_TLS_CERTIFICATE y MAIN_TLS_PRIVATEKEY en el fichero /etc/exim4/conf.d/main/00_exim4-config_mypanel

MAIN_TLS_CERTIFICATE = /etc/letsencrypt/live/yo.com/privkey.pem
MAIN_TLS_PRIVATEKEY = /etc/letsencrypt/live/yo.com/fullchain.pem

Detalles finales

El nombre de la máquina de correo se puede cambiar en el fichero en /etc/mailname para que coincida con la resolución inversa de DNS. Es importante ya que te reconozcan otros servidores de correo. Pero no termina de funcionar bien en Debian 8 y 9 así que alternativamente se puede forzar en el fichero /etc/exim4/conf.d/main/00_exim4-config_mypanel con:

primary_hostname = yo.com

Tras reiniciar el servicio exim4 debes testar el servidor con alguna herramienta, yo suelo usar mxtoolbox usando la opción Test Email Server

paulino

paulino escribió 18 entradas

Navegación de la entrada


Comentarios

  • Leonardo

    Podrías colocar un insert de una cuenta de correo?

    • paulino

      Ahí tienes un ejemplo, se usa la función ENCRYPT de mysql para la clave. Suelo ordenador los dominios por carpetas tal y como he puesto en el campo «maildir»

      INSERT INTO `mod_exim4_mailboxes` (`id`, `email`, `password`, `maildir`) VALUES (NULL, 'prueba@ejemplo.com', ENCRYPT('1234'), 'ejemplo.com/prueba@ejemplo.com');
      

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

Puede usar las siguientes etiquetas y atributos HTML:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>