The Funtoo Linux project has transitioned to "Hobby Mode" and this wiki is now read-only.
Difference between revisions of "Mail Server"
Line 218: | Line 218: | ||
}} | }} | ||
On to {{f|/etc/dovecot/dovecot-sql.conf.ext}}: | On to {{f|/etc/dovecot/dovecot-sql.conf.ext}} (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= | ||
driver = mysql | driver = mysql | ||
connect = host=127.0.0.1 dbname=mailserver user=mailuser password=mailuserpass | connect = host=127.0.0.1 dbname=mailserver user=mailuser password=<mailuserpass> | ||
default_pass_scheme = SHA512-CRYPT | default_pass_scheme = SHA512-CRYPT | ||
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u'; | password_query = SELECT email as user, password FROM virtual_users WHERE email='%u'; |
Revision as of 05:02, December 14, 2016
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 pam ssl
net-mail/dovecot bzip2 maildir 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:
/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 (change the defaults in the file to what's listed here):
/etc/postfix/main.cf
- More Postfix configurationcompatibility_level = 2
myhostname = <my.fqdn.com> # Replace <my.fqdn.com> with your mail server's FQDN
mydomain = <fqdn.com> # Replace <fqdn.com> with your mail server's domain
mydestination = localhost # This MUST be set to localhost
mynetworks = 192.168.0.0/24, 127.0.0.0/8 # Replace 192.168.0.0/24 with your LAN's IP/mask
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
:
/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'
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
:
/etc/dovecot/conf.d/10-mail.conf
- Dovecot configurationmail_location = maildir:/mailstore/%d/%n
mail_privileged_group = mail
first_valid_uid = 0
On to /etc/dovecot/conf.d/10-auth.conf
:
/etc/dovecot/conf.d/10-auth.conf
- Dovecot authorization configdisable_plaintext_auth = yes
auth_mechanisms = plain login
#INSERT a hashtag in front of the following import. This separates your mail server's login from UNIX logins.
#!include auth-system.conf.ext
#REMOVE the hashtag in front of the following import. This points it at mysql for authentication.
!include auth-sql.conf.ext
On to /etc/dovecot/conf.d/auth-sql.conf.ext
:
/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
}
On to /etc/dovecot/dovecot-sql.conf.ext
(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 up is /etc/dovecot/conf.d/10-master.conf
:
/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
}
…
service 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
}
service 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, /etc/dovecot/conf.d/10-ssl.conf
:
/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, they are self-signed certificates; 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 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.