Postfix Dovecot MYSQL
 (→/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., 03: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
 
 
[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
 
 -  példa: 
 -  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
 
 -  példa: 
 -  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
 
 -  példa: 
 -  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
 
 -  példa: 
 
 -  általános elemek:
 - 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: levelek vírusírtónak való átadása
 
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"
- mysql_virtual_alias_maps.cf - virtual_alias_maps: címfordítások
 
query = SELECT destination FROM forwardings WHERE source='%s' AND active = '1'
- mysql_virtual_domains_maps.cf - virtual_mailbox_domains: a server által kiszolgált domainek listája
 
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'
- mysql_virtual_transports.cf - transport_maps:
 
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==