3. Exim4 con MySQL y usuarios virtuales

Objetivos:

  1. Crear un usuario en el sistema para gestionar todo el correo

  2. Crear una base de datos con varias tablas para toda la gestión de: dominios,cuentas de correos, redirecciones (alias) y secundarios.

  3. Configurar Exim4 para que haga consultas a la base datos y entregue los correos en carpetas maildir indicadas en la base de datos.

3.1. Creación del usuario

En primer lugar hay que crear un usuario único del sistema bajo el cual estará todo el correo electrónico del sistema. En mi configuración utilizo vmail:

adduser --disabled-login vmail

El directorio /home/vmail será el directorio base donde se entreguen todos los correos

3.2. Creación de las tablas MySQL

LLegado aquí, se supone que se tiene instalado el servidor MySQL/MariaDB. Se debe crear una base de datos y usar el siguiente código para crear las 4 tablas:

Fichero: tablas.sql
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`)
);

3.3. 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

Para establecer algunas variables creo un nuevo fichero con prioridad y que contiene las opciones generales: /etc/exim4/conf.d/main/00_exim4-config_custom

# MyPanel configuration for virtual users with Exim4

# MySQL connection
hide mysql_servers = localhost/DATABASE_NAME/DB_USER/DB_PASSWORD

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='${quote_mysql:$2}' and password=sha2('${quote_mysql:$3}',256)
MYSQL_V_AUTH_LOGIN = SELECT email FROM mod_exim4_mailboxes WHERE email='${quote_mysql:$1}' and password=sha2('${quote_mysql:$2}',256)
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='${quote_mysql:$local_part@$domain}'

# Primary domains
MYSQL_V_DOMAINS = SELECT domain FROM mod_exim4_domains WHERE domain='${quote_mysql:$domain}'

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

# Get domains from MYSQL queries
MAIN_LOCAL_DOMAINS = mysql;MYSQL_V_DOMAINS
MAIN_RELAY_TO_DOMAINS = mysql;MYSQL_V_RELAY

Atención

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

En las dos últimas líneas de la configuración anterior se ha establecido que Exim4 obtenga los dominos locales y los secundarios de las consultas SQL. Pero para procesar los correos entrantes y, sin entrar en detalles internos sobre el diseño de Exim4, hay que crear dos elementos de configuración nuevos: un router y un transport.

3.3.1. Alias virtuales

El primer router es para los alias y se creará en el directorio/fichero /etc/exim4/conf.d/router/270_exim4-config_virtual_aliases_mypanel. Es importante el prefijo 270_ ya que se procesan por orden y quiero que estos tengan preferencia a los usuarios locales y alias del sistema. El fichero sería:

# Aliases from mysql table

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

3.3.2. Correos virtuales

El segundo router estará en el fichero /etc/exim4/conf.d/router/275_exim4-config_virtual_local_user_mypanel y se encarga de buscar las direcciones de correo en la tabla MySQL y en caso de encontrarla procesa el correo con el transporte virtual_local:

# Virtual users from mysql table

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

El transporte virtual_local es el encargado de entregar el correo en la carpeta maildir del usuario virtual. Se creará en un nuevo fichero para este transporte: /etc/exim4/conf.d/transport/30_exim4-config_virtual_mypanel:

# Transport for virtual users
# maildirs are under /home/vmail

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} {.Junk/}}
  delivery_date_add
  envelope_to_add
  return_path_add
  maildir_format
  mode = 0660
  mode_fail_narrower = false
  user=vmail
  group=vmail

El transporte está configurado de la siguiente forma:

  • Se fuerza que los correos se entreguen en una subcarpeta de /home/vmail. Con esto las entradas de la base de datos siempre son relativas.

  • El transporte ya tiene preparada la entrega del spam en la carpeta SPAM, solo hay que configurar correctamente Spamassassin posteriormente.

3.3.3. Autenticación usuarios virtuales

El siguiente paso es configurar los métodos de autenticación para el envío de correo mediante SMTP. En primer lugar se desactiva la configuración predeterminada renombrando el fichero /etc/exim4/conf.d/auth/30_exim4-config_examples del modo indicado:

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

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:

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

# Auth methods using mysql

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

Tras estos cambios se debe comprobar la configuración de Exim4 y reiniciar el servicio:

update-exim4.conf --check
systemctl restart exim4