Postfix, Dovecot en MySQL met CentOS

Door B2 op vrijdag 22 juni 2012 15:51 - Reacties (25)
Categorie: HOWTO : Homeserver, Views: 5.831

Update : deze blog is inmiddels in een geŁpdate ook te vinden op gZeel.nl

Er bestaan verschillende applicaties die gebruikt kunnen worden om een mail server op te zetten op Linux. In deze blog wil ik laten zien hoe je dat kunt doen met Postfix als MTA en Dovecot als IMAP/POP server om gebruikers hun mail op te laten halen. Postfix en Dovecot zijn beide standaard pakketten in RedHat Linux/CentOS. Postfix en Dovecot zijn goed te integreren, ik zal dan ook laten zien hoe je Dovecot de authenticatie voor Postfix kunt laten afhandelen.

De makkelijkste manier om een mail server op te zetten is door alle mailgebruikers aan te maken als standaard gebruikers (dus met een entry in /etc/passwd) en een maildir directory in hun homedir.
Het nadeel hieraan is dat wanneer je meerdere domeinen om deze mailserver wil hosten dit nogal omslachtig gaat. Je kunt dan beter gebruik maken van virtuele domeinen en gebruikers. Deze domeinen en gebruikers maak je dan aan in een database (in dit geval MySQL). Om het beheer makkelijk te maken installeer ik ook een php frontend, Postfix Admin.

Het diagram hieronder laat zien hoe het e.e.a. in elkaar zit :

http://wiki.mediatemple.net/images/Postfix_dovecot_chart.png

Ik begin met het installeren van Apache httpd, php en MySQL. Als je httpd al hebt draaien heb je deze pakketten waarschijnlijk al geinstalleerd. De php-mbstring en php-imap pakketten zijn nodig voor Postfix Admin.

code:
1
# yum install httpd mysql-server php php-mbstring php-imap php-mysql



Installeer Postfix en Dovecot. Postfix is waarschijnlijk al aanwezig op het systeem.

code:
1
# yum install postfix dovecot



Als het de eerste keer dat je MySQL opzet moet er wat configuratie werk gedaan worden :

code:
1
# service mysqld start



Dit zorgt er voor dat de server start, voer daarna het onderstaande commando uit om het MySQL root wachtwoord in te stellen en wat sample rommel op te ruimen.

code:
1
# /usr/bin/mysql_secure_installation


Als extra beveiligingsmaatregel kan in /etc/my.cnf de bind_address optie worden aangepast zodat MySQL alleen connecties vanaf de localhost accepteert.

code:
1
vi /etc/my.cnf



code:
1
bind-address=127.0.0.1


Herstart hierna de MySQL server

code:
1
service mysqld restart


Als MySQL automatisch gestart moet worden met het booten van het systeem voer dan het volgende commando uit

code:
1
# chkconfig mysqld on



Setup mail database
Als de MySQL server eenmaal draaiende is, moet er nog een database aangemaakt worden om de mail configuratie in op te slaan en een database user voor Postfix en Dovecot.

Log in bij MySQL als de MySQL root gebruiker :

code:
1
# mysql -u root -p


Maak een database aan, ik noem deze 'mail'

code:
1
mysql> CREATE DATABASE mail;


Maak een database user aan 'mail_admin' en geef deze genoeg rechten op de database. Vervang <WACHTWOORD> door je eigen gekozen wachtwoord.

code:
1
2
3
mysql> GRANT ALL ON mail.* TO 'mail_admin'@'localhost' IDENTIFIED BY '<WACHTWOORD>';
mysql> FLUSH PRIVILEGES;
mysql> quit;



Setup Postfix Admin
Download Postfix Admin van de sourceforge project site

code:
1
# wget http://sourceforge.net/projects/postfixadmin/files/postfixadmin/postfixadmin_2.3.tar.gz/download


Installeer het bijvoorbeeld in /usr/share/postfixadmin

code:
1
2
# tar xzf postfixadmin_2.3.tar.gz
# mv postfixadmin-2.3/ /usr/share/postfixadmin


Apache httpd moet een configuratie file hebben voor postfixadmin

code:
1
# vi /etc/httpd/conf.d/postfixadmin.conf


Insert de volgende code :

code:
1
2
3
4
5
6
7
8
<Directory "/usr/share/postfixadmin">
Order Allow,Deny
Allow from all
</Directory>

Alias /postfixadmin /usr/share/postfixadmin
Alias /PostFixAdmin /usr/share/postfixadmin
Alias /PostfixAdmin /usr/share/postfixadmin


Herstart Apache httpd om de wijzigingen actief te maken:

code:
1
# service httpd restart


Nu zou PostfixAdmin bereikbaar moeten zijn via http://domeinofip/postfixadmin
Eventueel zou je de postfixadmin.conf file nog zo aan kunnen passen dat deze alleen bereikbaaris vanuit je interne netwerk.

PostFixAdmin
Er moet nog het e.e.a. geconfigureerd worden aan postfixadmin.
Open hiervoor het volgende bestand :

code:
1
# vi /usr/share/postfixadmin/config.inc.php


verander

code:
1
$CONF['configured'] = false;


in

code:
1
$CONF['configured'] = true;


Vul de database gegevens in (verander wachtwoord in je eerder gekozen wachtwoord:

code:
1
2
3
4
5
6
7
8
9
10
// Database Config
// mysql = MySQL 3.23 and 4.0, 4.1 or 5
// mysqli = MySQL 4.1+
// pgsql = PostgreSQL
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'mail_admin';
$CONF['database_password'] = '<WACHTWOORD>';
$CONF['database_name'] = 'mail';
$CONF['database_prefix'] = '';


Het adres van de postmaster kun je nog aanpassen

code:
1
$CONF['admin_email'] = 'postmaster@eigendomeinnaam.nl';


Andere interessante instellingen kunnen zijn :

code:
1
$CONF['domain_path'] = 'YES';


Om de mailboxen op te slaan onder een domeinnaam path. Dus bijvoorbeeld : /var/mail/vhosts/eigendomeinnaam.nl/user/
en

code:
1
$CONF['domain_in_mailbox'] = 'NO';


om de username+domeinnaam te gebruiken, dus /var/mail/vhosts/eigendomeinnaam.nl/user@eigendomeinnaam.nl/
Ik heb hier voor NO gekozen, zodat het bij /var/mail/vhosts/eigendomeinnaam.nl/user/ blijft.

De volgende settings kunnen nog aangepast worden om de defaults te zetten voor quota, aantal mailboxen en aliasses.

code:
1
2
3
$CONF['aliases'] = '100';
$CONF['mailboxes'] = '100';
$CONF['maxquota'] = '100';


Wanneer je gebruik wilt gaan maken van quotas zijn de volgende opties van belang:

code:
1
2
3
$CONF['quota'] = 'YES';
$CONF['used_quotas'] = 'YES';
$CONF['new_quota_table'] = 'YES';



Nu het configuratiebestand klaar is kan de setup gestart worden. Ga hier voor naar

code:
1
http://www.eigendomeinnaam.nl/postfixadmin/setup.php


De setup test of alle benodigde packages geÔnstalleerd zijn. Hierna moet een setup wachtwoord opgegeven worden. Dit wachtwoord wordt gehashed, en moet vervolgens in /usr/shared/postfixadmin/config.inc.php ingevoerd worden :

code:
1
vi /usr/shared/postfixadmin/config.inc.php


Zoek de volgende regel, en verander changeme in de hash.

code:
1
$CONF['setup_password'] = 'changeme'


Daarna moet er nog een super-admin account aangemaakt worden. Ik heb hiervoor admin@domeinnaam.nl gekozen. Het moet in een email formaat, ook als het account geen mail gaat ontvangen.

Postfix
Postfix heeft de meeste configuratie opties in /etc/postfix/main.cf staan. Je kunt Postfix configureren met het postconf commando, maar ik vind het sneller werken om direct de main.cf aan te passen.

code:
1
vi /etc/postfix/main.cf


Verander de volgende opties :

code:
1
2
3
4
5
6
7
myhostname = mail.eigendomeinnaam.nl
mydomain = eigendomeinnaam.nl
myorigin = $mydomain
inet_interfaces = all
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
mynetworks = 127.0.0.0/8
home_mailbox = Maildir/



Onderstaande code zorgt voor de samenwerking qua authenticatie tussen Postfix en Dovecot

code:
1
2
3
4
5
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, permit
broken_sasl_auth_clients = yes


Herstart hierna postfix.

code:
1
# service postfix restart



Virtual Domains Setup
Als je Virtual Domains wilt ondersteunen moeten er nog een aantal extra dingen in de configuratie geregeld worden.

Maak als eerste een user aan welke eigenaar is van alle mail directories.

code:
1
# useradd -u 5000 -d /var/mail/vhosts/ -m -s /sbin/nologin vmail



Voor de samenwerking tussen Postfix en MySQL moeten er weer een aantal configuratieopties in /etc/postfix/main.cf gezet worden.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# The follwing lines connect Postfix with the MySQL database that contains information about
# the virtual users/accounts hosted. See proxymap(8) virtual(5) and mysql_table(5)
#
virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf
#
virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf
#
virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
#
# Additional for quota support
virtual_create_maildirsize = yes
virtual_mailbox_extended = yes
virtual_mailbox_limit_maps = mysql:/etc/postfix/mysql_virtual_mailbox_limit_maps.cf
virtual_mailbox_limit_override = yes
virtual_maildir_limit_message = Sorry, this user has exceeded their disk space quota, please try again later.
virtual_overquota_bounce = yes
#
#user/group voor de mail directories
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
#
proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $virtual_mailbox_limit_maps



Hierboven hebben we aangegeven dat Postfix informatie over de virtuele adressen uit MySQL moet halen (via mysql_virtual_domains_maps.cf, etc.), maar deze bestanden moeten we eerst nog aanmaken:

code:
1
# vi /etc/postfix/mysql_virtual_domains_maps.cf


Voeg de volgende regels toe:

code:
1
2
3
4
5
6
7
user = mail_admin
password = <WACHTWOORD>
hosts = localhost
dbname = mail
query          = SELECT domain FROM domain WHERE domain='%s' AND active = '1'
#optional query to use when relaying for backup MX
#query           = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1'



code:
1
# vi /etc/postfix/mysql_virtual_alias_maps.cf


Voeg ook hier de volgende regels toe :

code:
1
2
3
4
5
user = mail_admin
password = <WACHTWOORD>
hosts = localhost
dbname = mail
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'



code:
1
# vi /etc/postfix/mysql_virtual_mailbox_maps.cf



code:
1
2
3
4
5
user = mail_admin
password = <WACHTWOORD>
hosts = localhost
dbname = mail
query = SELECT CONCAT(domain,'/',maildir) FROM mailbox WHERE username='%s' AND active = 1


Als je quotas wilt ondersteunen moet je het volgende bestand ook nog aanmaken :

code:
1
# vi /etc/postfix/mysql_virtual_mailbox_limit_maps.cf



code:
1
2
3
4
5
user = mail_admin
password = <WACHTWOORD>
hosts = localhost
dbname = mail
query = SELECT quota FROM mailbox WHERE username='%s' AND active = '1'



Dovecot LDA
We kunnen Dovecot's LDA (local delivery agent) gebruiken om de mails uiteindelijk in de inbox van de users te krijgen. Postfix heeft zelf ook een LDA, maar die van Dovecot is iets uitgebreider met oa quota support en is sneller met IMAP door indexing.

code:
1
# vi /etc/postfix/main.cf


Voeg de volgende twee regels toe:

code:
1
2
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1


Nu moet de andere configuratie file van postfix nog bewerkt worden :

code:
1
# vi /etc/postfix/master.cf


Voeg de volgende regels toe aan het einde van het bestand :

code:
1
2
# Dovecot LDA, as explained here: http://wiki.dovecot.org/LDA/Postfix
dovecot   unix  -       n       n       -       -       pipe flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}


Als je Postfix ook op poort 587 wilt laten luisteren (ipv 25 wat verschillende ISP's nog wel eens willen blokkeren) moet je de volgende regel uitcommentarieeren :

code:
1
#submission inet n       -       n       -       -       smtpd



Dovecot

Tot zover hebben we Postfix opgezet om gebruik te maken van de SASL functionaliteit van Dovecot. Nu moet de configuratie van Dovecot natuurlijk nog zo aangepast worden dat deze functionaliteit ook beschikbaar is voor Postfix.

Dovecot's hoofd configuratie kan gevonden worden in /etc/dovecot.conf

code:
1
vi /etc/dovecot/dovecot.conf


Pas de volgende regels aan, of uncomment deze voor IMAP en POP3 functionaliteit. Het specifiek benoemen van IMAPS of POP3S is niet meer nodig.

code:
1
2
protocols = imap pop3
listen = *



De authenticatie configuratie staat in /etc/dovecot/conf.d/10-auth.conf

code:
1
vi /etc/dovecot/conf.d/10-auth.conf



code:
1
2
disable_plaintext_auth = no
auth_mechanisms = plain login



De plek op het filesysteem waar de mails worden opgeslagen staat in /etc/dovecot/conf.d/10-mail.conf
Ik wil de mails opgeslagen hebben in /var/mail/vhosts/eigendomeinnaam.nl/user/Maildir

code:
1
vi /etc/dovecot/conf.d/10-mail.conf



code:
1
mail_location = maildir:%hMaildir



Authenticatie voor Postfix

code:
1
vi /etc/dovecot/conf.d/10-master.conf



code:
1
2
3
4
5
6
7
8
9
10
11
12
13
#unix_listener auth-userdb {
    #mode = 0600
    #user =
    #group =
  #}

# change or setup on these line:
# Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }


Protocol-specifieke settings

Quota
Wanneer je gebruik wil maken van quota pas dan de volgende files aan

code:
1
vi /etc/dovecot/conf.d/20-imap.conf


En voeg toe :

code:
1
mail_plugins = quota imap_quota



code:
1
vi /etc/dovecot/conf.d/20-pop3.conf


En voeg toe :

code:
1
mail_plugins = quota



Outlook - Om Outlook beter met Dovecot POP3 te laten werken is het aan te raden onderstaande opties te zetten.

code:
1
2
pop3_uidl_format = %08Xu%08Xv
pop3_client_workarounds = outlook-no-nuls oe-ns-eoh



LDA - De Local Delivery Agent van Dovecot.

code:
1
vi /etc/dovecot/conf.d/15-lda.conf



code:
1
2
postmaster_address = postmaster@eigendomeinnaam.nl
mail_plugins = quota



Authenticatie bij Dovecot
Standaard doet Dovecot alleen plaintext authenticatie. Als je gebruik gaat maken van TLS/SSL is plaintext prima, het zal toch versleutelt worden. Alleen bepaalde versies van Outlook vereisen nog een extra optie : login.

code:
1
vi /etc/dovecot/conf.d/10-auth.conf


Zoek de regel auth_mechanisms op en verander in :

code:
1
auth_mechanisms = plain login



MySQL integratie
Om Dovecot met MySQL te kunnen laten samenwerken zal Dovecot moeten weten hoe en op welke manier er informatie uit MySQL gehaald moet worden.

code:
1
vi /etc/dovecot/conf.d/auth-sql.conf.ext


Pas args = /etc/dovecot/dovecot-sql.conf.ext aan naar

code:
1
args = /etc/dovecot/dovecot-sql.conf


Uncomment de userdb prefetch en userdb passwd regels zodat er het volgende komt te staan:

code:
1
2
3
4
5
6
7
8
9
10
userdb {
  driver = prefetch
}

userdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf
}

user = vmail


Kopieer nu de voorbeeld file dovecot-sql.conf-ext naar /etc/dovecot

code:
1
# cp /usr/share/doc/dovecot-`dovecot --version`/example-config/dovecot-sql-example.conf /etc/dovecot/dovecot-sql.conf


Open nu de file, en bewerk deze

code:
1
# vi /etc/dovecot/dovecot-sql.conf


Specificeer het type DB

code:
1
driver = mysql


De gegevens om de database te benaderen

code:
1
connect = host=localhost dbname=mail user=mail_admin password=WACHTWOORD


Wachtwoorden als CRAM-MD5 opslaan

code:
1
default_pass_scheme = CRAM-MD5


De queries om gebruikersinformatie op te halen:

code:
1
user_query = SELECT CONCAT('/var/mail/vhosts/', maildir) AS home, 5000 AS uid, 5000 AS gid FROM mailbox WHERE username = '%u' AND active='1'


Bij gebruik van quotas wordt dit :

code:
1
user_query = SELECT CONCAT('/var/mail/vhosts/', maildir) AS home, 5000 AS uid, 5000 AS gid, CONCAT('*:bytes=', quota) as quota_rule FROM mailbox WHERE username = '%u' AND active='1'


En de wachtwoord query:

code:
1
password_query = SELECT username AS user, password, CONCAT('/var/mail/vhosts/', maildir) AS userdb_home, 5000 AS userdb_uid, 5000 AS userdb_gid FROM mailbox WHERE username = '%u' AND active='1'


En hier ook met quotas :

code:
1
password_query = SELECT username AS user, password, CONCAT('/var/mail/vhosts/', maildir) AS userdb_home, 5000 AS userdb_uid, 5000 AS userdb_gid, CONCAT('*:bytes', quota) as userdb_quota_rule FROM mailbox WHERE username = '%u' AND active='1'


Dovecot weet nu waar de informatie op te halen wat de limieten voor een gebruiker zijn. Alleen moet het ook nog kunnen bepalen hoeveel er al gebruikt is van deze limiet.
Open hiervoor eerst de file /etc/dovecot/conf.d/10-master.conf en wijzig hierin.

code:
1
# vi /etc/dovecot/conf.d/10-master.conf


Voeg toe :

code:
1
2
3
dict {
quotadict = mysql:/etc/dovecot-dict-quota.conf
}


En daarna de file 90-quota.conf

code:
1
2
3
# Quota setting per /usr/share/postfixadmin/DOCUMENTS/DOVECOT.txt
# http://wiki.dovecot.org/Quota/Dict
quota = dict:user::proxy::quotadict


Maak hierna de file /etc/dovecot/dovecot-dict-quota.conf aan

code:
1
# vi /etc/dovecot/dovecot-dict-quota.conf


En voeg hier de volgende regels aan toe :

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
connect = host=localhost dbname=mail user=mail_admin password=<YOUR PASSWORD>
map {
pattern = priv/quota/storage
table = quota2
username_field = username
value_field = bytes
}
map {
pattern = priv/quota/messages
table = quota2
username_field = username
value_field = messages
}



Starten
Test nu de configuratie van dovecot door de service te starten.

code:
1
# service dovecot start


Als er geen foutmeldingen worden gegeven is het configureren gelukt.
Hetzelfde voor postfix :

code:
1
# service postfix start


Eventueel beide services toevoegen aan de init :

code:
1
2
# chkconfig postfix on
# chkconfig dovecot on


Testen
De postfix service kan getest worden door een telnet sessie te starten naar poort 25.

code:
1
# telnet localhost 25


De volgende respons zou moeten komen

code:
1
2
3
4
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 eigendomeinnaam.nl ESMTP Postfix


Hetzelfde voor Dovecot POP3 en IMAP

code:
1
# telnet localhost 110


Geeft :

code:
1
2
3
4
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
+OK Dovecot ready.


En IMAP

code:
1
# telnet localhost 143


Geeft :

code:
1
2
3
4
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE STARTTLS AUTH=PLAIN AUTH=LOGIN AUTH=DIGEST-MD5 AUTH=CRAM-MD5] Dovecot ready.


TLS/SSL Encryptie
Het is mogelijk om TLS/SSL encryptie toe te voegen aan Postfix en Dovecot.
Installeer hiervoor eerst het crypto-utils package

code:
1
# yum install crypto-utils


Genereer vervolgens de benodigde keys en certificaten

code:
1
# genkey --days 365 mail.eigendomeinnaam.nl


Wanneer er gevraagd wordt Would you like to send a Certificate Request (CSR) to a Certificate Authority (CA)? selecteer dan NO, tenzij je het certificaat naar een CA wil sturen om te laten signen. Selecteer ook niet Encrypt the private key, want Postfix ondersteund dit niet.
De bestanden komen hier te staan :

code:
1
2
/etc/pki/tls/certs/mail.eigendomeinnaam.nl.crt
/etc/pki/tls/private/mail.eigendomeinnaam.nl.key


Nu moet Postfix nog weten waar de bestanden te vinden zijn. Pas daarom het volgende bestand aan :

code:
1
# vim /etc/postfix/main.cf


En voeg de volgende regels code toe

code:
1
2
3
4
5
6
7
smtpd_tls_security_level = may
smtpd_tls_key_file = /etc/pki/tls/private/mail.eigendomeinnaam.nl.key
smtpd_tls_cert_file = /etc/pki/tls/certs/mail.eigendomeinnaam.nl.crt
smtpd_tls_loglevel = 1
smtpd_tls_session_cache_timeout = 3600s
smtpd_tls_session_cache_database = btree:/var/spool/postfix/smtpd_tls_cache
tls_random_source = dev:/dev/urandom


Open vervolgende het Dovecot configuratie bestand

code:
1
# vim /etc/dovecot.conf


En voeg de volgende regels toe

code:
1
2
3
ssl_cert_file = /etc/pki/tls/certs/eigendomeinnaam.nl.crt
ssl_key_file = /etc/pki/tls/private/eigendomeinnaam.nl.key
ssl_cipher_list = ALL:!LOW:!SSLv2


Herstart vervolgens postfix en dovecot

code:
1
2
# service postfix restart
# service dovecot restart



Klaar! Nu is het alleen nog een kwestie van de Mail Clients juist configureren.