Jasper Aikema

Open Source: freedom to do what I want and to help people wherever I can.

Nu ik bijna aan het einde ben gekomen van mijn blogs over een mail systeem, zijn er nog twee blogs die geschreven moeten worden.
De twee onderwerpen zijn Dovecot en webmail. In deze blog wil ik de installatie van een dovecot server bespreken. De dovecot server zal de gebruikers checken tegen een MySQL database. De database is opgezet met de structuur van postfixadmin.

Ook nu ben ik begonnen met het installeren van een minimale Ubuntu 10.04 server inclusief vim en openssh-server. Het ontvangen van de email (MTA) gebeurt via postfix, deze zal het afleveren in een virtual mailbox. Daarna kan de mail via IMAP of POP3 opgehaald worden op de MDA, in dit geval dovecot.

Als eerste heb ik postfix geïnstalleerd.
apt-get install postfix postfix-mysql

Net zoals in de blog over de inkomende mailserver, heb ik de volgende regels toegevoegd aan main.cf.

/etc/postfix/main.cf:
virtual_alias_domains =
virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_gid_maps = static:8
virtual_mailbox_base = /srv/vmail
virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_minimum_uid = 150
virtual_transport = dovecot
virtual_uid_maps = static:150

In tegenstelling tot de configuratie van de inkomende mailserver, worden alle emails nu door gestuurd naar dovecot. Dit gebeurt door de regel virtual_transport = dovecot.
Als gid gebruik ik 8, dit is van de groep mail. Als uid gebruik ik 150, dit is de gebruiker vmail.

Postfix moet nog wel weten wat het transport dovecot precies is, hiervoor heb ik de volgende regel toegevoegd aan master.cf

/etc/postfix/master.cf:
dovecot unix - n n - - pipe
  flags=DRhu user=vmail:mail argv=/usr/lib/dovecot/deliver -c /etc/dovecot/conf.d/01-dovecot-postfix.conf -d $(recipient)

De configuratie bestanden welke de database aanroepen zijn hetzelfde als bij de inkomende mailserver.

/etc/postfix/mysql_virtual_alias_maps.cf:
user = <database gebruikersnaam>
password = <database wachtwoord>
hosts = <database server>
dbname = <database naam>
table = alias
select_field = goto
where_field = address
additional_conditions = and active = '1'
# query = SELECT goto FROM alias WHERE address='%s' AND active = '1'

/etc/postfix/mysql_virtual_domains_maps.cf:
user = <database gebruikersnaam>
password = <database wachtwoord>
hosts = <database server>
dbname = <database naam>
table = domain
select_field = domain
where_field = domain
additional_conditions = and backupmx = '0' and active = '1'
# query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' \
# AND active = '1'

/etc/postfix/mysql_virtual_mailbox_maps.cf:
user = <database gebruikersnaam>
password = <database wachtwoord>
hosts = <database server>
dbname = <database naam>
table = mailbox
select_field = CONCAT(domain,'/',username) AS maildir
where_field = CONCAT(username,'@',domain)
additional_conditions = and active = '1'
# query = SELECT CONCAT(username,'@',domain) AS maildir FROM mailbox \
# WHERE CONCAT(username,'@',domain)='%s' AND active = '1'

De gebruiker vmail en de directory /srv/vmail wordt als volgt aangemaakt:

useradd -d /srv/vmail -g 8 -u 150 -c "Virtual mailbox" -s /sbin/nologin vmail
mkdir /srv/vmail
chown vmail:mail /srv/vmail

Nu postfix is ingesteld om de email af te leveren bij dovecot, moet dovecot geïnstalleerd worden.

apt-get install dovecot-common dovecot-imapd dovecot-pop3d dovecot-postfix

De volgende instellingen moeten toegevoegd of aangepast worden in het configuratie bestand:

/etc/dovecot/dovecot.conf:
mail_location = maildir:/srv/vmail/%d/%u
first_valid_uid = 150
last_valid_uid = 150

protocol lda {
  postmaster_address = postmaster@>domeinnaam$lt;
  sendmail_path = /usr/lib/sendmail
  auth_socket_path = /var/run/dovecot/auth-master
}

auth default {
  mechanisms = plain
  passdb sql {
    args = /etc/dovecot/dovecot-sql.conf
  }
  userdb sql {
  args = /etc/dovecot/dovecot-sql.conf
  }
  user = root
  }
  !include_try /etc/dovecot/auth.d/*.auth
}

In het bestand /etc/dovecot/dovecot-sql.conf staat de configuratie waarmee de database gecheckt kan worden. Hieronder de wijzigingen die ik gedaan heb.

driver = mysql
connect = host=>database server< dbname=&gr;database naam< user=&gr;database gebruikersnaam< password=&gr;database wachtwoord<
password_query = \
  SELECT username, domain, password \
  FROM mailbox WHERE username = '%n' AND domain = '%d'

user_query = \
  SELECT maildir AS home, 150 AS uid, 8 AS gid \
  FROM mailbox WHERE username = '%n' AND domain = '%d'

Nu kunnen postfix en dovecot herstart worden.

service postfix restart
service dovecot restart

Met mutt (of een ander email programma) kan er nu gecheckt worden of er verbinding gemaakt kan worden met de dovecot server.

mutt -f imaps://<gebruikersnaam>@<servernaam>

Na aanleiding van een vorige post over Postfix, ben ik begonnen met een mailcluster. Een onderdeel hiervan is een inkomende email server. Deze inkomende email server ontvangt email vanaf het internet. Er wordt gecheckt of deze emails voor onze domeinen bestemd zijn door middel van een MySQL database.

Als we de email accepteren zullen we deze doorsturen naar de server die het verder afhandelt.

Zoals al mijn server beginnen ik met de installatie van Ubuntu 10.04 inclusief vim en openssh-server.
Hierna installeer ik postfix en postfix-mysql
apt-get install postfix postfix-mysql

Om email te accepteren voor gebruikers en domeinen welke geen echte gebruikers en domeinen zijn op onze server, moeten we gebruik maken van virtuele gebruikers en domeinen.
Dit is in te stellen in /etc/postfix/main.cf

/etc/postfix/main.cf:
virtual_alias_domains =
virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_gid_maps = static:111
virtual_mailbox_base = /srv/vmail
virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_minimum_uid = 103
virtual_transport = virtual
virtual_uid_maps = static:103
transport_maps = proxy:mysql:/etc/postfix/mysql_virtual_transports.cf

proxy:mysql:bestandnaam wil zeggen dat de gegevens uit de database gehaald moeten worden. Door middel van proxy wordt de database verbinding herbruikt. Hierdoor worden er minder verbindingen naar de database geopend.

De volgende bestanden roepen de database aan.

/etc/postfix/mysql_virtual_alias_maps.cf:
user = <database gebruikersnaam>
password = <database wachtwoord>
hosts = <database server>
dbname = <database naam>
table = alias
select_field = goto
where_field = address
additional_conditions = and active = '1'
# query = SELECT goto FROM alias WHERE address='%s' AND active = '1'

/etc/postfix/mysql_virtual_domains_maps.cf:
user = <database gebruikersnaam>
password = <database wachtwoord>
hosts = <database server>
dbname = <database naam>
table = domain
select_field = domain
where_field = domain
additional_conditions = and backupmx = '0' and active = '1'
# query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' \
# AND active = '1'

/etc/postfix/mysql_virtual_mailbox_maps.cf:
user = <database gebruikersnaam>
password = <database wachtwoord>
hosts = <database server>
dbname = <database naam>
table = mailbox
select_field = CONCAT(domain,'/',username) AS maildir
where_field = CONCAT(username,'@',domain)
additional_conditions = and active = '1'
# query = SELECT CONCAT(username,'@',domain) AS maildir FROM mailbox \
# WHERE CONCAT(username,'@',domain)='%s' AND active = '1'

/etc/postfix/mysql_virtual_transports.cf:
user = <database gebruikersnaam>
password = <database wachtwoord>
hosts = <database server>
dbname = <database naam>
table = domain
select_field = transport
where_field = domain
additional_conditions = and active = '1'
# query = SELECT transport FROM domain WHERE domain='%s' AND active = '1'

De bestanden spreken redelijk voor zich. De database structuur is de structuur die postfixadmin gebruikt. Het bestand mysql_virtual_transport.cf wordt gebruikt om aan te geven, op welke server de email afgeleverd moet worden.

Als dit alles ingesteld is, kan postfix herstart worden en kun je beginnen met ontvangen van email.
service postfix restart

Mocht er toch nog iets niet goed gaat, dan kan er in het logbestand (/var/log/mail.info) gekeken worden.

Het gebruik van mobiel internet wordt steeds groter. Als je altijd en overal mail wilt versturen is het makkelijk om dit via een eigen SMTP server te doen. In de volgende handleiding zal ik een SMTP server opzetten, welke de gebruikersnaam en wachtwoord opzoekt in een MySQL database.

Ik ben begonnen met het installeren van een minimale Ubuntu 10.04 server. Hierbij installeer ik vim en openssh-server als extra programma’s, zoals ik eigenlijk altijd doe.

Na de installatie installeer ik de pakketten postfix, sasl2-bin en libpam-mysql.

apt-get intall postfix sasl2-bin libpam-mysql

Postfix is het mailprogramma. Via libpam-mysql kan ik PAM (Pluggable Authentication Modules) laten communiceren met een MySQL database. Het programma sasl2-bin zorgt voor de communicatie tussen postfix en PAM.

Binnen postfix zullen er een aantal aanpassingen gedaan moeten worden.

In main.cf moeten er twee regels toegevoegd worden.

main.cf:
smtpd_sender_restrictions = permit_sasl_authenticated,reject
smtpd_recipient_restrictions = permit_sasl_authenticated,reject

Verder verander ik ook altijd de regel mydestination, zodat daar alleen localhost staat.

mydestination = localhost, localhost.localdomain

In master.cf zorg ik ervoor dat postfix niet luistert op poort 25 en wel op poort 587. Over poort 25 wordt meestal email verstuurd, maar deze poort wordt steeds vaker geblokkeerd door providers. Ook vind ik dat alle inkomende email via poort 25 moet en verder niets. Aangezien we geen inkomende email hebben, heb ik deze poort uitgeschakeld.

master.cf:
#smtp      inet  n       -       -       -        -       smtpd
submission inet  n       -       -       -        -       smtpd
#  -o smtpd_tls_security_level=encrypt
   -o smtpd_sasl_auth_enable=yes
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject
   -o milter_macro_daemon_name=ORIGINATING

submission wordt gebruikt voor poort 587. Verder geef ik als optie mee dat sasl gebruikt moet worden voor de authenticatie.

In de configuratie moet ik nog 1 bestand toevoegen, zodat authenticatie ook echt via sasl gaat. Dit is het bestand /etc/postfix/sasl/smtpd.conf.

smtpd.conf:
pwcheck_method: saslauthd
mech_list: plain login cram-md5 digest-md5
allow_plaintext: true

Verder moet het configuratie bestand voor sasl aangepast moeten worden, zodat deze gestart wordt.
Postfix wordt normaal gesproken in een chrooted omgeving gedraaid. Hierdoor is het voor postfix niet mogelijk om de socket van de sasl daemon te benaderen. Hiervoor zullen we de locatie van de socket moeten aanpassen, zodat deze in de chrooted omgeving van postfix uitkomt. Het configuratie bestand voor sasl staat in de /etc/default map en heeft de naam saslauthd.

saslauthd:
START=yes
OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd"

De sasl daemon moet ook gestart worden en postfix moet nog toegang krijgen tot de sasl daemon.

service saslauthd start
adduser postfix sasl

Zoals gezegd stuurt sasl de authenticatie door naar PAM. De configuratie bestanden hiervoor staan in de map /etc/pam.d. Voor postfix maken we een nieuw bestand aan met de naam ‘smtp’ en de volgende 2 regels (ik heb een \ toegevoegd omdat ze hier niet op 1 regel konden).

smtp:
auth required pam_mysql.so user=<database gebruikersnaam> \
passwd=<database wachtwoord> host=<database server> \
db=<database naam> table=mailbox usercolumn=username \
passwdcolumn=password crypt=1
account sufficient pam_mysql.so user=<database gebruikersnaam> \
passwd=<database wachtwoord> host=<database server> \
db=<database naam> table=mailbox usercolumn=username \
passwdcolumn=password crypt=1

Als de server nu opnieuw opgestart is, kan er via telnet een verbinding naar toe gemaakt worden.

Om via telnet een email te sturen, is het mogelijk om dezelfde commando’s te geven als bij een normale SMTP verbinding, dus zonder authenticatie.
Wel zul je na het HELO of EHLO commando eerst de gebruikersnaam en het wachtwoord moeten sturen.

AUTH PLAIN <encypted string>

De gebruikersnaam en het wachtwoord worden in 1 string geëncrypt, dit is handmatig mogelijk via één van de volgende commandos.

perl -MMIME::Base64 -e 'print encode_base64("\0<gebruikersnaam>\0<wachtwoord>")'
php -r 'echo base64_encode("\0<gebruikersnaam>\0<wachtwoord>");'

Als er in de gebruikernaam een @ zit, dan moet deze geëscaped worden met een \.