Postfix Dovecot MYSQL

A Unix/Linux szerverek üzemeltetése wikiből
(Változatok közti eltérés)
(/etc/postfix/main.cf)
 
(2 szerkesztő 25 közbeeső változata nincs mutatva)
1. sor: 1. sor:
== 1. Szerver alkalmazások kiválasztása ==
+
Írta: Száray Lőrinc<br />
<ul>
+
Utolsó módosítás: 2012. november<br />
<li>MTA (Mail Transfer Agent): Postfix.</li>
+
<li>: Dovecot.</li>
+
Ez a szócikk egy konkrét levelezőszerver beállítását, döntéseim indoklását írja le, a következő hármassal: Postfix, Dovecot és MYSQL. Egy Ubuntu (12.04) Linux rendszeren lett összerakva, de az itt ismertetett beállítások nagyrészt disztribúciófüggetlenek.
</ul>
+
== 2. Működés áttekintése ==
+
== Szerveralkalmazások kiválasztása ==
== 3. Egy gyakorlati megvalósítás ==
+
* [http://en.wikipedia.org/wiki/Message_transfer_agent MTA] (Mail Transfer Agent): [http://www.postfix.org/ Postfix]. Nagyon sok Linuxos levelezőszerver közül lehet válogatni, a Postfix mellett szól a jó dokumentáció, gazdag funkcionalitás, aktív fejlesztői és karbantartói gárda, széles körben elterjedt, szinte minden disztribúcióban elérhető. [http://cr.yp.to/qmail.html Qmail]-el ellentétben a postfixben sok ellenőrzési funkció kapott helyet, így megkönnyítve a SPAM elleni harcot.
  +
* [http://en.wikipedia.org/wiki/Message_delivery_agent MDA] (Mail Delivery Agent): [http://www.dovecot.org/ Dovecot]. Több open source rendszer közül a Dovecot jól skálázhatónak és robusztusnak tűnt a leírások alapján. Natívan támogatja a felhasználók adatbázisban tárolását és az SSHA ([http://en.wikipedia.org/wiki/Salt_%28cryptography%29 Salted] [http://en.wikipedia.org/wiki/SHA-2 Safe Hash Algorithm]) algoritmust, mely a felhasználók jelszavainak gyors feltörését megakadályozza. A Dovecot további előnye, hogy a levelek fiókokba helyezését is ellátja, így az esetlegesen eltérő mailbox megvalósítások nem okoznak problémát. Kipróbáltam a [http://www.courier-mta.org/ Courier]-t rendszerét is, de a tesztidőszak alatti nagyobb memóriaigénye miatt és a Dovecot előnyösebb beállítási struktúrája miatt elvetettem.
  +
* [http://en.wikipedia.org/wiki/DBMS DBMS]: [http://www.mysql.com/ MYSQL]. A MYSQL az egyik széleskörben alkalmazott adatbázis-kezelő 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.), személyes tapasztalatom ezzel volt, nem merült fel kérdés, mit válasszak. [https://www.mysql.com/products/workbench/ MySQL Workbench] segítségével az adminisztráció, tervezés és adatmanipuláció is könnyen elvégezhető.
  +
=== POP(3) vs IMAP(4) ===
  +
A szervereken, amiket építettem, nem engedélyeztem a POP3 protokollt (nem telepítettem a dovecot-pop3 csomagot), ezért ebben a szócikkben nem is foglalkozom a beállításával, a fontosabb érveket felsorolom. A [http://wikipedia.org/wiki/POP3 POPv3] protokoll első verzióját 1984-ben specifikálták, a 3-ast pedig 1988-ban. A [http://wikipedia.org/wiki/IMAP IMAP] protokoll első verziója 1986-ban készült el (jelenleg a 4. verziót használjuk) és a POP3-nál modernebb szemléletű. Érdekesség, hogy a RAID-hez hasonlóan a mozaikszó mögötti jelentés változott: Interim Mail Access Protocol (IMAPv1) -> Interactive Mail Access Protocol (IMAPv2) -> Internet Message Access Protocol (IMAP2bis - 1993, amit később IMAPv4-ben szabványosítottak, ez az, amit most használunk, az IMAPv3 zsákutcának bizonyult).
  +
* IMAP előnyei:
  +
** A POP3 alapértelmezett mechanizmusa, hogy letörli a letöltött leveleket, ez több kliens, webmail használatát ellehetetleníti. Erre születtek megoldások, a google alkalmaz egy speciális POP3 megvalósítást, egy külön flaget használ, amivel megjelöli a POP3 által letöltött leveleket, azokat már nem mutatja a kliensnek, figyelmen kívül hagyja a törlési utasításokat. POP3 a levelek egy gépre mentésére szolgál, jellemzően a kis postafiókméret promlémájának orvoslására, napjainkban nem ez jellemzi a felhasználói szokásokat.
  +
** A kliens nem csak a levelek letöltésének idejére kapcsolódhat a szerverhez, hanem folyamatosan kapcsolódhat rá, így minimális késleltetéssel értesülhet új levelek érkezéséről. Ez nem teljesen triviális, hogy előny, mivel így folyamatosan nagy mennyiségű kliens csatlakozhat a szerverhez, de nem feltétlen jobb, ha a türelmetlen felhasználó 5 percenként új kapcsolatot nyit a szerver felé levelei lekérdezéséhez?
  +
** Több kliens is csatlakozhat egyszerre egy adott e-mail fiókhoz. Ez a funkció mára vált fontossá, mivel a felhasználói igények közt szerepel, hogy a leveleket egyszerre több (telefon, tablet, laptop, stb.) eszközön nézhessék meg.
  +
** Részenkénti letöltés. A levél különböző MIME részeit (képek, tömörített fájlok, stb.), nem tölti le automatikusan, ez külön kezdeményezhető. Jelenleg nem a modemes kapcsolat, hanem a telefonok sávszélessége és/vagy adatkorlátja szab határt, további előny, hogy így a kliens a levelek meta-adatait gyorsan letölti, és egy-egy nagy méretű e-mail nem "blokkolja" az újabbak letöltését (olyan kliensek is, amik minden adatot letöltenek offline használatra, kihasználják ezt a funkciót, először letöltik az összes levél meta-adatát és utána külön a csatolmányokat).
  +
** Szerver oldali levél állapotok. Ha több klienst, webmailt is használ a felhasználó IMAPon keresztül, akkor az elolvasás/megjelölés/áthelyezés minden kliensben megjelenik.
  +
** Szerver oldali keresés. Ez nyilván komoly teljesítményt foglalhat le kiszolgálói oldalon, ha valaki visszaél vele. Ennek ellenére az alacsony sávszélességű kliensek számára hasznos például, a telefonom e-mail kliense a legújabb 10-20-stb. levelet tárolja a különböző e-mail fiókjaimhoz. Ugyanez érvényes egy webmail esetén is, ahol mindenképp szerver oldalon keresünk (Ha a kliens oldalon keresnénk, minden adatot át kellene vinnünk a kereséshez).
  +
** Levelek biztonsági mentésének feladata nem a felhasználó feladata, szerver oldalon eleve megoldott a redundáns tárolás és a rendszeres backup.
  +
* IMAP hátrányai, az extra funkciók ára:
  +
** A kliensek nem törlik a letöltött leveleiket, magasabb tárigény.
  +
** Bonyolultabb szerver logika.
  +
** Szerver oldali kereséses visszaélés.
  +
** Még mindig nem biztos, hogy elég széleskörű funkcionalitás. Pl.: címtár, naptár, stb. nem tárolható szerver oldalon.
  +
** Kétszer kell feltöltenünk az elküldött levelünket (viszont, így minden kliensen elérhetőek az elküldött levelek).
  +
  +
== 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 rendszer működéséhez szükséges adatokat 4 MYSQL táblában tároljuk, így azok könnyen menedzselhetőek. Amikor a leveleket a Postfix megkapja, átadja a különböző szűrő alkalmazásoknak. A levelező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.<br />
  +
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 email címet megadni
  +
** ha más alkalmazás használja a felhasználói adatbázist, a felhasználók azonosítása egyszerűbb
  +
** egy cég több országban használja a nemzeti domaint, viszont a központi levelezőszerverre mindenkinek elég a felhasználónevét megadnia
  +
* hátrányok
  +
** nem tartozhat több domainhez ugyanolyan felhasználónév
  +
[[Fájl:mailtop.png|frame|none|A levelek útja a rendszerben.]]
  +
== Tűzfal/NAT ==
  +
* A kliensek által kezdeményezett kapcsolatok mind TCP-t használnak
  +
* "e-mail portok":
  +
** 25: SMTP port, sok szolgáltató (otthoni) tiltja, átirányítja (van ahol kikapcsolható, pl. T-nél webes felületükön ki lehet, vezetékes kapcsolat esetén), ezt főleg más SMTP szerver fogja használni
  +
** 465: SSMTP port, titkosított SMTP, felhasználói kliensek számára
  +
** 143: IMAP port
  +
** 585: IMAP4-SSL port, ezen tapasztalat, hogy a Microsoft Outlook nem tudja használni ezekkel a beállításokkal, alapértelmezésben Dovecot nem is nyújt IMAP szolgáltatást ezen a porton
  +
** 993: IMAP4 over SSL port, a Dovecot ezt valósítja meg
  +
** 110: POP3 port (teljesség kedvéért)
  +
** 995: SPOP3 port (teljesség kedvéért)
  +
== Egy gyakorlati megvalósítás ==
  +
=== Postfix beállítása ===
  +
==== /etc/postfix/main.cf ====
  +
Beállítások, amik eltérnek az alapértékektől.
  +
* Dovecot [http://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer SASL] (Simple Authentication and Security Layer) autentikáció beállítása:
  +
A SASL egy authentikációs protokoll, ennek a segítségével a Postfix bármely ezt támogató forrásból képes azonosítani a felhasználókat.<br />
  +
[http://www.postfix.org/postconf.5.html#smtpd_sasl_type smtpd_sasl_type]: A plugin neve amit az authentikáláshoz használunk.
  +
<pre>
  +
smtpd_sasl_type = Dovecot
  +
</pre>
  +
[http://www.postfix.org/postconf.5.html#smtpd_sasl_path smtpd_sasl_path]: /var/spool/postfix/private/auth - Dovecot autentikációs socket helye (relatív a /var/spool/postfix/-hez)
  +
<pre>
  +
smtpd_sasl_path = private/auth
  +
</pre>
  +
[http://www.postfix.org/postconf.5.html#smtpd_sasl_auth_enable smtpd_sasl_auth_enable]: bekapcsoljuk a SASL authentikációt
  +
<pre>
  +
smtpd_sasl_auth_enable = yes
  +
</pre>
  +
[http://www.postfix.org/postconf.5.html#broken_sasl_auth_clients broken_sasl_auth_clients]: MicroSoft Outlook kompatibilitás
  +
<pre>
  +
broken_sasl_auth_clients = yes
  +
</pre>
  +
[http://www.postfix.org/postconf.5.html#smtpd_sasl_security_options smtpd_sasl_security_options]: nem engedjük névnélküli autentikációt
  +
<pre>
  +
smtpd_sasl_security_options = noanonymous
  +
</pre>
  +
[http://www.postfix.org/postconf.5.html#smtpd_sasl_authenticated_header smtpd_sasl_authenticated_header] beleírjuk a header-be, hogy milyen felhasználónéven azonosítottuk a felhasználónkat
  +
<pre>
  +
smtpd_sasl_authenticated_header = yes
  +
</pre>
  +
* Hálózati paraméterek:
  +
<pre>
  +
# megjelenítendő hostnév
  +
myhostname = domain1.hu
  +
myorigin = domain1.hu
  +
mydestination = localhost.domain1.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 interface-en fogad leveleket
  +
inet_interfaces = all
  +
</pre>
  +
[http://www.postfix.org/postconf.5.html#smtp_bind_address smtp_bind_address]: ha több subnet-hez is kapcsolódik a server, megadhatjuk az interface-t amin keresztül kapcsolatokat kezdeményez a Postfix
  +
<pre>
  +
smtp_bind_address = 10.0.0.24
  +
</pre>
  +
[http://www.postfix.org/postconf.5.html#mynetworks_style mynetworks_style]: nem "bízik" meg csak a localhosttól érkező kérésekben, ellentétben az egész subnettel ami az alapbeállítás
  +
<pre>
  +
mynetworks_style = host
  +
</pre>
  +
* Levelek elhelyezésére vonatkozó információk:
  +
<pre>
  +
virtual_mailbox_base = /var/vmail
  +
virtual_uid_maps = static:150
  +
virtual_gid_maps = static:8
  +
</pre>
  +
* Szerver használat
  +
<pre>
  +
#elvárjuk hogy küldjön a kilens HELO-t
  +
smtpd_helo_required = yes
  +
#spammerek idejét pocsékoljuk
  +
#és a smtpd_helo_restrictions elfogad smtpd_recipient_restrictions és smtpd_relay_restrictions elemeket, mivel később is lefuthat az ellenőrzés
  +
smtpd_delay_reject = yes
  +
</pre>
  +
* Listák, amiken végighalad a Postfix, hogy eldöntse, kitől fogad levelet. A listán végighaladva, ha az egyik feltétel teljesül, akkor elutasítja/továbbengedi a levelet.
  +
** általános elemek:
  +
*** permit: a listák végén használható, ezzel, ha minden más teszten átment, elfogadjuk a levelet
  +
*** reject: permithez hasonlóan a listák végére, ezzel elutasítjuk a levelet
  +
*** warn_if_reject: nem különálló elem, reject állítások elé tehető, így "reject_warning" bejegyzés kerül a log fájlba, főleg debuggolás esetén hasznos
  +
*** permit_mynetworks: a [http://www.postfix.org/postconf.5.html#mynetworks mynetworks] listában megadott hálózatok/IP címek számára engedélyezi a hozzáférést, ezzel a belső hálózatot/gépet nem vetjük alá további ellenőrzésnek (pl. webserver, belső levelezés, stb.)
  +
*** reject_unauth_pipelining: [http://unixlinux.tmit.bme.hu/Az_SMTP_m%C5%B1k%C3%B6d%C3%A9se#.22Early_talker.22-ek_sz.C5.B1r.C3.A9se "Early talker"]-ek szűrése, a szerver ellenőrzi, hogy az adott SMTP command-nak megfelelő adatokat küldött-e csak a kliens
  +
*** permit_sasl_authenticated: akik bejelentkeztek azokat továbbengedjük
  +
** [http://www.postfix.org/postconf.5.html#smtpd_client_restrictions smtpd_client_restrictions]: kliens alapú szűrés, csatlakozáskor
  +
*** példa: <pre>smtpd_client_restrictions = reject_rbl_client sbl.spamhaus.org, reject_rbl_client blackholes.easynet.nl, reject_rbl_client dnsbl.njabl.org</pre>
  +
*** reject_rbl_client <domain>: [http://unixlinux.tmit.bme.hu/Az_SMTP_m%C5%B1k%C3%B6d%C3%A9se#Domain-alap.C3.BA_.28RHS.29_feketelist.C3.A1k Domain-alapú] feketelisták használata
  +
** [http://www.postfix.org/postconf.5.html#smtpd_helo_restrictions smtpd_helo_restrictions]: [http://unixlinux.tmit.bme.hu/Az_SMTP_m%C5%B1k%C3%B6d%C3%A9se#HELO-ellen.C5.91rz.C3.A9s HELO] ellenőrzések
  +
*** példa: <pre>smtpd_helo_restrictions = permit_mynetworks, warn_if_reject reject_non_fqdn_hostname, reject_invalid_hostname, permit</pre>
  +
*** check_helo_access(table): egy adatbázis, hogy HELO (EHLO) üzenetnél küldött domain mi lehet
  +
** [http://www.postfix.org/postconf.5.html#smtpd_sender_restrictions smtpd_sender_restrictions]: SMTP [http://unixlinux.tmit.bme.hu/Az_SMTP_m%C5%B1k%C3%B6d%C3%A9se#MAIL_FROM-ellen.C5.91rz.C3.A9s MAIL FROM] utasításon (feladó) hajtja végre
  +
*** példa: <pre>smtpd_sender_restrictions = reject_authenticated_sender_login_mismatch, permit_sasl_authenticated, permit_mynetworks, warn_if_reject reject_non_fqdn_sender, reject_unknown_sender_domain, reject_unauth_pipelining, permit</pre>
  +
*** reject_authenticated_sender_login_mismatch: egy gyakran kihagyott, de szerintem az egyik legfontosabb ellenőrzés, a belépett felhasználók nem küldhetnek csak a saját felhasználónevükkel megegyező feladóval címzett levelet (vagy más szabályra illeszkedő). Elég nagy probléma, hogyha bármelyik felhasználónk küldhet a root, administrator, accounting, stb. nevében levelet!
  +
*** reject_non_fqdn_sender: visszautasítjuk a leveleket, ha a feladó domain nem [http://hu.wikipedia.org/wiki/Fully_qualified_domain_name FQDN]
  +
*** reject_unknown_sender_domain: visszautasítjuk azokat a leveleket, amik feladóihoz nem mi kézbesítünk és nincs [http://unixlinux.tmit.bme.hu/A_DNS_m%C5%B1k%C3%B6d%C3%A9se DNS] A, MX rekordja vagy ezek hibásak
  +
** [http://www.postfix.org/postconf.5.html#smtpd_recipient_restrictions smtpd_recipient_restrictions]: SMTP [http://unixlinux.tmit.bme.hu/Az_SMTP_m%C5%B1k%C3%B6d%C3%A9se#RCPT_TO-f.C3.A1zis 'RCPT TO'] utasításon (címzett) hajtja végre
  +
*** példa: <pre>smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_pipelining, permit_sasl_authenticated, reject_non_fqdn_recipient, reject_unknown_recipient_domain, reject_unauth_destination, check_policy_service inet:127.0.0.1:10023, permit</pre>
  +
*** reject_non_fqdn_recipient: visszautasítjuk a leveleket, ha a címzett domain nem [http://hu.wikipedia.org/wiki/Fully_qualified_domain_name FQDN]
  +
*** reject_unknown_recipient_domain: visszautasítjuk azt, a levelet amit nem mi kézbesítünk és nincs [http://unixlinux.tmit.bme.hu/A_DNS_m%C5%B1k%C3%B6d%C3%A9se DNS] A, MX rekordja vagy ezek hibásak
  +
*** reject_unauth_destination: visszautasítjuk a levelet, hogyha a domain nem szerepel a transzport táblánkban vagy nem egyezik meg a szerver egyéb azonosítójával
  +
*** check_policy_service inet:127.0.0.1:10023: Postgray ellenőrzés
  +
* MYSQL felé való átjárás, részletek az adatbázis tábláknál. Ahova több lekérdezés is tartozik, ott sorban halad végig rajtuk, ha nem talál illeszkedést.
  +
<pre>
  +
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
  +
</pre>
  +
* [http://www.postfix.org/postconf.5.html#content_filter content_filter]: levelek vírusírtónak való átadása
  +
<pre>
  +
content_filter = amavis:[127.0.0.1]:10024
  +
</pre>
  +
* [http://www.postfix.org/postconf.5.html#virtual_transport virtual_transport]: leveleket fiókokba helyezésre átadjuk a Dovecotnak (egyesével)
  +
<pre>
  +
virtual_transport = dovecot
  +
dovecot_destination_recipient_limit = 1
  +
</pre>
  +
  +
==== /etc/postfix/master.cf ====
  +
A master.cf a Postfix kapcsolatait leíró fájl.
  +
* beérkező levelek számára az smtp(25) és az smtps(465) port
  +
<pre>
  +
# ==========================================================================
  +
# service type private unpriv chroot wakeup maxproc command + args
  +
# (yes) (yes) (yes) (never) (100)
  +
# ==========================================================================
  +
smtp inet n - - - - smtpd
  +
smtps inet n - - - - smtpd
  +
</pre>
  +
* tartalom szűrők fele, itt az a lényeg, hogy felüldefiniáljuk az alap beállításokat, az innen érkező levelekre
  +
<pre>
  +
# ==========================================================================
  +
# service type private unpriv chroot wakeup maxproc command + args
  +
# (yes) (yes) (yes) (never) (100)
  +
# ==========================================================================
  +
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
  +
</pre>
  +
* Dovecot fele a levelek továbbítása
  +
<pre>
  +
# ==========================================================================
  +
# service type private unpriv chroot wakeup maxproc command + args
  +
# (yes) (yes) (yes) (never) (100)
  +
# ==========================================================================
  +
dovecot unix - n n - - pipe
  +
flags=DRhu user=vmail:mail argv=/usr/lib/dovecot/dovecot-lda -d $(recipient)
  +
</pre>
  +
  +
==== Adattárolás és adatbázis kapcsolat ====
  +
* Célszerű egy külön táblát és saját felhasználót létrehozni csak olvasási joggal a Postfixnek és a Dovecotnak. A managementet egy külön felhasználóval célszerű 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öbbi statikus adatnál ennek gyakorlati haszna nincs). Ennek segítségével egy átirányítás vagy felhasználói fiók ideiglenesen is kikapcsolható.
  +
* Ebben a konfigurációban a kvóta byteokban értendő, 0 esetén a Dovecot nem alkalmaz korlátozást.
  +
<br />
  +
Adattáblák felépítése:
  +
* users: ezt használja a Dovecot authentikálásra, kvóta információk kinyerésére, postfix pedig a feladó, illetve címzett ellenőrzésére
  +
<pre>
  +
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`)
  +
)
  +
</pre>
  +
* users példaadatok:
  +
<pre>
  +
+--------+---------+------------+----------------------------------------------------------+--------+----------+
  +
| userID | user | domain | password | active | quota |
  +
+--------+---------+------------+----------------------------------------------------------+--------+----------+
  +
| 3 | test | domain1.hu |apfAlBBFtlYefTNlFF9+RZ3Xdz8og5E/86upbmrCw64tI1Z8cTNXMQ== | 1 | 10485760 |
  +
+--------+---------+------------+----------------------------------------------------------+--------+----------+
  +
</pre>
  +
* domains: postfix számára, milyen doaminekért felelős
  +
<pre>
  +
CREATE TABLE `domains` (
  +
`domainID` int(11) NOT NULL AUTO_INCREMENT,
  +
`domain` varchar(45) NOT NULL,
  +
PRIMARY KEY (`domainID`)
  +
)
  +
</pre>
  +
* domains példaadatok:
  +
<pre>
  +
+----------+------------+
  +
| domainID | domain |
  +
+----------+------------+
  +
| 1 | domain1.hu |
  +
| 2 | domain2.hu |
  +
+----------+------------+
  +
</pre>
  +
* forwardings: postfix számára, milyen "alias"-ok vannak a renszerünkben
  +
<pre>
  +
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`)
  +
)
  +
</pre>
  +
* forwardings példaadatok:
  +
** 1: minden nem létező címre szóló levelet a lost postafiókba továbbítunk
  +
** 2-5: a különböző adminisztrációs címeket az admin postafiókba továbbítjuk
  +
<pre>
  +
+---------------+--------------------------+------------------+--------+
  +
| forwardingsID | source | destination | active |
  +
+---------------+--------------------------+------------------+--------+
  +
| 1 | @domain1.hu | lost@domain1.hu | 1 |
  +
| 2 | postmaster@domain1.hu | admin@domain1.hu | 1 |
  +
| 3 | root@domain1.hu | admin@domain1.hu | 1 |
  +
| 4 | hostmaster@domain1.hu | admin@domain1.hu | 1 |
  +
| 5 | administrator@domain1.hu | admin@domain1.hu | 1 |
  +
+---------------+--------------------------+------------------+--------+
  +
</pre>
  +
* transport: postfix számára, hova továbbítsa a beérkezett leveleket
  +
<pre>
  +
CREATE TABLE `transport` (
  +
`transportID` int(11) NOT NULL AUTO_INCREMENT,
  +
`domain` varchar(45) DEFAULT NULL,
  +
`transport` varchar(45) DEFAULT NULL,
  +
PRIMARY KEY (`transportID`)
  +
)
  +
</pre>
  +
* transport példaadatok: mind a két domainünket helyben kiszolgáljuk (":"), nem továbbítjuk (pl. ha másnak az MX tartalék levelezőszervere, az ő MX szerverei felé továbbíthatunk)
  +
<pre>
  +
+-------------+----------------+-----------+
  +
| transportID | domain | transport |
  +
+-------------+----------------+-----------+
  +
| 1 | domain1.hu | : |
  +
| 2 | domain2.hu | : |
  +
+-------------+----------------+-----------+
  +
</pre>
  +
A /etc/postfix/ mappában a következő fájlokra van szükség, amik az adatbázissal kötik össze. Mivel minden fájlnak tartalmazni kell a jelszót, ezeknek a fájloknak a hozzáférésére fokozottan figyeljünk oda!
  +
* Miden fájl elejére be kell illeszteni az adatbázis kapcsolat adatait, ezek az adatok:
  +
<pre>
  +
user = <adatbázis felhasználónév - mail>
  +
password = <adatbázis jelszó - ****>
  +
hosts = <adatbázis címe - x.x.x.x>
  +
dbname = <adatábzis tábla neve - mail>
  +
</pre>
  +
* mysql_virtual_email2email.cf - [http://www.postfix.org/postconf.5.html#virtual_alias_maps virtual_alias_maps]: felhasználók azonosítására szolgál
  +
<pre>
  +
query = SELECT concat(user, '@', domain) FROM users WHERE user='%u' AND domain="%d"
  +
</pre>
  +
* mysql_virtual_alias_maps.cf - [http://www.postfix.org/postconf.5.html#virtual_alias_maps virtual_alias_maps]: címfordítások
  +
<pre>
  +
query = SELECT destination FROM forwardings WHERE source='%s' AND active = '1'
  +
</pre>
  +
* mysql_virtual_domains_maps.cf - [http://www.postfix.org/postconf.5.html#virtual_mailbox_domains virtual_mailbox_domains]: a server által kiszolgált domainek listája
  +
<pre>
  +
query = SELECT domain FROM domains WHERE domain='%s'
  +
</pre>
  +
* mysql_virtual_email_verify.cf - [http://www.postfix.org/postconf.5.html#smtpd_sender_login_maps smtpd_sender_login_maps]: bejelentkezett felhasználó emailcímének lekérdezésére szolgál (a dokumentáció alapján a kérés hibásnak tűnhet, több órás debuggolás után ez a kérés működik, teljes email címmel nem sikerült életre keltenem a funkciót)
  +
<pre>
  +
query = SELECT user FROM users WHERE user='%u'
  +
</pre>
  +
* mysql_virtual_mailbox_maps.cf - [http://www.postfix.org/postconf.5.html#virtual_mailbox_maps virtual_mailbox_maps]: a felhasználók fiókjainak a helyét adja meg
  +
<pre>
  +
query = SELECT CONCAT(domain,'/',user) FROM users WHERE user='%u' AND active = '1'
  +
</pre>
  +
* mysql_virtual_transports.cf - [http://www.postfix.org/postconf.5.html#transport_maps transport_maps]:
  +
<pre>
  +
query = SELECT transport FROM transport WHERE domain='%s'
  +
</pre>
  +
  +
=== Dovecot beállítása ===
  +
A különböző konfigurációs fájlok előtt a számok a fájlok végrehajtásának sorrendjét garantálják. Az IMAP modult és portot (143-IMAP, 993-IMAPS) nem kell engedélyezni, mivel ha fent van a dovecot-imap csomag, magától betölti. Ezekkel a beállításokkal a 143-as titkosítatlan IMAP porton keresztül sem engedjük a klienseinknek a titkosítatlan kapcsolatot.
  +
* /etc/dovecot/conf.d/10-auth.conf - authentikációs beállítások
  +
<pre>
  +
# azonosítás csak titkosított csatornán
  +
disable_plaintext_auth = yes
  +
# legtöbb levelező ismeri és használja a 'plain' authentikációt, de az outlook csak a 'login' metódust
  +
auth_mechanisms = plain login
  +
# includeoljuk a saját adatbázis fájlunkat
  +
!include auth-sql.conf.ext
  +
</pre>
  +
* /etc/dovecot/conf.d/10-mail.conf - levelek
  +
<pre>
  +
# 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
  +
# ezeknek az értékeknek ebben a konfigurációban nincs gyakorlati jelentősége
  +
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
  +
</pre>
  +
* /etc/dovecot/conf.d/10-master.conf - authentikációs socketek beállítása
  +
<pre>
  +
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ámára az authentikációs unix socket
  +
unix_listener /var/spool/postfix/private/auth {
  +
mode = 0666
  +
user = postfix
  +
group = postfix
  +
}
  +
}
  +
</pre>
  +
* /etc/dovecot/conf.d/20-imap.conf - imap specifikus beállítások
  +
<pre>
  +
# engedélyezni kell a kvótát imapon felül
  +
mail_plugins = $mail_plugins imap_quota
  +
</pre>
  +
* /etc/dovecot/conf.d/auth-sql.conf.ext - az alkalmazott DBMS specifikálása:
  +
<pre>
  +
passdb {
  +
driver = sql
  +
args = /etc/dovecot/dovecot-sql.conf.ext
  +
}
  +
userdb {
  +
driver = sql
  +
args = /etc/dovecot/dovecot-sql.conf.ext
  +
}
  +
</pre>
  +
* /etc/dovecot/conf.d/90-quota.conf - kvóta beállítások
  +
<pre>
  +
plugin {
  +
quota = maildir:User quota
  +
quota_rule = *:bytes=1000000
  +
}
  +
</pre>
  +
* /etc/dovecot/dovecot-sql.conf.ext - Dovecot mysql lekérései:
  +
<pre>
  +
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'
  +
</pre>
  +
  +
== Mellékletek ==
  +
* Egy PHP class, ami a Dovecot számára is olvasható formátumban állít elő SSHA256 jelszavakat. A bemeneteket sehol sem ellenőrzi, ez nem ennek az osztálynak a felelőssége. Elvileg a 8 byte(karakter)-nyi só ("salt"), feleslegesen hosszú, az SHA256 elegendően jó hash, hogy egyetlen byte is elég legyen. Rövidebb értéket is lehet választani, a kisebb méretű adatbázis érdekében.
  +
<pre>
  +
<?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;
  +
}
  +
}
  +
?>
  +
</pre>
  +
2 rövid segédfájl, hogy console-ból is könnyen lehessen jelszót generálni, azért nem közvetlen a PHP fájlt hívom meg, hogy a console logban ne legyen jelszószivárgás. PHP futtatáshoz szükséges a php5-cli csomag (ha webszerveres gépen futtatod, valószínűleg fent lesz, más gépeken nem valószínű).
  +
* mkpwd.php:
  +
<pre>
  +
<?php
  +
require_once 'Crypt.php';
  +
echo ''.Crypt::generatePasswordHash($argv[1]);
  +
?>
  +
</pre>
  +
* pwd.sh:
  +
<pre>
  +
#!/bin/bash
  +
read -s -p "Type password:" pwd
  +
echo -e "\nPassword SSHA256 hash:"
  +
php mkpwd.php $pwd
  +
echo -e ""
  +
</pre>
  +
* működés közben:
  +
<pre>
  +
lorinc@carpoon:~/php$ ./pwd.sh
  +
Type password:
  +
Password SSHA256 hash:
  +
zl+M7Qbe0PzF1dprF4yE9iYyEQg03slmVI1cgZ8r6fBSbDsvfT5FPQ==
  +
</pre>

A lap jelenlegi, 2013. január 20., 04:28-kori változata

Írta: Száray Lőrinc
Utolsó módosítás: 2012. november

Ez a szócikk egy konkrét levelezőszerver beállítását, döntéseim indoklását írja le, a következő hármassal: Postfix, Dovecot és MYSQL. Egy Ubuntu (12.04) Linux rendszeren lett összerakva, de az itt ismertetett beállítások nagyrészt disztribúciófüggetlenek.

Tartalomjegyzék

[szerkesztés] 1 Szerveralkalmazások kiválasztása

  • MTA (Mail Transfer Agent): Postfix. Nagyon sok Linuxos levelezőszerver közül lehet válogatni, a Postfix mellett szól a jó dokumentáció, gazdag funkcionalitás, aktív fejlesztői és karbantartói gárda, széles körben elterjedt, szinte minden disztribúcióban elérhető. Qmail-el ellentétben a postfixben sok ellenőrzési funkció kapott helyet, így megkönnyítve a SPAM elleni harcot.
  • MDA (Mail Delivery Agent): Dovecot. Több open source rendszer közül a Dovecot jól skálázhatónak és robusztusnak tűnt a leírások alapján. Natívan támogatja a felhasználók adatbázisban tárolását és az SSHA (Salted Safe Hash Algorithm) algoritmust, mely a felhasználók jelszavainak gyors feltörését megakadályozza. A Dovecot további előnye, hogy a levelek fiókokba helyezését is ellátja, így az esetlegesen eltérő mailbox megvalósítások nem okoznak problémát. Kipróbáltam a Courier-t rendszerét is, de a tesztidőszak alatti nagyobb memóriaigénye miatt és a Dovecot előnyösebb beállítási struktúrája miatt elvetettem.
  • DBMS: MYSQL. A MYSQL az egyik széleskörben alkalmazott adatbázis-kezelő 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.), személyes tapasztalatom ezzel volt, nem merült fel kérdés, mit válasszak. MySQL Workbench segítségével az adminisztráció, tervezés és adatmanipuláció is könnyen elvégezhető.

[szerkesztés] 1.1 POP(3) vs IMAP(4)

A szervereken, amiket építettem, nem engedélyeztem a POP3 protokollt (nem telepítettem a dovecot-pop3 csomagot), ezért ebben a szócikkben nem is foglalkozom a beállításával, a fontosabb érveket felsorolom. A POPv3 protokoll első verzióját 1984-ben specifikálták, a 3-ast pedig 1988-ban. A IMAP protokoll első verziója 1986-ban készült el (jelenleg a 4. verziót használjuk) és a POP3-nál modernebb szemléletű. Érdekesség, hogy a RAID-hez hasonlóan a mozaikszó mögötti jelentés változott: Interim Mail Access Protocol (IMAPv1) -> Interactive Mail Access Protocol (IMAPv2) -> Internet Message Access Protocol (IMAP2bis - 1993, amit később IMAPv4-ben szabványosítottak, ez az, amit most használunk, az IMAPv3 zsákutcának bizonyult).

  • IMAP előnyei:
    • A POP3 alapértelmezett mechanizmusa, hogy letörli a letöltött leveleket, ez több kliens, webmail használatát ellehetetleníti. Erre születtek megoldások, a google alkalmaz egy speciális POP3 megvalósítást, egy külön flaget használ, amivel megjelöli a POP3 által letöltött leveleket, azokat már nem mutatja a kliensnek, figyelmen kívül hagyja a törlési utasításokat. POP3 a levelek egy gépre mentésére szolgál, jellemzően a kis postafiókméret promlémájának orvoslására, napjainkban nem ez jellemzi a felhasználói szokásokat.
    • A kliens nem csak a levelek letöltésének idejére kapcsolódhat a szerverhez, hanem folyamatosan kapcsolódhat rá, így minimális késleltetéssel értesülhet új levelek érkezéséről. Ez nem teljesen triviális, hogy előny, mivel így folyamatosan nagy mennyiségű kliens csatlakozhat a szerverhez, de nem feltétlen jobb, ha a türelmetlen felhasználó 5 percenként új kapcsolatot nyit a szerver felé levelei lekérdezéséhez?
    • Több kliens is csatlakozhat egyszerre egy adott e-mail fiókhoz. Ez a funkció mára vált fontossá, mivel a felhasználói igények közt szerepel, hogy a leveleket egyszerre több (telefon, tablet, laptop, stb.) eszközön nézhessék meg.
    • Részenkénti letöltés. A levél különböző MIME részeit (képek, tömörített fájlok, stb.), nem tölti le automatikusan, ez külön kezdeményezhető. Jelenleg nem a modemes kapcsolat, hanem a telefonok sávszélessége és/vagy adatkorlátja szab határt, további előny, hogy így a kliens a levelek meta-adatait gyorsan letölti, és egy-egy nagy méretű e-mail nem "blokkolja" az újabbak letöltését (olyan kliensek is, amik minden adatot letöltenek offline használatra, kihasználják ezt a funkciót, először letöltik az összes levél meta-adatát és utána külön a csatolmányokat).
    • Szerver oldali levél állapotok. Ha több klienst, webmailt is használ a felhasználó IMAPon keresztül, akkor az elolvasás/megjelölés/áthelyezés minden kliensben megjelenik.
    • Szerver oldali keresés. Ez nyilván komoly teljesítményt foglalhat le kiszolgálói oldalon, ha valaki visszaél vele. Ennek ellenére az alacsony sávszélességű kliensek számára hasznos például, a telefonom e-mail kliense a legújabb 10-20-stb. levelet tárolja a különböző e-mail fiókjaimhoz. Ugyanez érvényes egy webmail esetén is, ahol mindenképp szerver oldalon keresünk (Ha a kliens oldalon keresnénk, minden adatot át kellene vinnünk a kereséshez).
    • Levelek biztonsági mentésének feladata nem a felhasználó feladata, szerver oldalon eleve megoldott a redundáns tárolás és a rendszeres backup.
  • IMAP hátrányai, az extra funkciók ára:
    • A kliensek nem törlik a letöltött leveleiket, magasabb tárigény.
    • Bonyolultabb szerver logika.
    • Szerver oldali kereséses visszaélés.
    • Még mindig nem biztos, hogy elég széleskörű funkcionalitás. Pl.: címtár, naptár, stb. nem tárolható szerver oldalon.
    • Kétszer kell feltöltenünk az elküldött levelünket (viszont, így minden kliensen elérhetőek az elküldött levelek).

[szerkesztés] 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 rendszer működéséhez szükséges adatokat 4 MYSQL táblában tároljuk, így azok könnyen menedzselhetőek. Amikor a leveleket a Postfix megkapja, átadja a különböző szűrő alkalmazásoknak. A levelező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 email címet megadni
    • ha más alkalmazás használja a felhasználói adatbázist, a felhasználók azonosítása egyszerűbb
    • egy cég több országban használja a nemzeti domaint, viszont a központi levelezőszerverre mindenkinek elég a felhasználónevét megadnia
  • hátrányok
    • nem tartozhat több domainhez ugyanolyan felhasználónév
Fájl:mailtop.png
A levelek útja a rendszerben.

[szerkesztés] 3 Tűzfal/NAT

  • A kliensek által kezdeményezett kapcsolatok mind TCP-t használnak
  • "e-mail portok":
    • 25: SMTP port, sok szolgáltató (otthoni) tiltja, átirányítja (van ahol kikapcsolható, pl. T-nél webes felületükön ki lehet, vezetékes kapcsolat esetén), ezt főleg más SMTP szerver fogja használni
    • 465: SSMTP port, titkosított SMTP, felhasználói kliensek számára
    • 143: IMAP port
    • 585: IMAP4-SSL port, ezen tapasztalat, hogy a Microsoft Outlook nem tudja használni ezekkel a beállításokkal, alapértelmezésben Dovecot nem is nyújt IMAP szolgáltatást ezen a porton
    • 993: IMAP4 over SSL port, a Dovecot ezt valósítja meg
    • 110: POP3 port (teljesség kedvéért)
    • 995: SPOP3 port (teljesség kedvéért)

[szerkesztés] 4 Egy gyakorlati megvalósítás

[szerkesztés] 4.1 Postfix beállítása

[szerkesztés] 4.1.1 /etc/postfix/main.cf

Beállítások, amik eltérnek az alapértékektől.

  • Dovecot SASL (Simple Authentication and Security Layer) autentikáció beállítása:

A SASL egy authentikációs protokoll, ennek a segítségével a Postfix bármely ezt támogató forrásból képes azonosítani a felhasználókat.
smtpd_sasl_type: A plugin neve amit az authentikáláshoz használunk.

smtpd_sasl_type = Dovecot

smtpd_sasl_path: /var/spool/postfix/private/auth - Dovecot autentikációs socket helye (relatív a /var/spool/postfix/-hez)

smtpd_sasl_path = private/auth

smtpd_sasl_auth_enable: bekapcsoljuk a SASL authentikációt

smtpd_sasl_auth_enable = yes

broken_sasl_auth_clients: MicroSoft Outlook kompatibilitás

broken_sasl_auth_clients = yes

smtpd_sasl_security_options: nem engedjük névnélküli autentikációt

smtpd_sasl_security_options = noanonymous

smtpd_sasl_authenticated_header beleírjuk a header-be, hogy milyen felhasználónéven azonosítottuk a felhasználónkat

smtpd_sasl_authenticated_header = yes
  • Hálózati paraméterek:
# megjelenítendő hostnév
myhostname = domain1.hu
myorigin = domain1.hu
mydestination = localhost.domain1.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 interface-en fogad leveleket
inet_interfaces = all

smtp_bind_address: ha több subnet-hez is kapcsolódik a server, megadhatjuk az interface-t amin keresztül kapcsolatokat kezdeményez a Postfix

smtp_bind_address = 10.0.0.24

mynetworks_style: nem "bízik" meg csak a localhosttól érkező kérésekben, ellentétben az egész subnettel ami az alapbeállítás

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
  • Szerver használat
#elvárjuk hogy küldjön a kilens HELO-t
smtpd_helo_required = yes
#spammerek idejét pocsékoljuk
#és a smtpd_helo_restrictions elfogad smtpd_recipient_restrictions és smtpd_relay_restrictions elemeket, mivel később is lefuthat az ellenőrzés
smtpd_delay_reject = yes
  • Listák, amiken végighalad a Postfix, hogy eldöntse, kitől fogad levelet. A listán végighaladva, ha az egyik feltétel teljesül, akkor elutasítja/továbbengedi a levelet.
    • általános elemek:
      • permit: a listák végén használható, ezzel, ha minden más teszten átment, elfogadjuk a levelet
      • reject: permithez hasonlóan a listák végére, ezzel elutasítjuk a levelet
      • warn_if_reject: nem különálló elem, reject állítások elé tehető, így "reject_warning" bejegyzés kerül a log fájlba, főleg debuggolás esetén hasznos
      • permit_mynetworks: a mynetworks listában megadott hálózatok/IP címek számára engedélyezi a hozzáférést, ezzel a belső hálózatot/gépet nem vetjük alá további ellenőrzésnek (pl. webserver, belső levelezés, stb.)
      • reject_unauth_pipelining: "Early talker"-ek szűrése, a szerver ellenőrzi, hogy az adott SMTP command-nak megfelelő adatokat küldött-e csak a kliens
      • permit_sasl_authenticated: akik bejelentkeztek azokat továbbengedjük
    • smtpd_client_restrictions: kliens alapú szűrés, csatlakozáskor
      • példa:
        smtpd_client_restrictions = reject_rbl_client sbl.spamhaus.org, reject_rbl_client blackholes.easynet.nl, reject_rbl_client dnsbl.njabl.org
      • reject_rbl_client <domain>: Domain-alapú feketelisták használata
    • smtpd_helo_restrictions: HELO ellenőrzések
      • példa:
        smtpd_helo_restrictions = permit_mynetworks, warn_if_reject reject_non_fqdn_hostname, reject_invalid_hostname, permit
      • check_helo_access(table): egy adatbázis, hogy HELO (EHLO) üzenetnél küldött domain mi lehet
    • smtpd_sender_restrictions: SMTP MAIL FROM utasításon (feladó) hajtja végre
      • példa:
        smtpd_sender_restrictions =  reject_authenticated_sender_login_mismatch, permit_sasl_authenticated, permit_mynetworks, warn_if_reject reject_non_fqdn_sender, reject_unknown_sender_domain, reject_unauth_pipelining, permit
      • reject_authenticated_sender_login_mismatch: egy gyakran kihagyott, de szerintem az egyik legfontosabb ellenőrzés, a belépett felhasználók nem küldhetnek csak a saját felhasználónevükkel megegyező feladóval címzett levelet (vagy más szabályra illeszkedő). Elég nagy probléma, hogyha bármelyik felhasználónk küldhet a root, administrator, accounting, stb. nevében levelet!
      • reject_non_fqdn_sender: visszautasítjuk a leveleket, ha a feladó domain nem FQDN
      • reject_unknown_sender_domain: visszautasítjuk azokat a leveleket, amik feladóihoz nem mi kézbesítünk és nincs DNS A, MX rekordja vagy ezek hibásak
    • smtpd_recipient_restrictions: SMTP 'RCPT TO' utasításon (címzett) hajtja végre
      • példa:
        smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_pipelining, permit_sasl_authenticated, reject_non_fqdn_recipient, reject_unknown_recipient_domain, reject_unauth_destination, check_policy_service inet:127.0.0.1:10023, permit
      • reject_non_fqdn_recipient: visszautasítjuk a leveleket, ha a címzett domain nem FQDN
      • reject_unknown_recipient_domain: visszautasítjuk azt, a levelet amit nem mi kézbesítünk és nincs DNS A, MX rekordja vagy ezek hibásak
      • reject_unauth_destination: visszautasítjuk a levelet, hogyha a domain nem szerepel a transzport táblánkban vagy nem egyezik meg a szerver egyéb azonosítójával
      • check_policy_service inet:127.0.0.1:10023: Postgray ellenőrzés
  • MYSQL felé való átjárás, részletek az adatbázis tábláknál. Ahova több lekérdezés is tartozik, ott sorban halad végig rajtuk, ha nem talál illeszkedést.
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
content_filter = amavis:[127.0.0.1]:10024
  • virtual_transport: leveleket fiókokba helyezésre átadjuk a Dovecotnak (egyesével)
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1

[szerkesztés] 4.1.2 /etc/postfix/master.cf

A master.cf a Postfix kapcsolatait leíró fájl.

  • beérkező levelek számára az smtp(25) és az smtps(465) port
# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
smtp      inet  n       -       -       -       -       smtpd
smtps     inet  n       -       -       -       -       smtpd
  • tartalom szűrők fele, itt az a lényeg, hogy felüldefiniáljuk az alap beállításokat, az innen érkező levelekre
# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
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
# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
dovecot unix    -       n       n       -       -       pipe
        flags=DRhu user=vmail:mail argv=/usr/lib/dovecot/dovecot-lda -d $(recipient)

[szerkesztés] 4.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 csak olvasási joggal a Postfixnek és a Dovecotnak. A managementet egy külön felhasználóval célszerű 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öbbi statikus adatnál ennek gyakorlati haszna nincs). Ennek segítségével egy átirányítás vagy felhasználói fiók ideiglenesen is kikapcsolható.
  • Ebben a konfigurációban a kvóta byteokban értendő, 0 esetén a Dovecot nem alkalmaz korlátozást.


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

  • users: ezt használja a Dovecot authentikálásra, kvóta információk kinyerésére, postfix pedig a feladó, illetve címzett ellenőrzésére
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    | domain1.hu |apfAlBBFtlYefTNlFF9+RZ3Xdz8og5E/86upbmrCw64tI1Z8cTNXMQ==  |      1 | 10485760 |
+--------+---------+------------+----------------------------------------------------------+--------+----------+
  • domains: postfix számára, milyen doaminekért felelős
CREATE TABLE `domains` (
  `domainID` int(11) NOT NULL AUTO_INCREMENT,
  `domain` varchar(45) NOT NULL,
  PRIMARY KEY (`domainID`)
)
  • domains példaadatok:
+----------+------------+
| domainID | domain     |
+----------+------------+
|        1 | domain1.hu |
|        2 | domain2.hu |
+----------+------------+
  • forwardings: postfix számára, milyen "alias"-ok vannak a renszerünkben
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ímre szóló levelet a lost postafiókba továbbítunk
    • 2-5: a különböző adminisztrációs címeket az admin postafiókba továbbítjuk
+---------------+--------------------------+------------------+--------+
| forwardingsID | source                   | destination      | active |
+---------------+--------------------------+------------------+--------+
|             1 | @domain1.hu              | lost@domain1.hu  |      1 |
|             2 | postmaster@domain1.hu    | admin@domain1.hu |      1 |
|             3 | root@domain1.hu          | admin@domain1.hu |      1 |
|             4 | hostmaster@domain1.hu    | admin@domain1.hu |      1 |
|             5 | administrator@domain1.hu | admin@domain1.hu |      1 |
+---------------+--------------------------+------------------+--------+
  • transport: postfix számára, hova továbbítsa a beérkezett leveleket
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: mind a két domainünket helyben kiszolgáljuk (":"), nem továbbítjuk (pl. ha másnak az MX tartalék levelezőszervere, az ő MX szerverei felé továbbíthatunk)
+-------------+----------------+-----------+
| transportID | domain         | transport |
+-------------+----------------+-----------+
|           1 | domain1.hu     | :         |
|           2 | domain2.hu     | :         |
+-------------+----------------+-----------+

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

  • Miden fájl elejére be kell illeszteni az adatbázis kapcsolat adatait, ezek az adatok:
user = <adatbázis felhasználónév - mail>
password = <adatbázis jelszó - ****>
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 (a dokumentáció alapján a kérés hibásnak tűnhet, több órás debuggolás után ez a kérés működik, teljes email címmel nem sikerült életre keltenem a funkciót)
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'

[szerkesztés] 4.2 Dovecot beállítása

A különböző konfigurációs fájlok előtt a számok a fájlok végrehajtásának sorrendjét garantálják. Az IMAP modult és portot (143-IMAP, 993-IMAPS) nem kell engedélyezni, mivel ha fent van a dovecot-imap csomag, magától betölti. Ezekkel a beállításokkal a 143-as titkosítatlan IMAP porton keresztül sem engedjük a klienseinknek a titkosítatlan kapcsolatot.

  • /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' authentikációt, de az outlook csak a 'login' metódust
auth_mechanisms = plain login
# includeoljuk a saját adatbázis fájlunkat
!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
# ezeknek az értékeknek ebben a konfigurációban nincs gyakorlati jelentősége 
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ámá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 specifikus 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'

[szerkesztés] 5 Mellékletek

  • Egy PHP class, ami a Dovecot számára is olvasható formátumban állít elő SSHA256 jelszavakat. A bemeneteket sehol sem ellenőrzi, ez nem ennek az osztálynak a felelőssége. Elvileg a 8 byte(karakter)-nyi só ("salt"), feleslegesen hosszú, az SHA256 elegendően jó hash, hogy egyetlen byte is elég legyen. Rövidebb értéket is lehet választani, a kisebb méretű adatbázis érdekében.
<?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édfájl, hogy console-ból is könnyen lehessen jelszót generálni, azért nem közvetlen a PHP fájlt hívom meg, hogy a console logban ne legyen jelszószivárgás. PHP futtatáshoz szükséges a php5-cli csomag (ha webszerveres gépen futtatod, valószínűleg fent lesz, más gépeken nem valószínű).

  • mkpwd.php:
<?php
require_once 'Crypt.php';
echo ''.Crypt::generatePasswordHash($argv[1]);
?>
  • pwd.sh:
#!/bin/bash
read -s -p "Type password:" pwd
echo -e "\nPassword SSHA256 hash:"
php mkpwd.php $pwd
echo -e ""
  • működés közben:
lorinc@carpoon:~/php$ ./pwd.sh 
Type password:
Password SSHA256 hash:
zl+M7Qbe0PzF1dprF4yE9iYyEQg03slmVI1cgZ8r6fBSbDsvfT5FPQ==
Személyes eszközök