In this guide, we will demonstrate how to install and configure a mail server on Ubuntu 24.04, as large and medium-sized companies can greatly benefit from having a private email server. By utilizing a mail server, it becomes feasible to monitor all email traffic closely. Additionally, the flexibility to customize settings enables the establishment of a clear and organized email service. While there are various options available for setting up a Linux email server, we will specifically concentrate on Postfix and Dovecot.
Table of Contents
Prerequisites for an Email Server on Ubuntu 24.04
- An Ubuntu 24.04 VPS
- SSH root access or a user with sudo privileges is required
Conventions
# – given commands should be executed with root privileges either directly as a root user or by use of sudo command
$ – given commands should be executed as a regular user
Step 1. Set Hostname
Hostname is a label used to identify a machine and will help you distinguish your servers from the others. You would need to create a DNS A record for your hostname because the server hostname should be an FQDN (Fully Qualified Domain Name). For example, we will use ubuntu.yourdomain.com as the server hostname in this tutorial. Subsequently, execute the following command:
$ sudo hostnamectl set-hostname ubuntu.yourdomain.com
Make sure to replace ubuntu.yourdomain.com with your own subdomain pointing to your server’s IP address
Step 2. Install Dependencies
In this step, we will install an Apache web server, PHP with its extensions, and MariaDB as the database server. Let’s execute this command below.
$ sudo apt install apache2 git mariadb-server php-{xml,pear,imap,intl,common,json,curl,mbstring,mysql,gd,imagick,zip,opcache,sqlite3} libapache2-mod-php
Step 3. Create a System User
In this step, we will create a new system user to store the emails on the server. Let’s invoke the command below.
$ sudo useradd -r -u 150 -g mail -d /var/vmail -s /sbin/nologin -c "Virtual Mail User" vmail
$ sudo mkdir -p /var/vmail
$ sudo chmod -R 770 /var/vmail
$ sudo chown -R vmail:mail /var/vmail
Step 4. Create a Database
Next, let’s create a database. By default, you can log in to MySQL shell without a password.
$ sudo mysql
Once logged in, let’s run these commands.
MariaDB [(none)]> CREATE DATABASE postfixadmin;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON postfixadmin.* TO 'postfixadmin'@'localhost' IDENTIFIED BY 'M0d1fyth15';
MariaDB [(none)]> FLUSH PRIVILEGES;
MariaDB [(none)]> \q
Step 5. Install Postfix
Install the Postfix mail server from the Ubuntu default repository with this command:
$ sudo apt install postfix-mysql
The mail server related data will be stored in a MySQL database. Once the package postfix-mysql installation is completed we need to create several configuration files for Postfix to communicate with the database.
$ sudo mkdir -p /etc/postfix/sql
Match the password, database name, and database user with those you created in the earlier step.
$ sudo nano /etc/postfix/sql/mysql_virtual_alias_maps.cf
user = postfixadmin
password = M0d1fyth15
hosts = localhost
dbname = postfixadmin
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
$ sudo nano /etc/postfix/sql/mysql_virtual_domains_maps.cf
user = postfixadmin
password = M0d1fyth15
hosts = localhost
dbname = postfixadmin
query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'
$ sudo nano /etc/postfix/sql/mysql_virtual_mailbox_maps.cf
user = postfixadmin
password = M0d1fyth15
hosts = localhost
dbname = postfixadmin
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
$ sudo nano /etc/postfix/sql/mysql_virtual_alias_domain_maps.cf
user = postfixadmin
password = M0d1fyth15
hosts = localhost
dbname = postfixadmin
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'
$ sudo nano /etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
user = postfixadmin
password = M0d1fyth15
hosts = localhost
dbname = postfixadmin
query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1'
$ sudo nano /etc/postfix/sql/mysql_virtual_mailbox_limit_maps.cf
user = postfixadmin
password = M0d1fyth15
hosts = localhost
dbname = postfixadmin
query = SELECT quota FROM mailbox WHERE username='%s' AND active = '1'
$ sudo nano /etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf
user = postfixadmin
password = M0d1fyth15
hosts = localhost
dbname = postfixadmin
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'
Now, we can run the commands below to edit postfix’s main.cf file.
$ sudo postconf -e "myhostname = $(hostname -f)" $ sudo postconf -e "mydestination = localhost" $ sudo postconf -e "mynetworks = 127.0.0.0/8" $ sudo postconf -e "inet_protocols = ipv4" $ sudo postconf -e "inet_interfaces = all" $ sudo postconf -e "smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem" $ sudo postconf -e "smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key" $ sudo postconf -e "smtpd_use_tls = yes" $ sudo postconf -e "smtpd_tls_auth_only = yes" $ sudo postconf -e "smtpd_sasl_type = dovecot" $ sudo postconf -e "smtpd_sasl_path = private/auth" $ sudo postconf -e "smtpd_sasl_auth_enable = yes" $ sudo postconf -e "smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination" $ sudo postconf -e "virtual_transport = lmtp:unix:private/lmtp" $ sudo postconf -e "virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf" $ sudo postconf -e "virtual_alias_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf, proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf, proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf" $ sudo postconf -e "virtual_mailbox_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf, proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf"
Once completed, we can continue and edit /etc/postfix/master.cf file:
$ sudo nano /etc/postfix/master.cf
Modify or add the following lines to the file.
smtp inet n - y - - smtpd
#smtp inet n - y - 1 postscreen
#smtpd pass - - y - - smtpd
#dnsblog unix - - y - 0 dnsblog
#tlsproxy unix - - y - 0 tlsproxy
# Choose one: enable submission for loopback clients only, or for any client.
#127.0.0.1:submission inet n - y - - smtpd
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
# -o smtpd_tls_auth_only=yes
# -o local_header_rewrite_clients=static:all
# -o smtpd_reject_unlisted_recipient=no
# Instead of specifying complex smtpd_<xxx>_restrictions here,
# specify "smtpd_<xxx>_restrictions=$mua_<xxx>_restrictions"
# here, and specify mua_<xxx>_restrictions in main.cf (where
# "<xxx>" is "client", "helo", "sender", "relay", or "recipient").
# -o smtpd_client_restrictions=
# -o smtpd_helo_restrictions=
# -o smtpd_sender_restrictions=
# -o smtpd_relay_restrictions=
# -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
Step 6. Install Dovecot
Run this command to install Dovecot.
$ sudo apt install dovecot-mysql dovecot-imapd dovecot-pop3d dovecot-lmtpd
Once Dovecot is installed, we can proceed with the following steps and edit some configuration files.
Open the /etc/dovecot/conf.d/10-auth.conf file
$ sudo nano /etc/dovecot/conf.d/10-auth.conf
Then, find this line
auth_mechanisms = plain
and replace the line with this one:
auth_mechanisms = plain login
Then, we need to comment !include auth-system.conf.ext and uncomment the line !include auth-sql.conf.ext
It should look like this:
#!include auth-system.conf.ext
!include auth-sql.conf.ext
Still in the 10-auth.conf file, we include auth-sql.conf.ext. So, let’s edit the file so it gets executed.
$ sudo nano /etc/dovecot/dovecot-sql.conf.ext
Insert the following lines into the file:
driver = mysql
connect = host=localhost dbname=postfixadmin user=postfixadmin password=M0d1fyth15
default_pass_scheme = BLF-CRYPT
password_query = SELECT username as user, password, '/var/vmail/%d/%n' as userdb_home, 'maildir:/var/vmail/%d/%n' as userdb_mail, 150 as userdb_uid, 8 as userdb_gid FROM mailbox WHERE username = '%u' AND active = '1'
user_query = SELECT '/var/vmail/%d/%u' as home, 'maildir:/var/vmail/%d/%u' as mail, 150 AS uid, 8 AS gid, concat('dirsize:storage=', quota) AS quota FROM mailbox WHERE username = '%u' AND active = '1'
The lines above contain the database credentials. Make sure they match the ones you created in the previous step. Save the file and exit
Next, open the /etc/dovecot/conf.d/10-mail.conf file and change the following values:
$ sudo nano /etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:/var/vmail/%d/%n
mail_uid = vmail
mail_gid = mail
mail_privileged_group = mail
first_valid_uid = 150
last_valid_uid = 150
Save the file, then exit. Now, let’s proceed with editing other dovecot configuration files.
$ sudo nano /etc/dovecot/conf.d/10-master.conf
There are several changes you need to make in this file.
Find the service lmtp section and change it to the following:
service lmtp {
unix_listener /var/spool/postfix/private/lmtp {
mode = 0600
user = postfix
group = postfix
}
}
Find the service auth section and change it to:
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
unix_listener auth-userdb {
mode = 0600
user = vmail
}
user = dovecot
}
Change the service auth-worker section to the following:
service auth-worker {
user = vmail
}
Do not forget to save the file and then exit. And now, it is time to correct the permissions.
$ sudo chown -R vmail:dovecot /etc/dovecot
$ sudo chmod -R o-rwx /etc/dovecot
Step 7. Install PostfixAdmin
In this step, we will download PostfixAdmin from Github and store it in the /opt directory.
$ sudo cd /opt
$ sudo git clone https://github.com/postfixadmin/postfixadmin.git
$ sudo cd /opt/postfixadmin
$ sudo bash install.sh
Let’s correct the permission.
$ sudo chown -R www-data: /opt/postfixadmin
Add /etc/apache2/conf-enabled/postfixadmin.conf
$ sudo nano /etc/apache2/conf-enabled/postfixadmin.conf
Insert these lines into that file.
Alias /postfixadmin /opt/postfixadmin/public
<Directory "/opt/postfixadmin/public">
AllowOverride All
Options +FollowSymLinks
Require all granted
</Directory>
Then, we need to reload Apache.
$ sudo systemctl reload apache2
Next, let’s create config.local.php
$ sudo nano /opt/postfixadmin/config.local.php
and insert the following lines
<?php
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfixadmin';
$CONF['database_password'] = 'M0d1fyth15';
$CONF['database_name'] = 'postfixadmin';
$CONF['configured'] = true;
?>
Save the file, then exit from the editor.
Go to http://YOUR_IP_ADDRESS/postfixadmin/setup.php and create a setup password. If you already have a website on your server, you can also access postfixadmin at http://yourdomain.com/postfixadmin/setup.php
Type your setup password twice and click on Generate setup_password hash button.
You will see a line containing a setup password, and you need to copy it to config.local.php, something like:
$CONF['setup_password'] = '$2y$10$YpUXiIQAP47pudUDz0n3leljN2ap5xBq/O1ntFmgAtU0WArEXy84y';
After adding the line to config.local.php file, you can refresh the page to log in and create a superadmin.
Scroll down to create a superadmin account. The setup password you created earlier is required to create a superadmin. In the admin field, it should be filled with an email address, it should look like this:
Now that a superadmin has been created, you can use the credentials to log in to http://192.168.53.5/postfixadmin/login.php and add domains, email address, etc.
Step 8. Install Webmail
At this point, your server can send emails. To receive emails, make sure your domain’s DNS MX record points to this server. You can use your favorite email client to send emails or use a webmail instead. Let’s install Roundcube now.
$ sudo apt install roundcube
Next, let’s edit rouncube configuration file at /etc/apache2/conf-enabled/roundcube.conf
$ sudo nano /etc/apache2/conf-enabled/roundcube.conf
Uncomment this line
# Alias /roundcube /var/lib/roundcube/public_html
And it should look like this:
Alias /roundcube /var/lib/roundcube/public_html
Save the file, exit then restart apache
$ sudo systemctl restart apache2
The next step is to edit another Rouncube config file, this one at /etc/roundcube/config.inc.php
$ sudo nano /etc/roundcube/config.inc.php
Find this string:
$config['smtp_host'] = 'localhost:587';
and replace it with this one:
$config['smtp_host'] = 'tls://%n:587';
You successfully installed an Email Server on Ubuntu 24.04
You can now navigate to your http://YOUR_SERVER_IP_ADDRESS/roundcube and log in using the credentials you created in the previous step. Once logged in, you can try to send an email.
Of course, you don’t have to install and configure an email server on Ubuntu 24.04 server if you have a server with us, in which case you can simply ask our expert Linux hosting admins to set all of this up for you, quickly and easily. They are available 24×7 and will respond to your request immediately. Our admins will also help you with more complex mail server installation, like using OpenDKIM, SPF, and DMARC.
PS. If you liked this post, please share it with your friends on social networks or simply leave a comment down in the comments section. Thank you.
Hi,
Not sure if I have done something wrong, but I’m fairly sure I have followed the steps exactly:
When I get to:
sudo nano /etc/postfix/sql/mysql_virtual_alias_maps.cf
there is no such file. Upon checking, the directory (/etc/postfix/sql/) exists, but is completely empty.
Any suggestions welcome :-)
Ignore me – I am supposed to be creating that file in the next command, rather than editing one that is already there.
Apologies!
You are missing dovecot-lmtpd when installing dovecot. Without it local mail delivery doesnt work and you will get the following error in maillog
conversation with mydomain.com[private/lmtp] timed out while receiving the initial server greeting
Thanks for noticing, we have now included the dovecot-lmtpd package.
All works, but when trying to login into Roundcube it returns ‘Connection to IMAP server failed’
Please check if you followed all the instructions correctly on steps 5 and 6. You can also check the error logs for more information about the issue you are facing.