In this article, we are going to show you how to configure a electronic mail server using Postfix, Dovecot, MySQL and SpamAssassin on Ubuntu 12.04. Following this tutorial you'll be able to add virtual domains, users,
and aliases. Moreover, your virtual server will be secure from spam
hub.
Prerequisites
Before setting up your mail server, it's necessary your VPS has the following:* Domain is forwarding to your server (setup your domain by your self or contact your registrar)
* MySQL installed and configured (setup mysql)
Install MySQL
MySQL is a powerful database management system used for organizing and retrieving dataTo install MySQL, open terminal and type in these commands:
sudo apt-get install mysql-server libapache2-mod-auth-mysql php5-mysql
During the installation, MySQL will ask you to set a root password. If you miss the chance to set the password while the program is installing, it is very easy to set the password later from within the MySQL shell.
Once you have installed MySQL, we should activate it with this command:
sudo mysql_install_db
Finish up by running the MySQL set up script:
sudo /usr/bin/mysql_secure_installation
The prompt will ask you for your current root password.
Type it in.
Enter current password for root (enter for none): OK, successfully used password, moving on...
Then the prompt will ask you if you want to change the root password. Go ahead and choose N and move on to the next steps.
It’s easiest just to say Yes to all the options. At the end, MySQL will reload and implement the new changes.
By default, a MySQL installation has an anonymous user, allowing anyone to log into MySQL without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? [Y/n] y ... Success! Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? [Y/n] y ... Success! By default, MySQL comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? [Y/n] y - Dropping test database... ... Success! - Removing privileges on test database... ... Success! Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? [Y/n] y ... Success! Cleaning up...
Database setup completed.
* User with root privileges (setup new users- omit step 5)
The lines that the user needs to enter or customize will be in red in this tutorial! The rest should mostly be copy-and-pastable.The Basics
When you first begin to access your fresh new server, there are a few early steps you should take to make it more secure. Some of the first tasks required on a virtual private server can include setting up a new user, providing them with the proper privileges, and configuring SSH.Step One - Root Login
Once you know your IP address and root password, login as the main user, root.It is not encouraged to use root on a VPS on a regular basis, and this tutorial will help you set up an alternative user to login with permanently.
ssh root@123.45.67.890
The terminal will show:
The authenticity of host '69.55.55.20 (69.55.55.20)' can't be established. ECDSA key fingerprint is 79:95:46:1a:ab:37:11:8e:86:54:36:38:bb:3c:fa:c0. Are you sure you want to continue connecting (yes/no)?
Go ahead and type yes, and then enter your root password.
Step Two - Create a New User
After you have logged in and changed your password, you will not need to login again as root. In this step we will make a new user and give them all of the root capabilities.You can choose any name for your user. Here I’ve suggested Demo
adduser demo
After you set the password, you do not need to enter any further information about the new user. You can leave all the lines blank if you wish
Step Three - Root Privileges
As of yet, only root has all of the administrative capabilities. We are going to give the new user the root privileges. When you perform any root tasks with the new user, you will need to use the phrase “sudo” before the command. This is a helpful command for 2 reasons: 1) it prevents the user making any system-destroying mistakes 2) it stores all the commands run with sudo to the file ‘/var/log/secure' which can be reviewed later if needed.Let’s go ahead and edit the sudo configuration. This can be done through the default editor, which in Ubuntu is called ‘nano’
visudo
Find the section called user privilege specification. It will look like this:
# User privilege specification root ALL=(ALL:ALL) ALL
Under there, add the following line, granting all the permissions to your new user:
demo ALL=(ALL:ALL) ALL
Type ‘cntrl x’ to exit the file.
Press Y to save; press enter, and the file will save in the proper place.
Step Four - Configure SSH (OPTIONAL)
Now it’s time to make the server more secure. These steps are optional. Please keep in mind that changing the port and restricting root login may make logging in more difficult in the future. If you misplace this information, it could be nearly impossible.Open the configuration file
nano /etc/ssh/sshd_config
Find the following sections and change the information where applicable:
Port 25000
Protocol 2
PermitRootLogin no
We’ll take these one by one.
Port: Although port 22 is the default, you can change this to any number between 1025 and 65536. In this example, I am using port 25000. Make sure you make a note of the new port number. You will need it to log in in the future. This change will make it more difficult for unauthorized people to log in.
PermitRootLogin: change this from yes to no to stop future root login. You will now only be logging on as the new user.
Add these lines to the bottom of the document, replacing *demo* in the AllowUsers line with your username. (AllowUsers will limit login to only the users on that line. To avoid this, skip this line):
UseDNS no
AllowUsers demo
Save and ExitStep Five - Reload and Done!
Reload SSH, and it will implement the new ports and settings.reload ssh
To test the new settings (don’t logout of root yet), open a new terminal window and login as your new user.
Don’t forget to include the new port number.
ssh -p 25000 demo@123.45.67.890
Your prompt should now say:
[demo@yourname ~]$
*Configure and identify your FQDN (setup FQDN)
Setting the Fully Qualified Domain Name (FQDN)
In a terminal or shell, execute:sudo vim /etc/hosts
Then, tap on the
i
key and use the arrow keys on your keyboard to navigate the text area. Modify your hosts
file so that it resembles the following (obviously, substituting the hostname
, yourdomain
, tld
, and YourIP
values with your own):127.0.0.1 localhost.localdomain localhost
127.0.1.1 hostname.yourdomain.tld hostname
YourIP hostname.yourdomain.tld hostname
To save & exit, tap the
Esc
key, on your keyboard, followed by these keystrokes: :
, w
, q
, and, finally, Enter
.You can verify that the FQDN was properly set by, again, executing:
hostname -f
DNS Records
If you want your remote server to be reachable over the internet via its FQDN, then you need to create the relevant DNS records.Optional: SSL certificate (setup free signed ssl certificate)
Optional ( Log in as root user )
Installing packages as the root user is useful because you have all privileges.
sudo -i
Introduce your user's password. Once it's successful, you will see that
$
symbol changes to #
.Step 1: Install Packages
apt-get install postfix postfix-mysql dovecot-core dovecot-imapd dovecot-lmtpd dovecot-mysql
When Postfix configuration is prompted choose Internet Site:
Postfix configuration will ask about System mail name – you could use your FDQN or main domain.
Step 2: Create a MySQL Database, Virtual Domains, Users and Aliases
After the installation finishes, we are going to create a MySQL database to configure three different tables: one for domains, one for users and the last one for aliases.We are going to name the database
servermail
, but you can use whatever name you want.Create the servermail database:
mysqladmin -p create servermail
Log in as MySQL root user
mysql -u root -p
Enter your MySQL root's password; if it's successful you will see:
mysql >
First we need to create a new user, specific for mail authentication, and we are going to give SELECT permission.
mysql > GRANT SELECT ON servermail.* TO 'usermail'@'127.0.0.1' IDENTIFIED BY 'mailpassword';
After that, we need to reload MySQL privileges to ensure it applies those permissions successfully:
mysql > FLUSH PRIVILEGES;
Finally we need to use the database for creating tables and introduce our data:
mysql> USE servermail;
We are going to create a table for the specific domains recognized as authorized domains.
CREATE TABLE `virtual_domains` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
We are going to create a table to introduce the users. Here you will add the email address and passwords. It is necessary to associate each user with a domain.
CREATE TABLE `virtual_users` (
`id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT NOT NULL,
`password` VARCHAR(106) NOT NULL,
`email` VARCHAR(120) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Finally we are going to create a virtual aliases table to specify all the emails that you are going to forward to the other email.
CREATE TABLE `virtual_aliases` (
`id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT NOT NULL,
`source` varchar(100) NOT NULL,
`destination` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
We have created the three tables successfully. Now we are going to introduce the data.
Virtual Domains
Here we are going to introduce your domains inside the virtual_domains table. You can add all the domains you want, but in this tutorial we are going to introduce just the primary domain (example.com) and your FQDN (hostname.example.com).
INSERT INTO `servermail`.`virtual_domains`
(`id` ,`name`)
VALUES
('1', 'example.com'),
('2', 'hostname.example.com');
Virtual Emails
We are going to introduce the email address and passwords associated for each domain. Make sure you change all the info with your specific information.
INSERT INTO `servermail`.`virtual_users`
(`id`, `domain_id`, `password` , `email`)
VALUES
('1', '1', ENCRYPT('firstpassword', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'email1@example.com'),
('2', '1', ENCRYPT('secondpassword', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'email2@example.com');
Virtual Aliases
We are going to introduce the email address (source) that we are going to forward to the other email address (destination).
INSERT INTO `servermail`.`virtual_aliases`
(`id`, `domain_id`, `source`, `destination`)
VALUES
('1', '1', 'alias@example.com', 'email1@example.com');
Exit MySQL
mysql > exit
Step 3: Configure Postfix
We are going to configure Postfix to handle the SMTP connections and send the messages for each user introduced in the MySQL Database.First we need to create a copy of the default file, in case you want to revert to the default configuration.
cp /etc/postfix/main.cf /etc/postfix/main.cf.orig
Open the main.cf file to modify it:
nano /etc/postfix/main.cf
First we need to comment the TLS Parameters and append other parameters. In this tutorial, we are using the Free SSL certificates and the paths, but you could modify depending your personal configurations.
# TLS parameters
#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
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
Then we are going to append the following parameters below the TLS settings that we have changed in the previous step:
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions =
permit_sasl_authenticated,
permit_mynetworks,
reject_unauth_destination
We need to comment the
mydestination
default settings and replace it with localhost
. This change allows your VPS to use the virtual domains inside the MySQL table.# mydestination = example.com, hostname.example.com, localhost.example.com, localhost
mydestination = localhost
Verify that myhostname parameter is set with your FQDN.
myhostname = hostname.example.com
Append the following line for local mail delivery to all virtual domains listed inside the MySQL table.
virtual_transport = lmtp:unix:private/dovecot-lmtp
Finally, we need to add these three parameters to tell Postfix to configure the virtual domains, users and aliases.
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
We are going to create the final three files that we append in the main.cf file to tell Postfix how to connect with MySQL. First we need to create the
mysql-virtual-mailbox-domains.cf
file. It's necessary to change the values depending your personal configuration.
nano /etc/postfix/mysql-virtual-mailbox-domains.cf
user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT 1 FROM virtual_domains WHERE name='%s'
Then we need to restart Postfix.
service postfix restart
We need to ensure that Postfix finds your domain, so we need to test it with the following command. If it is successful, it should returns 1:
postmap -q example.com mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
Then we need to create the mysql-virtual-mailbox-maps.cf file.
nano /etc/postfix/mysql-virtual-mailbox-maps.cf
user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT 1 FROM virtual_users WHERE email='%s'
We need to restart Postfix again.
service postfix restart
At this moment we are going to ensure Postfix finds your first email address with the following command. It should return 1 if it's successful:
postmap -q email1@example.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
Finally, we are going to create the last file to configure the connection between Postfix and MySQL.
nano /etc/postfix/mysql-virtual-alias-maps.cf
user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT destination FROM virtual_aliases WHERE source='%s'
Restart Postfix
service postfix restart
We need to verify Postfix can find your aliases. Enter the following
command and it should return the mail that's forwarded to the alias:postmap -q alias@example.com mysql:/etc/postfix/mysql-virtual-alias-maps.cf
If you want to enable port 587 to connect securely with email clients, it is necessary to modify the /etc/postfix/master.cf file
nano /etc/postfix/master.cf
We need to uncomment these lines and append other parameters:
submission inet n - - - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
In some cases, we need to restart Postfix to ensure port 587 is open.
service postfix restart
Note: You can use this tool to scan your domain ports and verify that port 25 and 587 are open (http://mxtoolbox.com/SuperTool.aspx)
Step 4: Configure Dovecot
We are going to copy the 7 files we're going to modify, so that you could revert it to default if you needed to. Enter the following commands one by one:
cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.orig
cp /etc/dovecot/conf.d/10-mail.conf /etc/dovecot/conf.d/10-mail.conf.orig
cp /etc/dovecot/conf.d/10-auth.conf /etc/dovecot/conf.d/10-auth.conf.orig
cp /etc/dovecot/dovecot-sql.conf.ext /etc/dovecot/dovecot-sql.conf.ext.orig
cp /etc/dovecot/conf.d/10-master.conf /etc/dovecot/conf.d/10-master.conf.orig
cp /etc/dovecot/conf.d/10-ssl.conf /etc/dovecot/conf.d/10-ssl.conf.orig
Edit configuration file from Dovecot.
nano /etc/dovecot/dovecot.conf
Verify this option is uncommented.
!include conf.d/*.conf
We are going to enable protocols (add pop3 if you want to) below the
!include_try /usr/share/dovecot/protocols.d/*.protocol line
.
!include_try /usr/share/dovecot/protocols.d/*.protocol
protocols = imap lmtp
Then we are going to edit the mail configuration file:
nano /etc/dovecot/conf.d/10-mail.conf
Find the
mail_location
line, uncomment it, and put the following parameter:mail_location = maildir:/var/mail/vhosts/%d/%n
Find the
mail_privileged_group
line, uncomment it, and add the mail parameter like so:mail_privileged_group = mail
Verify permissions
Enter this command:
ls -ld /var/mail
Ensure permissions are like this:
drwxrwsr-x 3 root vmail 4096 Jan 24 21:23 /var/mail
We are going to create a folder for each domain that we register in the MySQL table:
mkdir -p /var/mail/vhosts/example.com
Create a vmail user and group with an id of 5000
groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /var/mail
We need to change the owner of the
/var/mail
folder to the vmail user.chown -R vmail:vmail /var/mail
Then we need to edit the
/etc/dovecot/conf.d/10-auth.conf
file:nano /etc/dovecot/conf.d/10-auth.conf
Uncomment plain text authentication and add this line:
disable_plaintext_auth = yes
Modify
auth_mechanisms
parameter:auth_mechanisms = plain login
Comment this line:
#!include auth-system.conf.ext
Enable MySQL authorization by uncommenting this line:
!include auth-sql.conf.ext
We need to create the /etc/dovecot/dovecot-sql.conf.ext file with your information for authentication:nano /etc/dovecot/conf.d/auth-sql.conf.ext
Enter the following code in the file:
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}
We need to modify the
/etc/dovecot/dovecot-sql.conf.ext
file with our custom MySQL information:nano /etc/dovecot/dovecot-sql.conf.ext
Uncomment the driver parameter and set mysql as parameter:
driver = mysql
Uncomment the connect line and introduce your MySQL specific information:
connect = host=127.0.0.1 dbname=servermail user=usermail password=mailpassword
Uncomment the
default_pass_scheme
line and change it to SHA-512
.default_pass_scheme = SHA512-CRYPT
Uncomment the
password_query
line and add this information:password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';
Change the owner and the group of the dovecot folder to vmail user:
chown -R vmail:dovecot /etc/dovecot
chmod -R o-rwx /etc/dovecot
Open and modify the
/etc/dovecot/conf.d/10-master.conf
file (be careful because different parameters will be changed).
nano /etc/dovecot/conf.d/10-master.conf
##Uncomment inet_listener_imap and modify to port 0
service imap-login {
inet_listener imap {
port = 0
}
#Create LMTP socket and this configurations
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
#inet_listener lmtp {
# Avoid making LMTP visible for the entire internet
#address =
#port =
#}
}
Modify
unix_listener
parameter to service_auth
like this:
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
unix_listener auth-userdb {
mode = 0600
user = vmail
#group =
}
#unix_listener /var/spool/postfix/private/auth {
# mode = 0666
#}
user = dovecot
}
Modify
service auth-worker
like this:
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 = vmail
}
Finally, we are going to modify the SSL configuration file from Dovecot (skip this step if you are going to use default configuration).
# nano /etc/dovecot/conf.d/10-ssl.conf
Change the ssl parameter to required:
<ssl = required
And modify the path for
ssl_cert
and ssl_key
:ssl_cert = </etc/ssl/certs/dovecot.pem
ssl_key = </etc/ssl/private/dovecot.pem
Restart Dovecot
service dovecot restart
You should check that port 993 is open and working (in case you enable pop3; you should check also port 995).
telnet example.com 993
Congratulations. You have successfully configured your mail server and you may test your account using an email client:
- Username: email1@example.com - Password: email1's password - IMAP: example.com - SMTP: example.com
Note: use port 993 for secure IMAP and port 587 or 25 for SMTP.
Step 5: Configure SpamAssassin
First we need to install SpamAssassin.apt-get install spamassassin spamc
Then we need to create a user for SpamAssassin.
adduser spamd --disabled-login
To successfully configure SpamAssassin, it's necessary to open and modify the configuration settings.
nano /etc/default/spamassassin
We need to change the
ENABLED
parameter to enable SpamAssassin daemon.ENABLED=1
We need to configure the home and options parameters.
SPAMD_HOME="/home/spamd/"
OPTIONS="--create-prefs --max-children 5 --username spamd --helper-home-dir ${SPAMD_HOME} -s ${SPAMD_HOME}spamd.log"
Then we need to specify the
PID_File
parameter like this:PIDFILE="${SPAMD_HOME}spamd.pid"
Finally, we need to specify that SpamAssassin's rules will be updated automatically.
CRON=1
We need to open
/etc/spamassassin/local.cf
to set up the anti-spam rules.
nano /etc/spamassassin/local.cf
SpamAssassin will score each mail and if it determines this email is greater than 5.0 on its spam check, then it automatically will be considered spam. You could use the following parameters to configure the anti-spam rules:
rewrite_header Subject ***** SPAM _SCORE_ *****
report_safe 0
required_score 5.0
use_bayes 1
use_bayes_rules 1
bayes_auto_learn 1
skip_rbl_checks 0
use_razor2 0
use_dcc 0
use_pyzor 0
We need to change the Postfix
/etc/postfix/master.cf
file to tell it that each email will be checked with SpamAssassin.nano /etc/postfix/master.cf
Then we need to find the following line and add the spamassassin filter:
smtp inet n - - - - smtpd
-o content_filter=spamassassin
Finally we need to append the following parameters:
spamassassin unix - n n - - pipe
user=spamd argv=/usr/bin/spamc -f -e
/usr/sbin/sendmail -oi -f ${sender} ${recipient}
It is necessary to start SpamAssassin and restart Postfix to begin verifying spam from emails.
service spamassassin start
service postfix restart
Congratulations! You have successfully set up your mail server with Postfix and Dovecot with MySQL authentication and spam filtering with SpamAssassin!
No comments: