1

-------

Install and configure Postfix and Dovecot

Postfix ConfigurationWe will setup Postfix to use virtual mailboxes and domains.

Start by creating the sql configuration files which will instruct postfix how to access the MySQL database, created in the first part of this series.

sudo mkdir -p /etc/postfix/sql

Open your text editor and create the following files:

/etc/postfix/sql/mysql_virtual_domains_maps.cf

user = postfixadminpassword = P4ssvv0rDhosts = 127.0.0.1dbname = postfixadminquery = SELECT domain FROM domain WHERE domain='%s' AND active = '1'

Copy

/etc/postfix/sql/mysql_virtual_alias_maps.cf

user = postfixadminpassword = P4ssvv0rDhosts = 127.0.0.1dbname = postfixadminquery = SELECT goto FROM alias WHERE address='%s' AND active = '1'

Copy

/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf

user = postfixadminpassword = P4ssvv0rDhosts = 127.0.0.1dbname = postfixadminquery = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'

Copy

/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf

user = postfixadminpassword = P4ssvv0rDhosts = 127.0.0.1dbname = postfixadminquery  = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'

Copy

/etc/postfix/sql/mysql_virtual_mailbox_maps.cf

user = postfixadminpassword = P4ssvv0rDhosts = 127.0.0.1dbname = postfixadminquery = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'

Copy

/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf

user = postfixadminpassword = P4ssvv0rDhosts = 127.0.0.1dbname = postfixadminquery = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1'

Copy

Once the SQL configuration files are created, update the main postfix configuration file to include information about the virtual domains, users, and aliases which are stored in the MySQL database.

sudo postconf -e "virtual_mailbox_domains = mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf"

sudo postconf -e "virtual_alias_maps = mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf, mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf, mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf"

sudo postconf -e "virtual_mailbox_maps = mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf, mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf"

The postconf command displays the actual values of configuration parameters, changes configuration parameter values, or displays other configuration information about the Postfix mail system.

The local delivery agent will deliver the incoming emails to the users’ mailboxes. Run the following command to set Dovecot's LMTP service as a default mail delivery transport:

sudo postconf -e "virtual_transport = lmtp:unix:private/dovecot-lmtp"

Set the TL parameters using the previously generated Let's encrypt SSL certificate:

sudo postconf -e 'smtp_tls_security_level = may'

sudo postconf -e 'smtpd_tls_security_level = may'

sudo postconf -e 'smtp_tls_note_starttls_offer = yes'

sudo postconf -e 'smtpd_tls_loglevel = 1'

sudo postconf -e 'smtpd_tls_received_header = yes'

sudo postconf -e 'smtpd_tls_cert_file = /etc/letsencrypt/live/mail.linuxize.com/fullchain.pem'

sudo postconf -e 'smtpd_tls_key_file = /etc/letsencrypt/live/mail.linuxize.com/privkey.pem'

Configure the authenticated SMTP settings and hand off authentication to Dovecot:

sudo postconf -e 'smtpd_sasl_type = dovecot'

sudo postconf -e 'smtpd_sasl_path = private/auth'

sudo postconf -e 'smtpd_sasl_local_domain ='

sudo postconf -e 'smtpd_sasl_security_options = noanonymous'

sudo postconf -e 'broken_sasl_auth_clients = yes'

sudo postconf -e 'smtpd_sasl_auth_enable = yes'

sudo postconf -e 'smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination'

We'll also need to edit the Postfix master configuration file master.cf and enable the submission port (587) and smtps port (465).

Open the file with your text editor and uncomment/edit the following lines:

/etc/postfix/master.cf

submission inet n       -       y       -       -       smtpd   -o syslog_name=postfix/submission   -o smtpd_tls_security_level=encrypt   -o smtpd_sasl_auth_enable=yes #  -o smtpd_reject_unlisted_recipient=no   -o smtpd_client_restrictions=permit_sasl_authenticated,reject #  -o smtpd_helo_restrictions=$mua_helo_restrictions #  -o smtpd_sender_restrictions=$mua_sender_restrictions #  -o smtpd_recipient_restrictions= #  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject   -o milter_macro_daemon_name=ORIGINATING smtps     inet  n       -       y       -       -       smtpd   -o syslog_name=postfix/smtps   -o smtpd_tls_wrappermode=yes   -o smtpd_sasl_auth_enable=yes #  -o smtpd_reject_unlisted_recipient=no   -o smtpd_client_restrictions=permit_sasl_authenticated,reject #  -o smtpd_helo_restrictions=$mua_helo_restrictions #  -o smtpd_sender_restrictions=$mua_sender_restrictions #  -o smtpd_recipient_restrictions= #  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject   -o milter_macro_daemon_name=ORIGINATING

Restart the postfix service for changes to take effect.

sudo systemctl restart postfix

At this point you have successfully configured the Postfix service.

Configure Dovecot

In this section we'll configure Dovecot to match our setup. Make sure you edit the lines highlighted in yellow.

Start by configuring the dovecot-sql.conf.ext file that instructs Dovecot how to access the database and how to find the information about email accounts.

/etc/dovecot/dovecot-sql.conf.ext

driver = mysql

connect = host=127.0.0.1 dbname=postfixadmin user=postfixadmin password=P4ssvv0rD

default_pass_scheme = MD5-CRYPT

iterate_query = SELECT username AS user FROM mailbox

user_query = SELECT CONCAT('/var/mail/vmail/',maildir) AS home, \

 CONCAT('maildir:/var/mail/vmail/',maildir) AS mail, \

 5000 AS uid, 5000 AS gid, CONCAT('*:bytes=',quota) AS quota_rule \

 FROM mailbox WHERE username = '%u' AND active = 1

password_query = SELECT username AS user,password FROM mailbox \

 WHERE username = '%u' AND active='1'

Copy

Do not forget to use the correct MySQL credentials (dbname, user and password).

Next, edit the conf.d/10-mail.conf file and edit the following variables:

/etc/dovecot/conf.d/10-mail.conf

...

...

Copy

...

...

...

 }}...

Copy

Open the conf.d/10-ssl.conf and enable SSL/TLS.

/etc/dovecot/conf.d/10-ssl.conf

...

}...service dict {   unix_listener dict {

 ...}...service auth-worker {

 }   ...

 }...}...service auth {   ...   unix_listener auth-userdb {

...

Copy

Open the conf.d/10-master.conf file, and modify it as follows:

/etc/dovecot/conf.d/10-master.conf

...service lmtp {

...

...

...

Copy

To make the authentication work, open the conf.d/10-auth.conf, edit the following lines and include the auth-sql.conf.ext file:

/etc/dovecot/conf.d/10-auth.conf

...

...

...

...

...

ssl = yes

ssl_cert = </etc/letsencrypt/live/mail.linuxize.com/fullchain.pem

ssl_key = </etc/letsencrypt/live/mail.linuxize.com/privkey.pem

ssl_dh = </etc/ssl/certs/dhparam.pem

ssl_cipher_list = EECDH+AES:EDH+AES+aRSA

ssl_prefer_server_ciphers = yes

Make sure you use the correct path to the SSL certificate files.

If you have followed this series from the beginning, you should already have the fullchain.pem, privkey.pem, dhparam.pem files created on your server. For more information about how to create a free Let's encrypt SSL certificate and Diffie–Hellman key check this tutorial.

Thanks to Nevyn for noticing the problem and providing a solution.

 unix_listener /var/spool/postfix/private/dovecot-lmtp {

   mode = 0600

   user = postfix

   group = postfix

   mode = 0600

   user = vmail

   group = vmail

 unix_listener /var/spool/postfix/private/auth {

   mode = 0666

   user = postfix

   group = postfix

 }

 user = vmail

   mode = 0660

   user = vmail

   group = vmail

disable_plaintext_auth = yes

auth_mechanisms = plain login

#!include auth-system.conf.ext

!include auth-sql.conf.ext

mail_location = maildir:/var/mail/vmail/%d/%n

mail_uid = vmail

mail_gid = vmail

first_valid_uid = 5000

last_valid_uid = 5000

mail_privileged_group = vmail

mail_plugins = quota

Open the conf.d/20-imap.conf file and activate the imap_quota plugin:

/etc/dovecot/conf.d/20-imap.conf

...protocol imap {   ...

 mail_plugins = $mail_plugins imap_quota

 ...}...

Copy

Open the conf.d/20-lmtp.conf file and edit it as follows:

/etc/dovecot/conf.d/20-lmtp.conf

...protocol lmtp {

 postmaster_address = postmaster@linuxize.com

 mail_plugins = $mail_plugins

}...

Copy

Define the default Mailboxes in the conf.d/20-lmtp.conf file:

/etc/dovecot/conf.d/15-mailboxes.conf

...mailbox Drafts {   special_use = \Drafts}

mailbox Spam {

 special_use = \Junk

 auto = subscribe

}

mailbox Junk {   special_use = \Junk}...

Copy

There are two different types of quota sizes, one is set for the entire domain and the other per user mailbox. In the previous part of this series we have already enabled the quota support in PostfixAdmin which means the quota information will be stored in the PostfixAdmin database.

Now we need to configure Dovecot to connect to the database, to handle quota limits and to run a script that sends a mail to the user when user's quota exceeds a specified limit. To do so open the conf.d/90-quota.conf file and modify it as follows:

/etc/dovecot/conf.d/90-quota.conf

plugin {   quota = dict:User quota::proxy::sqlquota   quota_rule = *:storage=5GB   quota_rule2 = Trash:storage=+100M   quota_grace = 10%%   quota_exceeded_message = Quota exceeded, please contact your system administrator.   quota_warning = storage=100%% quota-warning 100 %u   quota_warning2 = storage=95%% quota-warning 95 %u   quota_warning3 = storage=90%% quota-warning 90 %u   quota_warning4 = storage=85%% quota-warning 85 %u}service quota-warning {   executable = script /usr/local/bin/quota-warning.sh   user = vmail    unix_listener quota-warning {     group = vmail   mode = 0660   user = vmail   }}dict {   sqlquota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext}

Copy

We also need to tell dovecot how to access the quota SQL dictionary. Open the dovecot-dict-sql.conf.ext file and edit the following lines:

/etc/dovecot/dovecot-dict-sql.conf.ext

...

...

Copy

 username_field = username   value_field = messages}...

 username_field = username   value_field = bytes}map {   pattern = priv/quota/messages

...map {   pattern = priv/quota/storage

connect = host=127.0.0.1 dbname=postfixadmin user=postfixadmin password=P4ssvv0rD

 table = quota2

 table = quota2

# map {

#   pattern = shared/expire/$user/$mailbox

#   table = expires

#   value_field = expire_stamp

#

#   fields {

#     username = $user

#     mailbox = $mailbox

#   }

# }

Make sure you use the correct MySQL credentials (dbname, user and password).

Create the following shell script which will send an email to the user if its quota exceeds a specified limit:

/usr/local/bin/quota-warning.sh

#!/bin/sh PERCENT=$1USER=$2 cat << EOF | /usr/lib/dovecot/dovecot-lda -d $USER -o "plugin/quota=dict:User quota::noenforcing:proxy::sqlquota" From: postmaster@linuxize.com Subject: Quota warning Your mailbox is now $PERCENT% full. EOF

Copy

Make the script executable by running the following chmod command:

sudo chmod +x /usr/local/bin/quota-warning.sh

Finally restart the dovecot service for changes to take effect.

sudo systemctl restart dovecot

-------