Servers 101: Emailify your server - Part 1

in #tutorial7 years ago (edited)

What good is a webserver if we can't receive & send email? It's no good, I tell you. In this tutorial we will install Postfix and Dovecot. We will configure them to use MySQL for authentication. Last, but not least, we will setup the email hostname we use for the mail server on Apache, and install Roundcube for webmail access!


Other stuff in the Server 101 series:


Before we begin (Taking care of DNS)

We need to do some other stuff before we begin! You must take a note of your server's IP address as well as add a hostname for this IP on your DNS manager. I will be using mail.example.com for the hostname, and 192.168.0.1 for the IP on this tutorial. REMEMBER TO SUBSTITUTE THEM WITH YOUR OWN!

You need to add a record for your domain (example.com) that will tell other servers you want your email delivered on mail.example.com. The record we need is an "MX Record" (Mail eXchanger). You will need to set a priority for this record. Priority is a 16bit number (0-65535) that determines which email server will be contacted first. If that server is down, the sender's mail server will try to deliver the email to the server with the 2nd lowest number etc. So, an MX record for old timers who don't use any GUI for DNS records would be:

example.com         MX      10      192.168.0.1



or if you have set an A record, you can use the hostname as such:

example.com         MX      10      mail.example.com



You could always use the main hostname of your server (such as "example.com") for your emails, but if at some point you need to move your mail server to a different machine, you'll have to reconfigure it. It is strongly advised to use a different hostname.


SSL Certificate

At some point Dovecot (our POP3/IMAP email server) provided an SSL certificate. Since Debian 8, the certificate is no longer provided and you have to make one yourself. You can create one via Let's Encrypt. I won't be covering this right now! You can either try to do it yourself, or you can wait and we will do it later. Remember, we will also add a Webmail app, so you can go on and setup an Apache vhost with your hostname and create a Let's Encrypt certificate that way. It will be usable for Dovecot as well!


Firewall!

If you followed my series of tutorials, or you installed a firewall, you have to open the ports we need for our mail server. The standard email ports are (SMTP) 25, 465, 587, (POP3) 110, 995 and finally (IMAP3) 143 and 993

The command we need is

ufw allow (port)

so we'll have to run:

ufw allow 25
ufw allow 465
ufw allow 587
ufw allow 110
ufw allow 995
ufw allow 143
ufw allow 993

Package Installation

For this tutorial, we're going to use the root account. If you followed my tutorials, you'll have to login with your user and do sudo su in order to be root.

Go ahead and install the packages. Don't forget to run an update and install any updates available first!

apt-get update
apt-get upgrade
apt-get install postfix postfix-mysql dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd dovecot-mysql mysql-server

We will get asked for a few details.

We will get asked what type of email server we want. We will choose "Internet Site" as we want to sent and receive email from the internet!

We will also be asked about our system email name. Enter your hostname. In this example, I used mail.example.com.

This will take a little while to install, so grab a fresh cup of coffee and enjoy it watching letters come and go on your screen!


Setting up a MySQL database

We will have to create and fill a database which will hold the domains and accounts of our mailserver. Yes, we can use this to host email for as many domains as we want (although at some point you'll have to upgrade your server with more RAM and space)

  • First, create the database (and the corresponding user):
mysqladmin -p create mailserver

Enter your MySQL password, and continue!

  • You now have to enter the mysql command-line tools
mysql -p mailserver


  • And grant the new user permissions on the new database we created. Don't forget to change "changethispass" to a password you want.
GRANT SELECT ON mailserver.* TO 'mailuser'@'127.0.0.1' IDENTIFIED BY 'changethispass';
FLUSH PRIVILEGES;
  • We also have to create 3 tables! The receiving domain(s) table, the user/password table and email aliases table.
CREATE TABLE `virtual_domains` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `virtual_users` (
  `id` int(11) NOT NULL auto_increment,
  `domain_id` int(11) NOT NULL,
  `password` varchar(106) NOT NULL,
  `email` varchar(100) 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;

CREATE TABLE `virtual_aliases` (
  `id` int(11) NOT NULL auto_increment,
  `domain_id` int(11) 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;



Copy and paste the above snippet in the MySQL command line we have open!


Adding initial data to MySQL

We will now add our domain(s), a couple email addresses and a few aliases. An alias serves as a secondary email address for an account. You can have as many aliases you want, and all email messages will come to the same account

  • Add your domain(s)

Copy/paste this inside the MySQL command line tool we have already open, but first change the domains. If you want only one domain, remove the last 2 lines, and substitute the comma (,) with a semicolon (;)

INSERT INTO `mailserver`.`virtual_domains`
  (`id` ,`name`)
VALUES
  ('1', 'example.com'),
  ('2', 'example.net'),
  ('3', 'example.org');



Later, if you want to add more domains, you can do it from PHPMyAdmin. We can also do all this on PHPMyAdmin, but I want you to experience working with command-line tools a little bit.

Keep in mind the IDs (example.com has ID 1, example.net has ID 2, example.org has ID 3), as we will need them to add our users!

  • Add your users:

You have to change: "domainid" to the correct ID of each domain, "changethispass" to a normal password, and "emailaddress" to an email. Be careful not to remove the ' from any field.

INSERT INTO `mailserver`.`virtual_users`
  (`id`, `domain_id`, `password` , `email`)
VALUES
  ('1', 'domainid', ENCRYPT('changethispass', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'emailaddress'),
  ('2', 'domainid', ENCRYPT('changethispass', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'emailaddress'),
  ('3', 'domainid', ENCRYPT('changethispass', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'emailaddress'),
  ('4', 'domainid', ENCRYPT('changethispass', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'emailaddress');

A working example would be:

('1', '3', ENCRYPT('asuio7a6r8$$oiswe', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), '[email protected]')

  • And also setup an alias, if you want to:
INSERT INTO `mailserver`.`virtual_aliases`
  (`id`, `domain_id`, `source`, `destination`)
VALUES
  ('1', '3', '[email protected]', '[email protected]');



Check the records!

You can check the records you added like this:

SELECT * FROM mailserver.virtual_domains;

You should now see your domains like this:

+----+-------------+
| id | name        |
+----+-------------+
|  1 | example.com |
|  2 | example.net |
|  3 | example.org |
+----+-------------+
3 rows in set (0.00 sec)

In the saim vein, you can see the users:

SELECT * FROM mailserver.virtual_users;

With the result coming back at you being something like this:

+----+-----------+------------------------------------------------------------------------------------------------------------+------------------+
| id | domain_id | password                                                                                                   | email            |
+----+-----------+------------------------------------------------------------------------------------------------------------+------------------+
|  1 |         3 | $6$eef43190a349aa9a$QsnZnjEuIsqg80GdwJPeorwDT1xr90Bcg/kXicWLWbevcMTAHhoRFpNPdB3/QeGSzAxqUcX9mh/oxrtX57rJf0 | [email protected] |
+----+-----------+------------------------------------------------------------------------------------------------------------+------------------+
1 row in set (0.00 sec)



and also the aliases:

SELECT * FROM mailserver.virtual_aliases;



Which results into this:

+----+-----------+--------------------+--------------------+
| id | domain_id | source             | destination        |
+----+-----------+--------------------+--------------------+
|  1 |         1 | [email protected] | [email protected]   |
+----+-----------+--------------------+--------------------+
1 row in set (0.00 sec)

That's it for now. In the next part we will start with configuring postfix and dovecot.

Second part, postfix configuration, is now available!


If you need a place to host your servers consider Vultr, Digital Ocean and BuyVM.

These are affiliate links. If you sign up through them, you support me and I will have more free time to write more content like this.

Also If you signup for Digital Ocean through my affiliate link, you will get $10 to try them out. Note: to battle abusers of this offer, you'll have to make a $5 deposit via Paypal or add your credit/debit card, so they can confirm that you are a new user. I did a deposit via Paypal to test them out, and then I added my credit card so I won't have to deposit money manually every now and then.


Also, I am running a witness server.

Please consider voting me, dimitrisp, for a witness if you find what I post & do helpful and add value to the network

You can read my witness declaration here

Coin Marketplace

STEEM 0.18
TRX 0.15
JST 0.029
BTC 62066.10
ETH 2419.11
USDT 1.00
SBD 2.66