The Funtoo Linux project has transitioned to "Hobby Mode" and this wiki is now read-only.
Difference between revisions of "Mail Server"
m (Add note about port 25 and alt port 587) |
|||
(7 intermediate revisions by the same user not shown) | |||
Line 13: | Line 13: | ||
The following packages need to be installed first, before we can do anything: {{c|mail-mta/postfix}}, {{c|net-mail/dovecot}}, and {{c|dev-db/mariadb}}. Before we emerge these, however, we must ensure some USE flags are properly set first: | The following packages need to be installed first, before we can do anything: {{c|mail-mta/postfix}}, {{c|net-mail/dovecot}}, and {{c|dev-db/mariadb}}. Before we emerge these, however, we must ensure some USE flags are properly set first: | ||
{{file|name=/etc/portage/package.use/mail-server|desc=USE flags|body=mail-mta/postfix dovecot-sasl pam ssl | {{file|name=/etc/portage/package.use/mail-server|desc=USE flags|body=mail-mta/postfix dovecot-sasl mysql pam ssl | ||
net-mail/dovecot bzip2 maildir pam ssl zlib}} | net-mail/dovecot bzip2 maildir mysql pam ssl zlib}} | ||
With USE flags properly set, we can emerge our packages: | With USE flags properly set, we can emerge our packages: | ||
Line 82: | Line 82: | ||
}} | }} | ||
You will be prompted to enter the password twice before it gives back the hash. The part that comes after {{c|{SHA512-CRYPT}}} is the password that will need to go into the database (it will always start with {{c|$6$}}). | You will be prompted to enter the password twice before it gives back the hash. The part that comes after {{c|{SHA512-CRYPT} }} is the password that will need to go into the database (it will always start with {{c|$6$}}). | ||
{{note|The password you will distribute to your users is the one you typed into {{c|doveadm}}; the hash that it outputs is what will go into the {{c|virtual_users}} table.}} | {{note|The password you will distribute to your users is the one you typed into {{c|doveadm}}; the hash that it outputs is what will go into the {{c|virtual_users}} table.}} | ||
Line 100: | Line 100: | ||
=== Configuring Postfix === | === Configuring Postfix === | ||
Now we have to configure Postfix. Pull up your favorite text editor and add the following lines to the bottom: | Now we have to configure Postfix. Pull up your favorite text editor and add the following lines to the bottom of {{f|/etc/postfix/main.cf}}: | ||
{{file|name=/etc/postfix/main.cf|desc=Postfix configuration|body= | {{file|name=/etc/postfix/main.cf|desc=Postfix configuration|body= | ||
Line 126: | Line 126: | ||
}} | }} | ||
Next, we have to change a few items in the same config file ( | Next, we have to change a few items in the same config file (we will be changing the defaults in the file to what's shown here). Since this is a new install, the developers recommended that the {{c|compatibility_level}} be set to 2: | ||
{{file|name=/etc/postfix/main.cf|desc=More Postfix configuration|body= | {{file|name=/etc/postfix/main.cf|desc=More Postfix configuration|body= | ||
compatibility_level = 2 | compatibility_level = 2 | ||
myhostname = <my.fqdn.com> | }} | ||
mydomain = <fqdn.com | |||
Next, we will be setting up the mail server's hostname and domain. How we fill this in depends on what your DNS and MX records point to. If you have it set up so that your main domain is of the form ''tld.ext'', then you will put that into the {{c|mydomain}} field, otherwise, you will set it the same as the {{c|myshostname}} field (in ''host.tld.ext'' form): | |||
{{file|name=/etc/postfix/main.cf|desc=More Postfix configuration|body= | |||
myhostname = <my.fqdn.com> | |||
mydomain = <fqdn.com {{!}} my.fqdn.com> | |||
}} | |||
The {{c|mydestination}} field '''MUST''' be set to localhost, otherwise, incoming mail will bounce: | |||
{{file|name=/etc/postfix/main.cf|desc=More Postfix configuration|body= | |||
mydestination = localhost # This MUST be set to localhost | mydestination = localhost # This MUST be set to localhost | ||
}} | }} | ||
Next, we have to create the files referenced above as part of the 'Authentication config'. First, we have to create {{f|/etc/postfix/mysql-virtual-mailbox-domains.cf}}: | Some mail servers will not talk to you if the hostname that is set up on your reverse DNS record does not match the SMTP banner that Postfix sends to peers. To fix that, add the following (replace ''<reverse DNS hostname>'' with your real reverse DNS hostname): | ||
{{file|name=/etc/postfix/main.cf|desc=And yet more Postfix configuration|body= | |||
smtpd_banner = <reverse DNS hostname> ESMTP $mail_name | |||
}} | |||
{{note|It is not necessary for the reverse DNS hostname to match your mail server's hostname; it just has to be present.}} | |||
Finally, in this file, we have to enumerate the networks that can relay mail via our server. Generally we want to list ''only'' the subnets that we want to be able to send mail from (replace ''<LAN IP>'' with your LAN's subnet and ''<LAN netmask>'' with your LAN's netmask, and leave 127.0.0.0/8 in): | |||
{{file|name=/etc/postfix/main.cf|desc=More Postfix configuration|body= | |||
mynetworks = <LAN IP>/<LAN netmask>, 127.0.0.0/8 | |||
}} | |||
{{note|If you want one or more remote hosts to be able to send through your mail server, you should add them to the {{c|mynetworks}} line as comma separated values. Also, you should set the netmask (the part after the '/') on each of them to 32, to ensure that ''only'' those IP addresses can be sent from.}} | |||
Next, we have to create the files referenced above as part of the 'Authentication config'. First, we have to create {{f|/etc/postfix/mysql-virtual-mailbox-domains.cf}} (be sure to replace ''<mailuserpass>'' with mailuser's real password): | |||
{{file|name=/etc/postfix/mysql-virtual-mailbox-domains.cf|desc=MySQL/virtual domains Postfix configuration|body= | {{file|name=/etc/postfix/mysql-virtual-mailbox-domains.cf|desc=MySQL/virtual domains Postfix configuration|body= | ||
user = mailuser | user = mailuser | ||
password = mailuserpass | password = <mailuserpass> | ||
hosts = 127.0.0.1 | hosts = 127.0.0.1 | ||
dbname = mailserver | dbname = mailserver | ||
Line 150: | Line 175: | ||
{{file|name=/etc/postfix/mysql-virtual-mailbox-maps.cf|desc=MySQL/virtual maps Postfix configuration|body= | {{file|name=/etc/postfix/mysql-virtual-mailbox-maps.cf|desc=MySQL/virtual maps Postfix configuration|body= | ||
user = mailuser | user = mailuser | ||
password = mailuserpass | password = <mailuserpass> | ||
hosts = 127.0.0.1 | hosts = 127.0.0.1 | ||
dbname = mailserver | dbname = mailserver | ||
Line 160: | Line 185: | ||
{{file|name=/etc/postfix/mysql-virtual-alias-maps.cf|desc=MySQL/virtual alias maps Postfix configuration|body= | {{file|name=/etc/postfix/mysql-virtual-alias-maps.cf|desc=MySQL/virtual alias maps Postfix configuration|body= | ||
user = mailuser | user = mailuser | ||
password = mailuserpass | password = <mailuserpass> | ||
hosts = 127.0.0.1 | hosts = 127.0.0.1 | ||
dbname = mailserver | dbname = mailserver | ||
query = SELECT destination FROM virtual_aliases WHERE source='%s' | query = SELECT destination FROM virtual_aliases WHERE source='%s' | ||
}} | }} | ||
If we want Postfix to talk on port 25, we have to make sure that the second field in the line in {{f|/etc/postfix/master.cf}} for smtp is {{c|inet}}: | |||
{{file|name=/etc/postfix/master.cf|desc=Postfix master service file|body= | |||
# ========================================================================== | |||
# service type private unpriv chroot wakeup maxproc command + args | |||
# (yes) (yes) (no) (never) (100) | |||
# ========================================================================== | |||
smtp inet n - y - - smtpd | |||
}} | |||
{{note|Some ISPs block port 25; in that case you would uncomment the line in master.cf that starts with "submission" (remove the '#' character in front of it) to enable postfix communicating on port 587.}} | |||
Now lets start Postfix and make sure that our authentication queries are working: | Now lets start Postfix and make sure that our authentication queries are working: | ||
Line 186: | Line 223: | ||
}} | }} | ||
Next we need to look at {{f|/etc/dovecot/conf.d/10-mail.conf}}: | Next we need to look at {{f|/etc/dovecot/conf.d/10-mail.conf}}. We need to tell Dovecot where to store mail (and, in the case of IMAP, keep it). {{c|mail_location}} and {{c|mail_privileged_group}} will likely be in there already and need to be changed; we will likely have to add {{c|first_valid_uid}}: | ||
{{file|name=/etc/dovecot/conf.d/10-mail.conf|desc=Dovecot configuration|body= | {{file|name=/etc/dovecot/conf.d/10-mail.conf|desc=Dovecot configuration|body= | ||
Line 194: | Line 231: | ||
}} | }} | ||
Next is {{f|/etc/dovecot/conf.d/10-auth.conf}}: Here we have to tell Dovecot how we want to authenticate our users. Note that in addition to setting {{c|disable_plaintext_auth}} to ''yes'' and {{c|auth_mechanisms}} to ''plain login'', we need to comment out (by inserting a '#' in front of) the line {{c|!include auth-system.conf.ext}} and uncomment (by removing any '#' in front of) the line {{c|!include auth-sql.conf.ext}}. This is to prevent Dovecot from using native accounts for authorization and use our database instead: | |||
{{file|name=/etc/dovecot/conf.d/10-auth.conf|desc=Dovecot authorization config|body= | {{file|name=/etc/dovecot/conf.d/10-auth.conf|desc=Dovecot authorization config|body= | ||
disable_plaintext_auth = yes | disable_plaintext_auth = yes | ||
auth_mechanisms = plain login | auth_mechanisms = plain login | ||
#!include auth-system.conf.ext | #!include auth-system.conf.ext | ||
!include auth-sql.conf.ext | !include auth-sql.conf.ext | ||
}} | }} | ||
Next we need to edit {{f|/etc/dovecot/conf.d/auth-sql.conf.ext}}, so Dovecot knows where and how the passwords are stored, and how and where to write our users' mail: | |||
{{file|name=/etc/dovecot/conf.d/auth-sql.conf.ext|desc=Dovecot SQL config|body= | {{file|name=/etc/dovecot/conf.d/auth-sql.conf.ext|desc=Dovecot SQL config|body= | ||
Line 218: | Line 253: | ||
}} | }} | ||
Next is {{f|/etc/dovecot/dovecot-sql.conf.ext}}, which is mentioned in the previous file. This is to tell Dovecot the details of how to talk to the database in order to validate user logins (replace ''<mailuserpass>'' with the password you created for the MySQL user 'mailuser'): | |||
{{file|name=/etc/dovecot/dovecot-sql.conf.ext|desc=More Dovecot SQL config|body= | {{file|name=/etc/dovecot/dovecot-sql.conf.ext|desc=More Dovecot SQL config|body= | ||
Line 227: | Line 262: | ||
}} | }} | ||
Next | Next file we have to modify is {{f|/etc/dovecot/conf.d/10-master.conf}}. First, we will set the listener ports for IMAP and POP3 to zero, to force encrypted links: | ||
{{file|name=/etc/dovecot/conf.d/10-master.conf|desc=Dovecot master config file|body= | {{file|name=/etc/dovecot/conf.d/10-master.conf|desc=Dovecot master config file|body= | ||
Line 234: | Line 269: | ||
port = 0 | port = 0 | ||
} | } | ||
service pop3-login { | service pop3-login { | ||
inet_listener pop3 { | inet_listener pop3 { | ||
port = 0 | port = 0 | ||
} | } | ||
}} | |||
Next, we have to configure Dovecot's LMTP service: | |||
{{file|name=/etc/dovecot/conf.d/10-master.conf|desc=Dovecot master config file|body= | |||
service lmtp { | service lmtp { | ||
unix_listener /var/spool/postfix/private/dovecot-lmtp { | unix_listener /var/spool/postfix/private/dovecot-lmtp { | ||
Line 254: | Line 293: | ||
user=mail | user=mail | ||
} | } | ||
}} | |||
Finally, we need to properly set up the {{c|auth}} and {{c|auth-worker}} services: | |||
{{file|name=/etc/dovecot/conf.d/10-master.conf|desc=Dovecot master config file|body= | |||
service auth { | service auth { | ||
# auth_socket_path points to this userdb socket by default. It's typically | # auth_socket_path points to this userdb socket by default. It's typically | ||
Line 286: | Line 329: | ||
}} | }} | ||
And last, but not least, {{f|/etc/dovecot/conf.d/10-ssl.conf}}: | And last, but not least, we need to edit {{f|/etc/dovecot/conf.d/10-ssl.conf}}, so that Dovecot knows where to find valid certificates to work with: | ||
{{file|name=/etc/dovecot/conf.d/10-ssl.conf|desc=Dovecot SSL config|body= | {{file|name=/etc/dovecot/conf.d/10-ssl.conf|desc=Dovecot SSL config|body= | ||
Line 300: | Line 343: | ||
}} | }} | ||
Yes, | Yes, the certificates generated this way are self-signed; if that bothers you feel free to buy one from GoDaddy or some other CA. It won't make things more secure (self-signed certificates have an undeserved bad reputation), but it will make you slightly poorer and the CA slightly richer. | ||
Finally, we set the permissions on the Dovecot config files so they belong to {{c|mail:dovecot}} and nobody else: | Finally, we set the permissions on the Dovecot config files so they belong to {{c|mail:dovecot}} and nobody else: | ||
Line 343: | Line 386: | ||
{{TableEnd}} | {{TableEnd}} | ||
{{note|Once the settings are correct in Thunderbird, the first time you send or receive an email message, Thunderbird will ask you to confirm the certificates coming from your email server if they are self-signed.}} | {{note|Once the settings are correct in Thunderbird, the first time you send or receive an email message, Thunderbird will ask you to confirm that you want to use the certificates coming from your email server if they are self-signed.}} | ||
== A Few Words on Security, Spam & Blacklists == | == A Few Words on Security, Spam & Blacklists == |
Latest revision as of 15:02, January 25, 2022
How to set up a simple, secure, lightweight email server using Postfix and Dovecot
Running one's own email server doesn't have to be mystical and impenetrable; using a simple MTA like Postfix along with an LDA like Dovecot makes the task relatively easy. Regrettably, good information on how to do this is hard to come by. What this guide will help you do is install a mail server which uses a database backend to manage domains and users, and features mail delivery via POP3 and/or IMAP.
Prerequisites
If you intend to run your own email server, you will need to have DNS with at least one MX record on a DNS server that can be seen by the Internet at large. It is also essential for reliable mail delivery to have properly-configured reverse DNS as many mail servers will use reverse DNS and will expect your IP address to resolve to your advertised hostname. Setting up such a thing is beyond the scope of this document.
Preparation
The following packages need to be installed first, before we can do anything: mail-mta/postfix
, net-mail/dovecot
, and dev-db/mariadb
. Before we emerge these, however, we must ensure some USE flags are properly set first:
/etc/portage/package.use/mail-server
- USE flagsmail-mta/postfix dovecot-sasl mysql pam ssl
net-mail/dovecot bzip2 maildir mysql pam ssl zlib
With USE flags properly set, we can emerge our packages:
root # emerge -avq postfix mariadb
Setting the dovecot-sasl
USE flag should pull in net-mail/dovecot
. If it does not, emerge this way:
root # emerge -avq postfix dovecot mariadb
Next, we need to set up the location on the server where email will be delivered:
root # mkdir /mailstore root # chgrp mail /mailstore root # chmod -R g+rw /mailstore
Configuration
Now we come to the meat of the project. First we will have to set up the mail user/domain database, then we will have to configure Postfix, then finally, configure Dovecot. At the end of this procedure, we should have a fully functioning mail server.
Setting up the Database
First step is to set up the database for the virtual domain/user tracking. We need to set up the database's root user and get the database up and running (be sure to replace <strong-password> with a real, strong password):
root # mysqladmin -u root password '<strong-password>' root # rc-update add mysql default root # rc
Next, we need to login to MySQL (you will have to enter the <strong-password> you set above):
root # mysql -p
Now, we create the database and its tables (again, replace <mailuserpass> with a real password):
mysql> CREATE DATABASE mailserver; mysql> USE mailserver; mysql> GRANT SELECT ON mailserver.* TO 'mailuser'@'127.0.0.1' IDENTIFIED BY '<mailuserpass>'; mysql> FLUSH PRIVILEGES; mysql> CREATE TABLE virtual_domains (id INT(11) NOT NULL AUTO_INCREMENT, root ##i## name VARCHAR(50) NOT NULL, PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8; mysql> CREATE TABLE virtual_users (id INT(11) NOT NULL AUTO_INCREMENT, root ##i## domain_id INT(11) NOT NULL, password VARCHAR(106) NOT NULL, email VARCHAR(100) NOT NULL, root ##i## PRIMARY KEY (id), UNIQUE KEY email (email), FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) root ##i## ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8; mysql> CREATE TABLE virtual_aliases (id INT(11) NOT NULL AUTO_INCREMENT, root ##i## domain_id INT(11) NOT NULL, source VARCHAR(100) NOT NULL, destination VARCHAR(100) NOT NULL, root ##i## PRIMARY KEY (id), FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE) root ##i## ENGINE=InnoDB DEFAULT CHARSET=utf8;
Now that we've created our database and tables, we need to put our domain into it. Replace <my.fqdn.com> with the FQDN of that will go to the right of the '@' sign in email addresses on your mail domain:
mysql> INSERT INTO virtual_domains VALUES (DEFAULT, '<my.fqdn.com>');
If you're planning on receiving mail for more than one domain, you can add them by reusing the previous query and changing <my.fqdn.com> to the other domain(s); you will have to enter one query for each extra domain.
Next, we need to populate that database with users (the part that goes on the left side of the '@' sign). Again, these need to be added one at a time. For each entry in the database, we will need a username and a password; since we want these passwords to be strong, we will use doveadm to generate them:
root # doveadm pw -s SHA512-CRYPT Enter new password: Retype new password: {SHA512-CRYPT}$6$dMNWSDK.CYzDfADO$LLSqttmYD/3WDBIEwxLjzae1s0G.eQw6EU8U7cjysPDK/z3Pntz8gxabfrYmLzpdc.L3gMyxaoI4V9ci4zruM.
You will be prompted to enter the password twice before it gives back the hash. The part that comes after {SHA512-CRYPT}
is the password that will need to go into the database (it will always start with $6$
).
The password you will distribute to your users is the one you typed into doveadm
; the hash that it outputs is what will go into the virtual_users
table.
Replace <pw_hash> with the output of doveadm
(starting with $6$
), and <user@my.fqdn.com> with the email address for the user you're creating:
mysql> INSERT INTO virtual_users VALUES (DEFAULT, 1, '<pw_hash>', '<user@my.fqdn.com>');
The second field in the query above (the '1') is the ID of the entry in the virtual_domains
table. If you're only using one domain, you don't have to worry about changing it; otherwise, you will have to change it to correspond to the domain for that user. You can find out what IDs they have with the following query:
mysql> SELECT * FROM virtual_domains;
Once you are done entering users you can leave MySQL:
mysql> quit
Configuring Postfix
Now we have to configure Postfix. Pull up your favorite text editor and add the following lines to the bottom of /etc/postfix/main.cf
:
/etc/postfix/main.cf
- Postfix configuration# SASL config
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
# TLS config
smtpd_tls_cert_file = /etc/ssl/certs/dovecot.pem
smtpd_tls_key_file = /etc/ssl/private/dovecot.pem
smtpd_use_tls = yes
smtpd_tls_auth_only = yes
smtp_tls_security_level = may
smtp_tls_loglevel = 2
smtpd_tls_received_header = yes
# Authentication config
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf
local_recipient_maps = $virtual_mailbox_maps
Next, we have to change a few items in the same config file (we will be changing the defaults in the file to what's shown here). Since this is a new install, the developers recommended that the compatibility_level
be set to 2:
/etc/postfix/main.cf
- More Postfix configurationcompatibility_level = 2
Next, we will be setting up the mail server's hostname and domain. How we fill this in depends on what your DNS and MX records point to. If you have it set up so that your main domain is of the form tld.ext, then you will put that into the mydomain
field, otherwise, you will set it the same as the myshostname
field (in host.tld.ext form):
/etc/postfix/main.cf
- More Postfix configurationmyhostname = <my.fqdn.com>
mydomain = <fqdn.com | my.fqdn.com>
The mydestination
field MUST be set to localhost, otherwise, incoming mail will bounce:
/etc/postfix/main.cf
- More Postfix configurationmydestination = localhost # This MUST be set to localhost
Some mail servers will not talk to you if the hostname that is set up on your reverse DNS record does not match the SMTP banner that Postfix sends to peers. To fix that, add the following (replace <reverse DNS hostname> with your real reverse DNS hostname):
/etc/postfix/main.cf
- And yet more Postfix configurationsmtpd_banner = <reverse DNS hostname> ESMTP $mail_name
It is not necessary for the reverse DNS hostname to match your mail server's hostname; it just has to be present.
Finally, in this file, we have to enumerate the networks that can relay mail via our server. Generally we want to list only the subnets that we want to be able to send mail from (replace <LAN IP> with your LAN's subnet and <LAN netmask> with your LAN's netmask, and leave 127.0.0.0/8 in):
/etc/postfix/main.cf
- More Postfix configurationmynetworks = <LAN IP>/<LAN netmask>, 127.0.0.0/8
If you want one or more remote hosts to be able to send through your mail server, you should add them to the mynetworks
line as comma separated values. Also, you should set the netmask (the part after the '/') on each of them to 32, to ensure that only those IP addresses can be sent from.
Next, we have to create the files referenced above as part of the 'Authentication config'. First, we have to create /etc/postfix/mysql-virtual-mailbox-domains.cf
(be sure to replace <mailuserpass> with mailuser's real password):
/etc/postfix/mysql-virtual-mailbox-domains.cf
- MySQL/virtual domains Postfix configurationuser = mailuser
password = <mailuserpass>
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'
Next, we have to create /etc/postfix/mysql-virtual-mailbox-maps.cf
:
/etc/postfix/mysql-virtual-mailbox-maps.cf
- MySQL/virtual maps Postfix configurationuser = mailuser
password = <mailuserpass>
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_users WHERE email='%s'
And finally, we have to create /etc/postfix/mysql-virtual-alias-maps.cf
:
/etc/postfix/mysql-virtual-alias-maps.cf
- MySQL/virtual alias maps Postfix configurationuser = mailuser
password = <mailuserpass>
hosts = 127.0.0.1
dbname = mailserver
query = SELECT destination FROM virtual_aliases WHERE source='%s'
If we want Postfix to talk on port 25, we have to make sure that the second field in the line in /etc/postfix/master.cf
for smtp is inet
:
/etc/postfix/master.cf
- Postfix master service file# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (no) (never) (100)
# ==========================================================================
smtp inet n - y - - smtpd
Some ISPs block port 25; in that case you would uncomment the line in master.cf that starts with "submission" (remove the '#' character in front of it) to enable postfix communicating on port 587.
Now lets start Postfix and make sure that our authentication queries are working:
root # /etc/init.d/postfix start root # postmap -q <my.fqdn.com> mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf 1 root # postmap -q <user>@<my.fqdn.com> mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf 1
Assuming both postmap
commands returned 1, we can go on to configuring Dovecot.
Configuring Dovecot
Now that Postfix is properly configured, it's time to tackle Dovecot. The first file we want to look at is /etc/dovecot/dovecot.conf
. In particular, we want to make sure the protocols
line has imap
, pop3
, and lmtp
enabled:
/etc/dovecot/dovecot.conf
- Dovecot configurationprotocols = imap pop3 lmtp
Next we need to look at /etc/dovecot/conf.d/10-mail.conf
. We need to tell Dovecot where to store mail (and, in the case of IMAP, keep it). mail_location
and mail_privileged_group
will likely be in there already and need to be changed; we will likely have to add first_valid_uid
:
/etc/dovecot/conf.d/10-mail.conf
- Dovecot configurationmail_location = maildir:/mailstore/%d/%n
mail_privileged_group = mail
first_valid_uid = 0
Next is /etc/dovecot/conf.d/10-auth.conf
: Here we have to tell Dovecot how we want to authenticate our users. Note that in addition to setting disable_plaintext_auth
to yes and auth_mechanisms
to plain login, we need to comment out (by inserting a '#' in front of) the line !include auth-system.conf.ext
and uncomment (by removing any '#' in front of) the line !include auth-sql.conf.ext
. This is to prevent Dovecot from using native accounts for authorization and use our database instead:
/etc/dovecot/conf.d/10-auth.conf
- Dovecot authorization configdisable_plaintext_auth = yes
auth_mechanisms = plain login
#!include auth-system.conf.ext
!include auth-sql.conf.ext
Next we need to edit /etc/dovecot/conf.d/auth-sql.conf.ext
, so Dovecot knows where and how the passwords are stored, and how and where to write our users' mail:
/etc/dovecot/conf.d/auth-sql.conf.ext
- Dovecot SQL configpassdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = static
args = uid=mail gid=mail home=/mailstore/%d/%n
}
Next is /etc/dovecot/dovecot-sql.conf.ext
, which is mentioned in the previous file. This is to tell Dovecot the details of how to talk to the database in order to validate user logins (replace <mailuserpass> with the password you created for the MySQL user 'mailuser'):
/etc/dovecot/dovecot-sql.conf.ext
- More Dovecot SQL configdriver = mysql
connect = host=127.0.0.1 dbname=mailserver user=mailuser password=<mailuserpass>
default_pass_scheme = SHA512-CRYPT
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';
Next file we have to modify is /etc/dovecot/conf.d/10-master.conf
. First, we will set the listener ports for IMAP and POP3 to zero, to force encrypted links:
/etc/dovecot/conf.d/10-master.conf
- Dovecot master config fileservice imap-login {
inet_listener imap {
port = 0
}
service pop3-login {
inet_listener pop3 {
port = 0
}
Next, we have to configure Dovecot's LMTP service:
/etc/dovecot/conf.d/10-master.conf
- Dovecot master config fileservice lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0666
group = postfix
user = postfix
}
# Create inet listener only if you can't use the above UNIX socket
#inet_listener lmtp {
# Avoid making LMTP visible for the entire internet
#address =
#port =
#}
user=mail
}
Finally, we need to properly set up the auth
and auth-worker
services:
/etc/dovecot/conf.d/10-master.conf
- Dovecot master config fileservice auth {
# auth_socket_path points to this userdb socket by default. It's typically
# used by dovecot-lda, doveadm, possibly imap process, etc. Its default
# permissions make it readable only by root, but you may need to relax these
# permissions. Users that have access to this socket are able to get a list
# of all usernames and get results of everyone's userdb lookups.
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
unix_listener auth-userdb {
mode = 0600
user = mail
#group =
}
# Postfix smtp-auth
#unix_listener /var/spool/postfix/private/auth {
# mode = 0666
#}
# Auth process is run as this user.
user = dovecot
}
service auth-worker {
# Auth worker process is run as root by default, so that it can access
# /etc/shadow. If this isn't necessary, the user should be changed to
# $default_internal_user.
user = mail
}
And last, but not least, we need to edit /etc/dovecot/conf.d/10-ssl.conf
, so that Dovecot knows where to find valid certificates to work with:
/etc/dovecot/conf.d/10-ssl.conf
- Dovecot SSL configssl_cert = </etc/ssl/certs/dovecot.pem
ssl_key = </etc/ssl/private/dovecot.pem
ssl = required
We now need to generate the SSL certificates that Postfix and Dovecot are looking for. When it asks for a FQDN for the certificate, make sure to put in the FQDN of the mail server:
root # openssl req -new -x509 -days 1000 -nodes -out "/etc/ssl/certs/dovecot.pem" -keyout "/etc/ssl/private/dovecot.pem"
Yes, the certificates generated this way are self-signed; if that bothers you feel free to buy one from GoDaddy or some other CA. It won't make things more secure (self-signed certificates have an undeserved bad reputation), but it will make you slightly poorer and the CA slightly richer.
Finally, we set the permissions on the Dovecot config files so they belong to mail:dovecot
and nobody else:
root # chown -R mail:dovecot /etc/dovecot root # chmod -R o-rwx /etc/dovecot
Final Steps
We want Postfix and Dovecot to come up when our server boots up, so we need to add them to the server's startup; once that's done, we'll start Dovecot with the rc
command:
root # rc-update add postfix default root # rc-update add dovecot default root # rc
With that, the mail server should be configured correctly to send and receive email. If it doesn't work, you will probably want to snoop around /var/log/messages
and look for lines that have postfix
or dovecot
in them for clues.
Client Configuration
This configuration is for Thunderbird, but it should be applicable to any other client. When setting up a new account, it will ask for your name, email address, and password. Clicking on the Continue
button will then have Thunderbird attempt to autodetect your mail server settings automagically; this should normally fail (if not, then you're done!). If you look in /var/log/messages
on the mail server, you should see something similar to this:
/var/log/messages
- System log filepostfix/smtpd[]: improper command pipelining after EHLO from <client FQDN>[<client IP>]: QUIT\r\n
The solution then is to select port 993 from the Port:
combobox on the Incoming:
line. Hitting the Re-test
button should allow Thunderbird to properly detect the settings at this point, assuming that the following is true:
- The server hostname fields contain the FQDN of your mail server
- The
Incoming:
andOutgoing:
username fields contain the user's full email address - The password given for the user's email address is correct.
If all else fails, you can try the following settings:
Protocol | Server | Port | SSL | Authentication | |
---|---|---|---|---|---|
Incoming: | IMAP | mail server's FQDN | 993 | SSL/TLS | Normal password |
Outgoing: | SMTP | mail server's FQDN | 25 | STARTTLS | Normal password |
Once the settings are correct in Thunderbird, the first time you send or receive an email message, Thunderbird will ask you to confirm that you want to use the certificates coming from your email server if they are self-signed.
A Few Words on Security, Spam & Blacklists
The email server you have just set up should be reasonably secure from attackers; it won't relay messages outside of your LAN and it won't talk to unencrypted peers. As long as you and your users have chosen good, strong passwords for each link of the chain, you shouldn't have to worry too much about such as bad actors, or being put on spam blacklists. As long as you keep an eye on your mail server and investigate suspicious activity, it should serve you well and work well in the wider Internet environment.
But Wait, There's More!
But only a bit more. Those are the basics, but if you want you can also set up SPF, DKIM, PTR records; unfortunately those are beyond the scope of this article. Other possibilities are spam filtering, push support, and full text-search; these are left as an exercise for the reader.