How to setup properly a email server on Ubuntu with postfix, dovecot and opendkim

After checking dozens of blog posts to know how to setup my own mail server on ubuntu, I have been able to create a server that sends mail to any mail provider and those doesn’t get to the SPAM folder!! Here’s how I did it

In case this doesn’t work for you, just write to me and I will help you, has been a long since I configure it and maybe something it is in the wind. So I will make this post better and help you so, win win.

1. Install the required programs to use.

sudo apt-get install postfix postfix-mysql dovecot-core dovecot-imapd dovecot-lmtpd dovecot-mysql opendkim opendkim-tools sasl2-bin dovecot-pop3d

During the install of this packages some configuration prompts will be diplayed read them and select the one for you.

2. We will need to setup a database to handle the domains and users that our email server will use.

We are going to create a database named “mailserver” but you can name it as you want.

The tables that we are going to create are

domains:

  • id: int(autoincrement)
  • name varchar(255)

CREATE TABLE domains (id INT NOT NULL AUTO_INCREMENT, name VARCHAR(255) NOT NULL, PRIMARY KEY (id), UNIQUE KEY unique_name (name));

users:

  • id: int(autoincrement)
  • domain_id: int(foreign_for_id_on_virtual_domains)
  • name: varchar(50)
  • username: varchar(50)
  • email: varchar(255)
  • mail_directory: varchar(255)
  • password: varchar(255)

CREATE TABLE users (id INT NOT NULL AUTO_INCREMENT, domain_id INT NOT NULL, name VARCHAR(50), username VARCHAR(50), email VARCHAR(255), mail_directory VARCHAR(255), password VARCHAR(255), PRIMARY KEY (id), FOREIGN KEY (domain_id) REFERENCES domains(id), UNIQUE KEY unique_email (email));

aliases:

  • id: int(autoincrement)
  • domain_id: int(foreign_for_id_on_virtual_domains)
  • src: varchar(250)
  • dst: varchar(250)

CREATE TABLE aliases (id INT NOT NULL AUTO_INCREMENT, domain_id INT NOT NULL, src VARCHAR(250) NOT NULL, dst VARCHAR(250) NOT NULL, PRIMARY KEY (id), FOREIGN KEY (domain_id) REFERENCES domains(id));

Well there is nothing really complicated here, the things to consider are: Make the email field for users unique, the mail_directory should be something like “virtual_host.com/username/” (it’s important that last slash), there is much that can be refactored for this database, but this is the simpliest way, for the password field we are not going to put it there plain text, the SQL command to store it is: ENCRYPT(‘PLAIN_PASSWORD’, CONCAT(‘$6$’, SUBSTRING(SHA(RAND()), -16)))

3. Creating the configuration files for postfix to read from the database

This files can be stored in the configuration folder for postfix (/etc/postfix)

mysql-mailbox-domains.cf
user = DATABASE_USER
password = DATABASE_PASSWORD
hosts = DATABASE_HOST
dbname = DATABASE_NAME
query = SELECT 1 FROM domains WHERE name = '%s'

mysql-mailbox-maps.cf
user = DATABASE_USER
password = DATABASE_PASSWORD
hosts = DATABASE_HOST
dbname = DATABASE_NAME
query = SELECT mail_directory FROM users WHERE email = '%s'

mysql-alias-maps.cf
user = DATABASE_USER
password = DATABASE_PASSWORD
hosts = DATABASE_HOST
dbname = DATABASE_NAME
query = SELECT dst FROM aliases WHERE src = '%s'

After create those files you can check them using
postmap -q email@example.com mysql:/etc/postfix/mysql-mailbox-maps.cf
And view the return it’s a good idea to postmap all of them.

4. Configure postfix

We will be doing well backing up the original postfix configuration files in case that we make a mess of them.
These files are located on /etc/postfix/

Start configuring the main.cf file
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no
append_dot_mydomain = no
readme_directory = no
# TLS parameters
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
queue_directory = /var/spool/postfix
smtpd_sasl_auth_enable = yes
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_destination
smtpd_sasl_security_options = noanonymous
# Please use valid SSL certificates in order to validate the connection
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
# Fixing encryption warning
smtpd_tls_security_level=may
smtpd_tls_loglevel=1
smtp_tls_security_level=may
smtp_tls_loglevel=1
broken_sasl_auth_clients = yes
myhostname = EXAMPLE.COM
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = localhost
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
milter_protocol = 2
milter_default_action = accept
smtpd_milters = inet:localhost:12301
non_smtpd_milters = inet:localhost:12301
virtual_mailbox_domains = mysql:/etc/postfix/mysql-mailbox-domains.cf
virtual_mailbox_base = /var/mail/vhosts
virtual_mailbox_maps = mysql:/etc/postfix/mysql-mailbox-maps.cf
virtual_minimum_uid = 100
# Change this values for the UID and GID of your vmail user
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_alias_maps = mysql:/etc/postfix/mysql-alias-maps.cf

And now the master.cf
smtp inet n - - - - smtpd
submission inet n - - - - smtpd
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/auth
-o smtpd_sasl_security_options=noanonymous
-o smtpd_sasl_local_domain=$myhostname
-o smtpd_client_restrictions=permit_sasl_authenticated,reject

Now restart postfix to load the new configuration.
sudo service postfix restart

5. Configure dovecot

Dovecot it’s a IMAP POP3 handler, always it’s a good idea to backup the configuration that we are going to modify.
Make sure that /etc/dovecot/dovecot.conf has the include conf.d/*.conf line uncommented.

Modify the conf.d/10-mail.conf and set the line mail_location = maildir:/var/mail/vhosts/%d/%n
As you can see this correspond to the domain/username that we have setting up before for the users. Make sure to give the properly permissions to the user and group vmail for that folder. Or the user that you are going to use. Obviously create a folder for every domain that you create on the database.

Modify the conf.d/10-auth.conf
disable_plaintext_auth = no
auth_mechanisms = plain login digest-md5 cram-md5 apop rpa skey
!include auth-sql.conf.ext

Modify conf.d/auth-sql.conf.ext
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}

Modify dovecot-sql.conf.ext
driver = mysql
connect = host=DATABASE_HOST dbname=DATABASE_NAME user=DATABASE_USER password=DATABASE_PASSWORD
default_pass_scheme = SHA512-CRYPT
password_query = \
SELECT email AS user, password FROM users WHERE email = '%u'

Modify conf.d/10-master.conf

Create a self signed certificate or use one of your own, it may be good to store it on /etc/dovecot/private/
openssl req -new -x509 -days 1000 -nodes -out "example.com.public.pem" -keyout "example.com.private.pem"
And modify the file conf.d/10-ssl.conf

ssl = yes
#local_name example.com {
 ssl_cert = </etc/dovecot/private/example.com.public.pem
 ssl_key = </etc/dovecot/private/example.com.private.pem
#}

It may be necessary to include the line protocols = imap pop3 lmtp in the file /etc/dovecot/dovecot.conf

At this point you should be able to send and receive mails from any server, but most likely when sending mails they are going to be on the SPAM folder so in order to avoid that on a great manner, we are going to certificate the mails with opendkim

6. Configure opendkim
https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-dkim-with-postfix-on-debian-wheezy

And set the content of the mail.txt file AKA public key to your domain TXT Record Like
Name: mail._domainkey.example.com
Text: “v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5N3lnvvrYgPCRSoqn+awTpE+iGYcKBPpo8HHbcFfCIIV10Hwo4PhCoGZSaKVHOjDm4yefKXhQjM7iKzEPuBatE7O47hAx1CJpNuIdLxhILSbEmbMxJrJAG0HZVn8z6EAoOHZNaPHmK2h4UUrjOG8zA5BHfzJf7tGwI+K619fFUwIDAQAB”

Advertisements

One thought on “How to setup properly a email server on Ubuntu with postfix, dovecot and opendkim

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s