sudo: Jack of all trades, master of some

Servidor de correo con usuarios virtuales usando Postfix, Dovecot y MySQL en Debian

4 comentarios

Esta son las notas personales que he ido acumulando durante mis experiencias en la instalación y configuración de un sistema de correo utilizando usuarios virtuales con Postfix, Dovecot y MySQL sobre Debian GNU/Linux.
Estas notas no pretenden ser una guía amigable para los usuarios que necesiten exactamente un paso a paso, pretendo con esta entrada dar hints a los lectores interesados y de cierta manera prefiero crear un feedback ya que no tengo mucho tiempo de documentar detalladamente la guía.
Estas notas se usaron para la configuración de este sistema que utiliza Postfix 2.9.3, Dovecot 2.1.7 y MySQL 5.1 sobre Debian GNU/Linux Squeeze. Tampoco pretendo tocar los temas de TLS y seguridad de Postfix y Dovecot, estos pudieran ser posibles futuros contenidos.
Estas notas pueden contener erratas, de encontrar alguna, notificarla.

¡MUY IMPORTANTE!

Como he dicho en varias entradas la plantilla NO me permite poner códigos en un solo renglón. Es importante que se tenga cuidado al copiar y pegar texto.

Contenidos

1.  Instalación de paquetes necesarios
2.  Preparación de la base de datos de MySQL
    2.1 Creación de las tablas
    2.2 Inserción de datos en las tablas
3.  Configuración de la conexión de Postfix con MySQL
4.  Configuración de Dovecot
    4.1 Configuración de la conexión de Dovecot con MySQL
5.  Configuración de la conexión de Postfix con Dovecot
6.  Creación de certificados SSL para Postfix y Dovecot
    Referencias

1. Instalación de paquetes necesarios

aptitude install postfix postfix-mysql
aptitude install mysql-server
aptitude install dovecot-imapd dovecot-pop3d dovecot-mysql

2. Preparación de la base de datos de MySQL

mysql -u root -p

Creación del usuario que administrará la base de datos:

CREATE DATABASE vmail;
GRANT SELECT ON vmail.* TO 'postfix'@'localhost' IDENTIFIED BY 'pass';
FLUSH PRIVILEGES;

2.1 Creación de las tablas necesarias

mysql -u root -p
USE vmail;

CREATE TABLE `domains` (
`id` INT(11) NOT NULL auto_increment,
`domain` VARCHAR(50) NOT NULL,
`active` TINYINT(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8;

CREATE TABLE `users` (
`id` INT(11) NOT NULL auto_increment,
`domain_id` INT(11) NOT NULL,
`email` VARCHAR(100) NOT NULL,
`password` VARCHAR(64) NOT NULL,
`quota` INT(11) NOT NULL DEFAULT '0',
`active` TINYINT(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
FOREIGN KEY (domain_id) REFERENCES domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8;

CREATE TABLE `aliases` (
`id` INT(11) NOT NULL auto_increment,
`domain_id` INT(11) NOT NULL,
`source` VARCHAR(100) NOT NULL,
`destination` VARCHAR(100) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (domain_id) REFERENCES domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8;

2.2 Inserción de datos en las tablas

mysql -u root -p

Para instertar dominios:

INSERT INTO vmail.domains (id,domain)
VALUES (DEFAULT,'dominio.tld');

Para insertar usuarios:

INSERT INTO vmail.users (id,domain_id,email,password,quota,access,active)
VALUES (DEFAULT,'1','usuario@dominio.tld',MD5('pass'),'20','int','1');

Para insertar aliases:

INSERT INTO vmail.aliases (id,domain_id,source,destination)
VALUES (DEFAULT,'1','usuario2@dominio.tld','usuario@dominio.tld');

3. Configuración de la conexión de Postfix con MySQL

Crear el archivo /etc/postfix/mysql_virtual_domains.cf con el siguiente contenido:

user = postfix
password = pass
hosts = 127.0.0.1
dbname = vmail
query = SELECT 1 FROM domains WHERE domain='%s' AND active='1'
postconf -e virtual_mailbox_domains=mysql:/etc/postfix/mysql_virtual_domains.cf

Crear el archivo /etc/postfix/mysql_virtual_mailboxes.cf con el siguiente contenido:

user = postfix
password = pass
hosts = 127.0.0.1
dbname = vmail
query = SELECT 1 FROM users WHERE email='%s' AND active='1'
postconf -e virtual_mailbox_maps=mysql:/etc/postfix/mysql_virtual_mailboxes.cf

Crear el archivo /etc/postfix/mysql_virtual_aliases.cf con el siguiente contenido:

user = postfix
password = pass
hosts = 127.0.0.1
dbname = vmail
query = SELECT destination FROM aliases WHERE source='%s'
postconf -e virtual_alias_maps=mysql:/etc/postfix/mysql_virtual_aliases.cf

Comprobación de la conexión de Postfix con MySQL

postmap -q dominio.tld mysql:/etc/postfix/mysql_virtual_domains.cf
postmap -q usuario@dominio.tld mysql:/etc/postfix/mysql_virtual_mailboxes.cf
postmap -q usuario@dominio.tld mysql:/etc/postfix/mysql_virtual_aliases.cf

En todos los casos debe devolver 1 si la consulta se realiza satisfactoriamente.

Nota: postconf -e agrega la configuración y recarga Postfix.

Permisos de archivos de configuración

chgrp postfix /etc/postfix/mysql_*.cf
chmod 640 /etc/postfix/mysql_*.cf

Crear el usuario vmail

groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /home/vmail -m -s /usr/sbin/nologin
chown -R vmail:vmail /home/vmail
chmod u+w /home/vmail

4. Configuración de Dovecot

auth_default_realm = dominio.tld
auth_mechanisms = plain login
disable_plaintext_auth = no
first_valid_uid = 5000
last_valid_uid = 5000
log_path = /var/log/dovecot.log
log_timestamp = "%Y-%m-%d %H:%M:%S "
login_greeting = IMAP/POP3 Server
mail_uid = 5000
mail_gid = 5000
mail_location = maildir:/home/vmail/%d/%n/Maildir
ssl_cert = </etc/dovecot/ssl/dovecot.pem
ssl_key = </etc/dovecot/ssl/private/dovecot.pem
protocols = imap pop3
service imap-login {
    inet_listener imap {
        address = *
        port = 143
    }
    inet_listener imaps {
        address = *
        port = 993
    }
}
service pop3-login {
    inet_listener pop3 {
        address = *
        port = 110
    }
    inet_listener pop3s {
        address = *
        port = 995
    }
}
service auth {
    unix_listener /var/spool/postfix/private/auth {
        mode = 0660
        user = postfix
        group = postfix
    }
    unix_listener auth-master {
        mode = 0600
        user = vmail
        group = vmail
    }
}
userdb {
    driver = sql
    args = /etc/dovecot/dovecot-sql.conf
}
passdb {
    driver = sql
    args = /etc/dovecot/dovecot-sql.conf
}
service quota-warning {
    executable = script /etc/dovecot/quota-warning.sh
    user = vmail
    unix_listener quota-warning {
        user = vmail
    }
}
protocol imap {
    mail_plugins = quota imap_quota
}
protocol pop3 {
    mail_plugins = quota
}
protocol lda {
    auth_socket_path = /var/run/dovecot/auth-master
    log_path = /var/log/dovecot.log
    mail_plugins = quota
    postmaster_address = postmaster@dominio.tld
}
plugin {
    quota = maildir:User quota
    quota_rule = *:storage=50M
}
plugin {
    quota_exceeded_message = ESTE BUZON HA EXCEDIDO LA CUOTA DE ESPACIO EN DISCO
}
plugin {
    quota_warning = storage=95%% quota-warning 95 %u
}

Script quota-warning.sh

#!/bin/bash

PERCENT=$1
USER=$2

cat << EOF | /usr/lib/dovecot/dovecot-lda -d $USER -o "plugin/quota=maildir:User quota:noenforcing"
From: postmaster@domain.tld
Subject: ALERTA DE USO DE CUOTA

SU BUZON DE CORREO ACTUALMENTE OCUPA UN $PERCENT% EN DISCO.

EOF

4.1 Configuración de la conexión de Dovecot con MySQL

Crear el archivo /etc/dovecot/dovecot-sql.conf con el siguiente contenido:

driver = mysql
connect = host=127.0.0.1 user=postfix password=pass dbname=vmail
default_pass_scheme = PLAIN-MD5
user_query = SELECT CONCAT('*:storage=', quota, 'M') AS quota_rule FROM users WHERE email='%u' AND active='1'
password_query = SELECT email AS user, password FROM virtual_users WHERE email='%u' AND active='1'

Permisos del log de Dovecot

chown vmail:vmail /var/log/dovecot.log
chmod go= /var/log/dovecot.log

Permisos de archivos de configuración de Dovecot

chown root:root /etc/dovecot/dovecot-sql.conf
chmod go= /etc/dovecot/dovecot-sql.conf
chgrp vmail /etc/dovecot/dovecot.conf
chmod g+r /etc/dovecot/dovecot.conf

5. Configuración de la conexión de Postfix y Dovecot

Agregar en el archivo /etc/postfix/master.cf lo siguiente:

dovecot unix - n n - - pipe
    flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}

Nota: la segunda línea debe tener al menos un espacio o tabulación inicial.

6. Creación de certificados SSL para Postfix y Dovecot

openssl req -new -x509 -days 3650 -nodes -out /etc/dovecot/ssl/dovecot.pem -keyout /etc/dovecot/ssl/private/dovecot.pem
openssl req -new -x509 -days 3650 -nodes -out /etc/postfix/ssl/postfix.pem -keyout /etc/postfix/ssl/private/postfix.pem

Permisos de los certificados

chmod o= /etc/dovecot/ssl/private/dovecot.pem
chmod o= /etc/postfix/ssl/private/postfix.pem

Referencias

Comentarios desactivados
  1. Koratsuki 5 años atrás

    Haz probado iRedmail[iredmail.org] o PostfixAdmin[postfixadmin.sourceforge.net]? Creo que no pasarás tanto trabajo con las bases de datos, almacenamiento y demás, cuando los pruebes… Un salu2.

    1. @Koratsuki

      He probado ambos, de hecho tomé elementos de los dos para mi setup, pero prefiero hacer las cosas yo, de ese modo el debug se me hace más fácil y solamente incluyo las funcionalidades que necesito.

  2. el campo access en la tabla users no se crea previamente y salta el error unknown column ‘access’

    INSERT INTO vmail.users (id,domain_id,email,password,quota,access,active)
    VALUES (DEFAULT,’1′,’usuario@dominio.tld’,MD5(‘pass’),’20’,’int’,’1′);

    quisiera saber que tipo de datos lleva ese campo para crearlo manual.

    thks

    1. @JosRA

      Puedes prescindir de este campo.