Arxius

Postfix + Mysql + Courier-imap-ssl

Escrit al 2004-04-05 00:00:00 per whats_up

En aquest article intentaré explicar com muntar un sistema de correu 100% en woody força complet. Suposo que serà de gran ajut ja que ens la meva recerca, vaig trobar poca cosa que valgués realment la pena, i no cal dir, en català ni somiar-ho!El nostre sistema de correu, tindrà molts usuaris, per tant és inviable fer-ho sense cap tipus de “suport” a l'hora de gestionar els usuaris. Si ho féssim "a pel", el que passaria és que tindríem un /etc/passwd de un "colló" de files. Per solucionar aquest problema, he triat la genial base de dades MySQL. Per oferir comoditat i seguretat als usuaris tractant els seus correus, posarem IMAP-SSL. Al utilitzar aquest sistema podrem tenir una infinitat d'usuaris amb comptes de correu sense haber de tenir compta local al sistema, seràn usuaris virtuals.


En principi amb aquest article, n'hauríeu de tenir prou per muntar el sistema de correu una mica complet, que tindrà el servidor de correu (Postfix), una base de dades (MySQL) per gestionar tots els usuaris, i un sistema de treballar amb el correu directament sobre el servidor de forma segura (IMAP_SSL).

Aquest article, es basa només en la distribució estable de Debian (woody), i només utilitzarem (de moment) paquets precompilats per muntar el nostre servidor.



MYSQL


Primer de tot començarem per la base de dades, ja que potser es el més independent.
Necessitarem els paquets del servidor i del client, per tant:

apt-get install mysql-server mysql-client

I ja els tenim instal·lats! :)

Ara anirem a crear una base de dades i un usuari que la pugui manegar. Si teniu l'Apache i el PHP recomano instal·lar un paquet que s'anomena phpmyadmin que us servirà per manejar les bases de dades de forma gràfica i amb un gran potencial

Ens connectem a la base de dades..

bunker:~# mysql -h localhost -u root -p

(la contrasenya per defecte està en blanc)

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 462 to server version: 3.23.49-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql>

crearem una base de dades que s'anomenarà correu:

mysql> create database correu;
Query OK, 1 row affected (0.04 sec)

mirem que s'hagi creat

mysql> show databases
+----------+
| Database |
+----------+
| correu |
| mysql |
| test |
+----------+
3 rows in set (0.00 sec)

Creem la taula “passwd” ens la que hi tindrem totes les dades:

mysql>use correu;
mysql>create table passwd(
id char(128)DEFAULT '' NOT NULL,
crypt char(32)DEFAULT '' NOT NULL,
name char(32)DEFAULT '' NOT NULL,
uid int(10) unsigned NOT NULL,
gid int(10) unsigned NOT NULL,
home char(255)DEFAULT '' NOT NULL,
maildir char(255)DEFAULT '' NOT NULL,
KEY id (id(128))
);

Query OK, 0 rows affected (0.00 sec)

Mirem com ens ha quedat la taula..

mysql> describe passwd;

+---------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------------+------+-----+---------+-------+
| id | char(128) | | MUL | | |
| crypt | char(32) | | | | |
| name | char(32) | | | | |
| uid | int(10) unsigned | | | | |
| gid | int(10) unsigned | | | | |
| home | char(255) | | | | |
| maildir | char(255) | | | | |
+---------+------------------+------+-----+---------+-------+
7 rows in set (0.00 sec)

Creen la taula que ens servirà per establir alias:

mysql>CREATE TABLE aliases (
alias varchar(128) NOT NULL default '',
rcpt varchar(255) NOT NULL default ''
) TYPE=MyISAM;

Mirem com ens ha quedat la taula..

mysql> describe aliases;

+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| alias | varchar(128) | | | | |
| rcpt | varchar(255) | | | | |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.01 sec)

Creem la taula transport que ens servirà per a encaminar cap a dominis o subdominis (en aquest article no l'utilitzarem):

mysql> CREATE TABLE transport (
id int(11) NOT NULL auto_increment,
domain varchar(128) NOT NULL default '',
destination varchar(128) NOT NULL default '',
PRIMARY KEY (id),
UNIQUE KEY domain (domain)
) TYPE=MyISAM;

Mirem com ens ha quedat..

mysql> describe transport;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | | PRI | NULL | auto_increment |
| domain | varchar(128) | | UNI | | |
| destination | varchar(128) | | | | |
+-------------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

Creem la taula relocated, que ens servirà per anunciar si algun usuari del nostre sistema s'ha canviat de direcció de correu (tampoc l'utilitzarem en aquest article):

mysql> CREATE TABLE relocated (
id int(11) NOT NULL auto_increment,
email varchar(128) NOT NULL default '',
destination varchar(128) NOT NULL default '',
PRIMARY KEY (id)
) TYPE=MyISAM;

Mirem com ens ha quedat..

+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | | PRI | NULL | auto_increment |
| email | varchar(128) | | | | |
| destination | varchar(128) | | | | |
+-------------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

Ara crearem un usuari que tingui tots els permisos a aquestes taules:

mysql> GRANT ALL ON correu.passwd TO postfix@localhost IDENTIFIED BY "pass_per_l'user_postfix";
mysql> GRANT ALL ON correu.aliases TO postfix@localhost IDENTIFIED BY "pass_per_l'user_postfix";
mysql> GRANT ALL ON correu.transport TO postfix@localhost IDENTIFIED BY "pass_per_l'user_postfix";
mysql> GRANT ALL ON correu.relocated TO postfix@localhost IDENTIFIED BY "pass_per_l'user_postfix";


Inserim 2 entrades d'exemple per a les nostres proves, hem de tenir en compte que el tros de l'id avans de @ ha de ser igual al nom d'usuari:

mysql>insert into passwd (id,crypt,name,uid,gid,home,maildir)
values("sarrio@salles.mine.nu",encrypt('password'),"sarrio",
"1001","8","/","/var/spool/mail/sarrio/Maildir/");

Query OK, 1 row affected (0.01 sec)


mysql>insert into passwd (id,crypt,name,uid,gid,home,maildir)
values("ferran@salles.mine.nu",encrypt('password'),"ferran",
"1002","8","/","/var/spool/mail/ferran/Maildir/");

Query OK, 1 row affected (0.00 sec)

Mirem com ens ha quedat la cosa...

mysql> select * from passwd;
+-----------------------+----------+--------+------+-----+------+---------------------------------+
| id | crypt | name | uid | gid | home | maildir |
+-----------------------+----------+--------+------+-----+------+---------------------------------+
| sarrio@salles.mine.nu | password | sarrio | 1001 | 8 | / | /var/spool/mail/sarrio/Maildir/ |
| ferran@salles.mine.nu | password | ferran | 1002 | 8 | / | /var/spool/mail/ferran/Maildir/ |
+-----------------------+----------+--------+------+-----+------+---------------------------------+
2 rows in set (0.00 sec)

Ara afagirem alguns aliases necessaris:

#El del administrador del sistema de correu
mysql>insert into aliases (alias,rcpt) values("postmaster","sarrio@salles.mine.nu");
#Creem com una llista de distribució, al enviar un correu a llista@salles.mine.nu, el rebran tots els usuaris que apareixen a rcpt
mysql>insert into aliases (alias,rcpt) values("llista","usuari1@salles.mine.nu, usuari2@terra.es, usuari3@hotmail.com");
#Creem un alias de tota la vida. En cas que a alias aoaregui un altre domini, (ex: wekk.net) haurem de posar aquest domini
#a mydestination del main.cf perquè funcioni.
mysql>insert into aliases (alias,rcpt) values("Sarri@wekk.net","sarrio@salles.mine.nu");

Ja l'hem acabat, ja podem sortir:

mysql> quit
Bye

Una cosa important a fer, seria canviar la contrasenya del root, ja que per defecte et ve en blanc.

Ho podeu fer escrivint això estant dins..

mysql> SET PASSWORD FOR root@localhost=password('la_nova_contrasenya');
mysql> FLUSH PRIVILEGES;

Ara ja tenim la base de dades creada, amb els usuaris ben posats, per tant ja podem anar cap al Postfix!

Fins aquí l'apartat de la nostre base de dades!



POSTFIX


Necessitarem els paquets del programa i el suport per el MySQL, per tant:

apt-get install postfix postfix-ldap postfix-mysql postfix-pcre

Un cop instal·lats anirem al directori de configuració del programa /etc/postfix i modificarem els següents arxius:

  • main.cf
    (aquest arxiu és l'arxiu principal de configuració de Postfix)

    #Com que les opcions parlen bastant per elles soles, explicaré només les
    #més importants, o les que és més fàcil que hageu de canviar

    ###########################
    # ubicació dels directoris #
    ###########################
    queue_directory = /var/spool/postfix
    command_directory = /usr/sbin
    daemon_directory = /usr/lib/postfix
    program_directory = /usr/lib/postfix
    mail_spool_directory = /var/spool/mail/

    #propietari del procès
    mail_owner = postfix
    #el nom de la vostre màquina
    myhostname = salles.mine.nu
    #el lloc per defecte des de on s'enviaran els mails
    myorigin = $myhostname

    #control de correu entrant/sortint
    #quan el postfix rebi un correu, mirarà aquesta variable, si la destinació
    #del correu està entre aquests hosts, se'l quedarà, i l'intentarà entregar,
    #ja que voldrà dir que ell és el servidor de correu d'aquestes direccions
    #i que el correu és per un usuari dels que tenim a la base de dades
    mydestination = salles.mine.nu, localhost, localhost.localdomain, salles , crade.shacknet.nu, elizir.mine.nu wekk.net

    #aquí és on li dius quines maquines poden enviar correus (pot fer un relay)
    #que seran les mateixes que les que estan a $mydestination
    relay_domains = $mydestination

    #definir quines ip's formen part de la teva xarxa (útil per després)
    mynetworks = 192.168.1.0/24

    ###########################
    # mysql #
    ###########################
    virtual_mailbox_base=/
    virtual_mailbox_maps=mysql:/etc/postfix/mysql_virt.cf
    virtual_uid_maps=mysql:/etc/postfix/ids.cf
    virtual_gid_maps=mysql:/etc/postfix/gids.cf
    local_transport = virtual
    virtual_maps = mysql:/etc/postfix/aliases.cf


    ############################
    # alguns altres parametres de configuració #
    ############################

    #Moltes d'aquestes opcions ja et venen definides per defecte, i poden ser innecessaries.
    disable_vrfy_command = yes
    message_size_limit = 10485760
    mailbox_size_limit = 0

    #a aquesta opció hi posem Maildir perquè és la que més ens interessa.
    #Això el que farà serà permetre al client(l'usuari de la compte de correu)
    #guardar en diferents carpetes tots els seus correus per tenir-los més
    #ordenats. Fins ara, es solien anar guardant tots els correus en un arxiu, un
    #a continuació de l'altre, i si el client en volia baixar un, s'havia de baixar
    #tot l'arxiu. Amb aquest sistema el client només es baixa els correus que vol
    #llegir
    home_mailbox = Maildir/

    smtpd_banner = $myhostname ESMTP server
    maximal_queue_lifetime = 5d
    #Ens notificarà entre altres coses quan algú intenti fer servir el nostre sistema per enviar spam
    notify_classes = resource, software, policy
    smtpd_helo_required = yes
    local_destination_concurrency_limit = 2
    default_destination_concurrency_limit = 10

    #Opció per a debugació. Us la deixo aqui per si algú té problemes.
    #debug_peer_level = 2

    #I si algú està intentant adaptar aquest article per el postfix2...
    #IDENTIFICACIO D'USUARIS LOCALS (és obligatori amb el postfix 2)
    #local_recipient_maps = $alias_maps unix:passwd.byname

    Ara hem de crear els arxius on li diem a quina base de dades, taula i columna està cada dada, heu d'anar en compte de no deixar espais darrere del password, que sino més d'un s'estarà trencant les banyes per una tonteria com aquesta.

  • gids.cf

    #Usuari i contrasenya per accedir al servidor MySQL
    user=postfix
    password=pass_per_l'user_postfix
    #Nom de la base de dades i la taula
    dbname=correu
    table=passwd
    #El camp d'on trèiem el gid
    select_field=gid
    where_field=id
    #El host que té el MySQL. Nosaltres ens connectarem via socket perquè així
    #no ens cal haver de tenir el MySQL escoltant a l'exterior
    hosts=unix:mysqld.sock


  • ids.cf

    #Usuari i contrassenya per accedir al servidor MySQL
    user=postfix
    password=pass_per_l'user_postfix
    #Nom de la base de dades i la taula
    dbname=correu
    table=passwd
    #El camp d'on traiem el uid
    select_field=uid
    where_field=id
    #El host que té el MySQL. Nosaltres ens connectarem via socket perquè així no ens cal haver de tenir el MySQL escoltant a l'exterior
    hosts=unix:mysqld.sock


  • aliases.cf

    #Usuari i contrassenya per accedir al servidor MySQL
    user=postfix
    password=pass_per_l'user_postfix
    #Nom de la base de dades i la taula
    dbname=correu
    table=aliases
    #Particularitats de la taula
    select_field=rcpt
    where_field=alias
    #El host que té el MySQL. Nosaltres ens connectarem via socket perquè així no ens cal haver de tenir el MySQL escoltant a l'exterior
    hosts=unix:mysqld.sock


  • mysql_virt.cf

    #Usuari i contrasenya per accedir al servidor MySQL
    user=postfix
    password=pass_per_l'user_postfix
    #Nom de la base de dades i la taula
    dbname=correu
    table=passwd
    #El camp que triem, serà el que hi haurà el directori amb el nom de
    #l'usuari pel qual siguin els correus
    select_field=maildir
    where_field=id
    #El host que té el MySQL. Nosaltres ens connectarem via socket perquè així
    #no ens cal haver de tenir el MySQL escoltant a l'exterior
    hosts=unix:mysqld.sock

    Com que el Postfix s'executa dins d'una gàbia, per a que pugui accedir al socket del MySQL i poder treballar junts, hem de fer un enllaç dur del socket cap al directori de treball del Postfix, per tant:

    ln -f /var/run/mysqld/mysqld.sock /var/spool/postfix/mysqld.sock

    quan re iniciem la màquina, l'enllaç desapareixerà, el que podem fer, és modificar l'arxiu d'inici del MySQL per tal de que es crei cada vegada que s'iniciï

    /etc/init.d/mysql

    #!/bin/sh -e
    #
    # MySQL daemon start/stop script.
    #
    # Debian version. Based on the original by TcX.
    #

    test $DEBIAN_SCRIPT_DEBUG && set -v -x

    test -x /usr/sbin/mysqld || exit 0

    SELF=$(cd $(dirname $0); pwd -P)/$(basename $0)
    CONF=/etc/mysql/my.cnf
    MYADMIN="/usr/bin/mysqladmin --defaults-extra-file=/etc/mysql/debian.cnf"

    # Safeguard (relative paths, core dumps..)
    cd /
    umask 077
    export PATH=/bin:/usr/bin

    # mysqladmin likes to read /root/.my.cnf. This is usually not what I want
    # as many admins e.g. only store a password without a username there and
    # so break my scripts.
    export HOME=/etc/mysql/

    is_mysqld_alive () {
    if [ -n "`$MYADMIN ping 2>/dev/null`" ]; then return 0; else return 1; fi
    }

    case "$1" in
    'start')
    # Start daemon
    echo -n "Starting MySQL database server: mysqld"
    /usr/bin/safe_mysqld > /dev/null 2>&1 &
    for i in 1 2 3 4 5 6; do
    if is_mysqld_alive; then break; fi
    sleep 1
    done
    if is_mysqld_alive; then

    #aquesta és la línia que afegim:
    ln -f /var/run/mysqld/mysqld.sock /var/spool/postfix/mysqld.sock
    echo "."
    else
    echo "...failed."
    fi
    ;;


    (.......l'arxiu continua....)

    Un cop fet això ens posarem a definir els permisos per els arxius de configuració que hem anat tocant. És important que només els pugui llegir el Postfix per la informació que contenen, per tant:

    chmod -R 640 *
    chown -R root *
    chgrp -R postfix *
    chmod a+x post-install
    chmod a+x postfix-script
    chmod a+r main.cf dynamicmaps.cf



    IMAP


    Per a poder oferir a l'usuari una bona interfície per treballar amb el correu i seguretat, he triat IMAP-SSL, que al treballar amb el correu directament del servidor, ens estalviem forces possibles problemes :)

    Anirem per instal·lar els paquets necessaris:

    apt-get install courier-imap courier-authmysql courier-authdaemon courier-base courier-imap-ssl courier-ssl

    Quan es configurin us demanaran unes dades que seran per crear els certificats.
    Un cop instal·lats anirem per configurar-lo. Està al directori /etc/courier

    El primer arxiu que modificarem serà:

  • authdaemonrc

    #l'única línia imprescindible, és:

    authmodulelist="authmysql"

    #per començar només i deixarem aquesta, més endavant ja fareu les
    #proves ;)

    el segon...

  • authmysqlrc

    #aquest arxiu és l'important, hi ha tota la informació de les caselles de la base d dades

    MYSQL_SERVER localhost
    MYSQL_USERNAME postfix
    MYSQL_PASSWORD pass_per_l'user_postfix
    MYSQL_PORT 3306
    MYSQL_OPT 0
    MYSQL_DATABASE correu
    MYSQL_USER_TABLE passwd
    MYSQL_CRYPT_PWFIELD crypt
    DEFAULT_DOMAIN salles.mine.nu
    MYSQL_UID_FIELD uid
    MYSQL_GID_FIELD gid
    MYSQL_LOGIN_FIELD id
    MYSQL_HOME_FIELD home
    MYSQL_NAME_FIELD name
    MYSQL_MAILDIR_FIELD maildir

    el tercer..

  • imapd-ssl

    No recordo si per defecte l'opció IMAPDSTARTTLS et ve a YES, si no et ve, ja li esteu posant, i amb l'arxiu IMAPD al revés, si l'opció IMAPDSTART us ve a YES ja l'esteu posant a no, perquè el vostre sistema només tindrà operatiu IMAP amb SSL :)

    Ara només falta re iniciar cada servei:

    bunker:~# /etc/init.d/courier-authdaemon restart
    Stopping Courier authdaemon: done.
    Starting Courier authdaemon: done.

    bunker:~# /etc/init.d/courier-imap restart
    Stopping Courier IMAP server: imapd.
    Starting Courier IMAP server: imapd.

    bunker:~# /etc/init.d/courier-imap-ssl restart
    Stopping Courier IMAP-SSL server: imapd-ssl.
    Starting Courier IMAP-SSL server: imapd-ssl.

    bunker:~# /etc/init.d/mysql restart
    Stopping MySQL database server: mysqld.
    Starting MySQL database server: mysqld.

    bunker:~# /etc/init.d/postfix restart
    Stopping mail transport agent: Postfix.
    Starting mail transport agent: Postfix.

    mirem quins serveis tenim oberts a la nostre màquina...

    bunker:~# nmap localhost

    Starting nmap V. 2.54BETA31 ( www.insecure.org/nmap/ )
    Interesting ports on localhost (127.0.0.1):
    (The 1549 ports scanned but not shown below are in state: closed)
    Port State Service
    25/tcp open smtp
    993/tcp open imaps

    Nmap run completed -- 1 IP address (1 host up) scanned in 0 seconds

    i bingo!!, només el Postfix i el IMAP-SSL escoltant des de fora, a veure si el MySQL també està preparat...

    bunker:~# /etc/init.d/mysql status
    /usr/bin/mysqladmin Ver 8.23 Distrib 3.23.49, for pc-linux-gnu on i686
    Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
    This software comes with ABSOLUTELY NO WARRANTY. This is free software,
    and you are welcome to modify and redistribute it under the GPL license

    Server version 3.23.49-log
    Protocol version 10
    Connection Localhost via UNIX socket
    UNIX socket /var/run/mysqld/mysqld.sock
    Uptime: 2 min 21 sec

    Jejeje tot pinta bé. Ja es podria dir que tot funciona, només falta fer una cosa, una simple cosa que si ens la deixem ens donarà molts mal de caps...

    Hem d'enviar un correu a cadascun dels usuaris que hàgim creat al sistema, ja que al rebre el correu, es crearà l'estructura de directoris a /var/spool/mail, si no ho féssim, ens donaria error al voler accedir per IMAP al nostre servidor
    Un cop enviat el correu, si tot ha anat bé ens apareixerà una carpeta per a cada usuari a /var/spool/mail

    Per depurar tots els errors possibles, és important que feu servir els logs. Pels qui no ho sàpiguen estan a /var/log, tots els programes aniran afegint les seves línies als corresponents fitxers. El que es queda més curt en el tema és el courier, i de veritat que es nota ;)

    I fins aquí hem arribat!

    En principi ja està la primera part del nostre servidor de correu. Ho he anat fent tot força de memòria, per tant agrairia moltíssim que la gent que el provés em comentés si hi falta alguna cosa, si hi sobra o si no s'entén.

    Molta sort a tothom!
  • Categories: Articles, Servidor


    Comentaris

    • què en fem del mailman? molt bó l'article i molt útil pel que veig, no cal disposar de mailman per fer la llista de correu segons tu, oi? ;) el problema seria, com es pot actualitzar la llista que està posada a mysql? a través d'un php-mysql que miri dins de la munió d'adreces per trobar-ne una i esborrar-la? i amb lo divertit que és que et surti [títol_de_la_llista_de_correu] ... fins aviat!

      Escrit al 2006-12-25 22:29:03 per Anònim

    • RE: què en fem del mailman? Home, el mailman t'ofereix moltissimes opcions més! Aquest article anomeno com fer una petita llista de distribució, però no se ni si és pot dir així, ja que en realitat l'unic que es fa, es associar una direcció de correu a moltes. Depenent de les teves necessitats en tindràs prou, però és molt provable que hagis d'acavar instal·lant el mailman per a poder veure els correus vells, enviar notificacions, poder afegir denegar gent, etc.

      Escrit al 2006-12-25 22:34:12 per whats_up

    • domini Bones, T'has currat una bona recerca!! Just ahir parlàvem de fer un servidor de correu i potser web per al nostre Col·lectiu. Podriem instal·lar-hi una Debian amb aquests paquets i fer que tingues un domini @colectiu.com ??? Gràcies albertsanchez@correucatala.com

      Escrit al 2006-12-25 22:35:24 per Anònim

    • Re: Postfix + Mysql + Courier- Res... nomes dir que he moltes felicitats que hagi fet aquest article. Em vaig estar mirant el de bulma, i no hi va pas haver collons de fer-ho anar amb aquella manera que explica allà. Dec 19 18:26:34 debian postfix/smtpd[1523]: fatal: no SASL authentication mechanisms i no hi havia pas maneres de sortir d'aquí, tot i que em vaig mirar mig internet xD

      Escrit al 2006-12-25 22:36:04 per Anònim

    • Re: Postfix + Mysql + Courier- No es mereixen, jo tb vaig patir lo meu per aconseguir muntar-m'ho a casa, i per això vaig fer l'article, pq no vaig trobar enlloc on expliquès bé com fer-ho :P Sort!

      Escrit al 2006-12-25 22:36:42 per whats_up

    Arxius