Postfix Dovecot MYSQL

A Unix/Linux szerverek üzemeltetése wikiből
(Változatok közti eltérés)
a (Visszavontam Carpoon (vita | szerkesztései) szerkesztését (oldid: 5165))
32. sor: 32. sor:
 
<pre>
 
<pre>
 
# megjelenítendő hostnév
 
# megjelenítendő hostnév
myhostname = domain1.hu
+
myhostname = carpoon.hu
myorigin = domain1.hu
+
myorigin = carpoon.hu
mydestination = localhost.domain1.hu, localhost
+
mydestination = localhost.carpoon.hu, localhost
 
# azok a hálózatok amiket biztonságosnak ítélünk és bizonyos ellenőrzéseket átugrunk ezekről a címekről
 
# azok a hálózatok amiket biztonságosnak ítélünk és bizonyos ellenőrzéseket átugrunk ezekről a címekről
 
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
 
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
130. sor: 130. sor:
 
| userID | user | domain | password | active | quota |
 
| userID | user | domain | password | active | quota |
 
+--------+---------+------------+----------------------------------------------------------+--------+----------+
 
+--------+---------+------------+----------------------------------------------------------+--------+----------+
| 3 | test | domain1.hu |apfAlBBFtlYefTNlFF9+RZ3Xdz8og5E/86upbmrCw64tI1Z8cTNXMQ== | 1 | 10485760 |
+
| 3 | test | carpoon.hu |apfAlBBFtlYefTNlFF9+RZ3Xdz8og5E/86upbmrCw64tI1Z8cTNXMQ== | 1 | 10485760 |
 
+--------+---------+------------+----------------------------------------------------------+--------+----------+
 
+--------+---------+------------+----------------------------------------------------------+--------+----------+
 
</pre>
 
</pre>
143. sor: 143. sor:
 
* domains példaadatok:
 
* domains példaadatok:
 
<pre>
 
<pre>
+----------+------------+
+
+----------+---------------+
| domainID | domain |
+
| domainID | domain |
+----------+------------+
+
+----------+---------------+
| 1 | domain1.hu |
+
| 1 | carpoon.hu |
| 2 | domain2.hu |
+
| 2 | mattewvigo.hu |
+----------+------------+
+
+----------+---------------+
 
</pre>
 
</pre>
 
* forwardings:
 
* forwardings:
167. sor: 167. sor:
 
| forwardingsID | source | destination | active |
 
| forwardingsID | source | destination | active |
 
+---------------+--------------------------+------------------+--------+
 
+---------------+--------------------------+------------------+--------+
| 1 | @domain1.hu | lost@domain1.hu | 1 |
+
| 1 | @carpoon.hu | lost@carpoon.hu | 1 |
| 2 | postmaster@domain1.hu | admin@domain1.hu | 1 |
+
| 2 | postmaster@carpoon.hu | admin@carpoon.hu | 1 |
| 3 | root@domain1.hu | admin@domain1.hu | 1 |
+
| 3 | root@carpoon.hu | admin@carpoon.hu | 1 |
| 4 | hostmaster@domain1.hu | admin@domain1.hu | 1 |
+
| 4 | hostmaster@carpoon.hu | admin@carpoon.hu | 1 |
| 5 | administrator@domain1.hu | admin@domain1.hu | 1 |
+
| 5 | administrator@carpoon.hu | admin@carpoon.hu | 1 |
 
+---------------+--------------------------+------------------+--------+
 
+---------------+--------------------------+------------------+--------+
 
</pre>
 
</pre>
188. sor: 188. sor:
 
| transportID | domain | transport |
 
| transportID | domain | transport |
 
+-------------+----------------+-----------+
 
+-------------+----------------+-----------+
| 1 | domain1.hu | : |
+
| 1 | carpoon.hu | : |
| 2 | domain2.hu | : |
+
| 2 | matthewvigo.hu | : |
 
+-------------+----------------+-----------+
 
+-------------+----------------+-----------+
 
</pre>
 
</pre>

A lap 2012. október 3., 10:51-kori változata

Tartalomjegyzék

1 Szerver alkalmazások kiválasztása

Az email rendszert amit bemutatok egy honlap rendszerhez tartozik. Szempont volt hogy közös felhasználói adatábzis legyes és hogy minden platform képes legyen a felhasználókat authentikálni. A rendzser minden felhasználója autómatikusan kapott egy email címet.
Az általam válaszott szerver alkalazások, inkoklás miért ezek mellett döntöttem:

  • MTA (Mail Transfer Agent): Postfix.
  • MDA (Mail Delivery Agent): Dovecot. Több open source rendszert megnézetem, ezek közül a dovecot jól skálázható, robusztus. Natívan támogatja a felhasználók adatbázisban tárolását és az SSHA(Salted Safe Hash Algorithm) agloritmust. Dovecot további előnye, hogy a levelek fiókokba helyezését is el tudja látni így az esetlegesen eltérő megvalósítások mailbox megvalósítások nem okoznak hibát. Élesben kipróbáltam a Courier-t is, de sokkal nagyobb volt a memóriaigénye a tesztidőszak alatt.
  • DBMS: MYSQL. A MYSQL az egyik széleskörben alkalmazott adatbáziskezelő rendszer, könnyen használható különböző programozási nyelvek alól, ami a project megvalósításánál fontos szempont volt (php, node.js, java, stb).

2 Működés áttekintése

A levelek fogadásáról és küldéséről a postfix gondoskodik. A levelek elhelyezéséről, tartóstárba írásáról, azonosításáról pedig a dovecot. A működéshez szükséges adatokat 4 MYSQL táblában tárolja, így azok könnyen managelhetőek. A leveleket a postfix amikor megkapja átadja a különböző szűrő alkalmazásoknak ezek egyenlőre nem részei ennek az írásnak. A levelelzőszerverek a leveleket a /var/vmail/ mappába teszik, a leveleket mint vmail(uid: 150) felhasználó teszik be, aki a mail(gid: 8) csoport tagja. Lehetőség van minden fiók számára saját linux felhasználó létrehozására ezzel biztonságosabbá téve a fiók hozzáférését, ha az IMAP szerverben biztonsági rés lenne.
A felhasználókról külön tároljuk a felhasználónevüket és a domainjüket, amihez az emailcím tartozik, ennek megvannak a maga sajátosságai.

  • előnyök
    • azonosításnál elég a felhasználónév megadása nem kell a teljes emailcímet megadni
    • ha nem csak a levelekhasználják a felhasználói adatbázis azok számára is könnyebb a használat
  • hátrányok
    • nem tartozhat több domainhez ugyan olyan felhasználónév, vagy ha ezt szeretnénk akkor elveszítjük az előnyöket

Fájl:mailtop.png

3 Egy gyakorlati megvalósítás

3.1 Postfix beállítása

3.1.1 main.cf

Beállítások amik eltérnek az alapértékektől (teljes file a melléketek közt).

  • Dovecot SASL autentikáció beállítása:
smtpd_sasl_type = dovecot
#/var/spool/postfix/private/auth - dovecot auth socket
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain =
smtpd_sasl_authenticated_header = yes
  • Hálózati paraméterek:
# megjelenítendő hostnév
myhostname = carpoon.hu
myorigin = carpoon.hu
mydestination = localhost.carpoon.hu, localhost
# azok a hálózatok amiket biztonságosnak ítélünk és bizonyos ellenőrzéseket átugrunk ezekről a címekről
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
# minden interfacen fogad leveleket
inet_interfaces = all
# több subnethez is kapcsolódik a server, megadhatjuk az interfacet amin keresztül kapcsolatokat kezdeményez a szerver
default_transport = 10.0.0.24
mynetworks_style = host
  • Levelek elhelyezésére vonatkozó információk:
virtual_mailbox_base = /var/vmail
virtual_uid_maps = static:150
virtual_gid_maps = static:8
  • MYSQL felé való átjárás, részletek az adatábzistábláknál. Ahova több lekérés is tartozik, ott
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf, mysql:/etc/postfix/mysql_virtual_email2email.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
transport_maps = mysql:/etc/postfix/mysql_virtual_transports.cf
smtpd_sender_login_maps = mysql:/etc/postfix/mysql_virtual_email_verify.cf
  • Levelek virusírtónak való átadása:
content_filter = amavis:[127.0.0.1]:10024
  • Levelek fiókokba helyezése dovecotnak való átadása:
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1

3.1.2 master.cf

A master.cf a postfix kapcsolatati leíró file.

  • beérkező levelek számára a 25-ös és a ssl port
smtp      inet  n       -       -       -       -       smtpd
smtps     inet  n       -       -       -       -       smtpd
  • tartalom szűrők fele
amavis  unix    -       -       -       -       2       smtp
        -o smtp_data_done_timeout=1200
        -o smtp_send_xforward_command=yes
        -o disable_dns_lookups=yes
        -o max_use=20
127.0.0.1:10025 inet    n       -       -       -       -       smtpd
        -o content_filter=
        -o local_recipient_maps=
        -o relay_recipient_maps=
        -o smtpd_restriction_classes=
        -o smtpd_delay_reject=no
        -o smtpd_client_restrictions=permit_mynetworks,reject
        -o smtpd_helo_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o smtpd_data_restrictions=reject_unauth_pipelining
        -o smtpd_end_of_data_restrictions=
        -o mynetworks=127.0.0.0/8
        -o smtpd_error_sleep_time=0
        -o smtpd_soft_error_limit=1001
        -o smtpd_hard_error_limit=1000
        -o smtpd_client_connection_count_limit=0
        -o smtpd_client_connection_rate_limit=0
        -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks
  • dovecot fele a levelek továbbítása
dovecot unix    -       n       n       -       -       pipe
        flags=DRhu user=vmail:mail argv=/usr/lib/dovecot/dovecot-lda -d $(recipient)

3.1.3 Adattárolás és adatbázis kapcsolat

  • Célszerű egy külön táblát és saját felhasználót létrehozni postfixnek és dovecotnak és csak olvasási joggot adni az accountra. A managementet egy külön felhasználóval lehet végezni.
  • Két táblában van 'active' oszlop ezeket a sorokat a lekérések csak 1 érték esetén veszik figyelembe (ezt minden táblánál meg lehetne tenni, de a többinél ennek gyakorlati haszna nem lenne). Ennek a segítségével egy átirányátás, vagy felhasználói fiók ideiglenesen is kikapcsolható.
  • Ebben a konfigurációban a quota byteokban értendő, 0 esetén a dovecot nem alkalmaz korlátozást.


Adattáblák felépítése:

  • users:
CREATE TABLE `users` (
  `userID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user` varchar(128) NOT NULL,
  `domain` varchar(128) NOT NULL,
  `password` varchar(128) DEFAULT '',
  `active` int(11) NOT NULL DEFAULT '0',
  `quota` int(10) unsigned NOT NULL DEFAULT '10485760',
  PRIMARY KEY (`userID`)
)
  • users példaadatok:
+--------+---------+------------+----------------------------------------------------------+--------+----------+
| userID | user    | domain     | password                                                 | active | quota    |
+--------+---------+------------+----------------------------------------------------------+--------+----------+
|      3 | test    | carpoon.hu |apfAlBBFtlYefTNlFF9+RZ3Xdz8og5E/86upbmrCw64tI1Z8cTNXMQ==  |      1 | 10485760 |
+--------+---------+------------+----------------------------------------------------------+--------+----------+
  • domains:
CREATE TABLE `domains` (
  `domainID` int(11) NOT NULL AUTO_INCREMENT,
  `domain` varchar(45) NOT NULL,
  PRIMARY KEY (`domainID`)
)
  • domains példaadatok:
+----------+---------------+
| domainID | domain        |
+----------+---------------+
|        1 | carpoon.hu    |
|        2 | mattewvigo.hu |
+----------+---------------+
  • forwardings:
CREATE TABLE `forwardings` (
  `forwardingsID` int(11) NOT NULL AUTO_INCREMENT,
  `source` varchar(128) NOT NULL,
  `destination` varchar(128) NOT NULL,
  `active` int(11) NOT NULL DEFAULT '1',
  PRIMARY KEY (`forwardingsID`)
)
  • forwardings példaadatok:
    • 1: minden nem létező címere szóló levelet a lost postafiókba továbbítunk
    • 2-5: a kölönböző adminisztrációs címket az admin postafiókba továbbítjuk
+---------------+--------------------------+------------------+--------+
| forwardingsID | source                   | destination      | active |
+---------------+--------------------------+------------------+--------+
|             1 | @carpoon.hu              | lost@carpoon.hu  |      1 |
|             2 | postmaster@carpoon.hu    | admin@carpoon.hu |      1 |
|             3 | root@carpoon.hu          | admin@carpoon.hu |      1 |
|             4 | hostmaster@carpoon.hu    | admin@carpoon.hu |      1 |
|             5 | administrator@carpoon.hu | admin@carpoon.hu |      1 |
+---------------+--------------------------+------------------+--------+
  • transport:
CREATE TABLE `transport` (
  `transportID` int(11) NOT NULL AUTO_INCREMENT,
  `domain` varchar(45) DEFAULT NULL,
  `transport` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`transportID`)
)
  • transport példaadatok: mindekét domainünket helyben kiszolgáljuk, nem továbbítjuk (pl ha másnak az MX tartalék levelezőszervere vagyunk, az ő elsődleges servere felé továbbítunk)
+-------------+----------------+-----------+
| transportID | domain         | transport |
+-------------+----------------+-----------+
|           1 | carpoon.hu     | :         |
|           2 | matthewvigo.hu | :         |
+-------------+----------------+-----------+

A /etc/postfix/ mappába a következő fileokra van szükség, amik az adatbázissal kötik össze. Mivel minden filenak tartalmazni kell a jelszót ezeknek a fileoknak a hozzáférésére fokozottan figyeljünk oda!

  • Miden file elejére be kell illeszteni az adatbázis kapcsolat adatait ezek az adatokatok:
user = <adatbázis felhasználónév - mail>
password = <adatbázisjelszó - ****>
hosts = <adatbázis címe - x.x.x.x>
dbname = <adatábzis tábla neve - mail>
  • mysql_virtual_email2email.cf - virtual_alias_maps: felhasználók azonosítására szolgál
query = SELECT concat(user, '@', domain) FROM users WHERE user='%u' AND domain="%d"
query = SELECT destination FROM forwardings WHERE source='%s' AND active = '1'
query = SELECT domain FROM domains WHERE domain='%s'
  • mysql_virtual_email_verify.cf - smtpd_sender_login_maps: bejelentkezett felhasználó emailcímének lekérdezésére szolgál
query = SELECT user FROM users WHERE user='%u'
  • mysql_virtual_mailbox_maps.cf - virtual_mailbox_maps: a felhasználók fiókjainak a helyét adja meg
query = SELECT CONCAT(domain,'/',user) FROM users WHERE user='%u' AND active = '1'
query = SELECT transport FROM transport WHERE domain='%s'

3.2 Dovecot beállítása

A különböző konfigurációs fileok elött számok a fileok végrehajtásának sorrendjét garantálják.

  • /etc/dovecot/conf.d/10-auth.conf - authentikációs beállítások
# azonosítás csak titkosított csatornán
disable_plaintext_auth = yes
# legtöbb levelező ismeri és használja a 'plain' autentikációt, de az outlook csak a 'login' megtódust
auth_mechanisms = plain login
# includeoljuk a saját adatbázisfileunkat
!include auth-sql.conf.ext
  • /etc/dovecot/conf.d/10-mail.conf - levelek
# postafiókok helye
mail_location = maildir:/var/vmail/%d/%n
# levelek írásához/olvasásához használt felhasználó, és csoport
mail_uid = vmail
mail_gid = mail
# ezek az értékek ebben a konfigurációban nem
first_valid_uid = 150
last_valid_uid = 150
first_valid_gid = 8
last_valid_gid = 8
# meg kell adni a plugin könyvtárat ha használni akarunk kvótát
mail_plugin_dir = /usr/lib/dovecot/modules
  • /etc/dovecot/conf.d/10-master.conf - authentikációs socketek beállítása
service auth {
# dovecot saját folyamatai számára az authentikációs unix socket
  unix_listener auth-userdb {
    mode = 0600
    user = vmail
    group = mail
  }
# postfix szára az authentikációs unix socket
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }
}
  • /etc/dovecot/conf.d/20-imap.conf - imap sepcifikus beállítások
# engedélyezni kell a kvótát imapon felül
  mail_plugins = $mail_plugins imap_quota
  • /etc/dovecot/conf.d/auth-sql.conf.ext - az alkalmazott DBMS specifikálása:
passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
  • /etc/dovecot/conf.d/90-quota.conf - kvóta beállítások
plugin {
  quota = maildir:User quota
  quota_rule = *:bytes=1000000
}
  • /etc/dovecot/dovecot-sql.conf.ext - dovecot mysql lekérései:
driver = mysql
connect = host=<adatbázis címe - x.x.x.x> dbname=<adatbázis felhasználónév - mail> user=<adatábzis tábla neve - mail> password=<adatbázisjelszó - ****>
default_pass_scheme = SSHA256
password_query = SELECT user as user, password, concat('/var/vmail/', domain,'/%n') as userdb_home, concat('maildir:/var/vmail/', domain,'/%n') as userdb_mail, 150 as userdb_uid, 8 as userdb_gid FROM users WHERE user = '%n' AND active ='1'
user_query = SELECT concat('/var/vmail/', domain,'/%n') as home, concat('maildir:/var/vmail/', domain,'/%n') as mail, 150 AS uid, 8 AS gid, concat('*:bytes=', quota) AS quota_rule FROM users WHERE user = '%n' AND active = '1'

4 Mellékletek

  • Egy php class ami a dovecot számára is olvasható formátumban állít elő SSHA256 jelszavakat.
<?php
class Crypt {
    public static $allowedABC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    public static $allowed =    '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz{|}~[\]^_!#$%&()*+,-./`:;<=>?';
    public static function authenticate($ssha, $password) {
        $salt = substr(base64_decode($ssha, true), 32);
        if(Crypt::calculatePasswordHash($password, $salt) == $ssha) {
            return true;
        } else {
            return false;
        }
    }
    public static function generatePasswordHash($password) {
        $salt = Crypt::randomCharsFull(8);
        return base64_encode(hash('sha256', $password . $salt, TRUE) . $salt);
    }
    public static function calculatePasswordHash($password, $salt) {
        return base64_encode(hash('sha256', $password . $salt, TRUE) . $salt);
    }
    public static function randomCharsFull($length){
        $string = '';
        $limit = strlen(Crypt::$allowed);
        for($i = 0 ; $i < $length ; $i++) {
            $string .= substr(Crypt::$allowed, mt_rand(0, $limit-1), 1);
        }
        return $string;
    }
    public static function randomCharsAbc($length){
        $string = '';
        $limit = strlen(Crypt::$allowedABC);
        for($i = 0 ; $i < $length ; $i++) {
            $string .= substr(Crypt::$allowedABC, mt_rand(0, $limit-1), 1);
        }
        return $string;
    }
}
?>

2 rövid segédfile, hogy consoleból is könnyen lehessen jelszót generálni

mkpwd.php:
<?php
require_once 'Crypt.php';
echo ''.Crypt::generatePasswordHash($argv[1]);
?>
mkpwd.sh:
#!/bin/bash
read -s -p "Type password:" pwd
echo -e "\nPassword SSHA256 hash:"
php mkpwd.php $pwd
echo -e ""
Személyes eszközök