Part 3: PostfixAdmin – Create Virtual Mailboxes on Ubuntu Mail Server

In previous articles, we discussed how to set up your own mail server on Ubuntu from scratch. In part 1 and part 2 of this tutorial series, we learned how to set up Postfix SMTP server and Dovecot IMAP server, but so far we can only have email addresses for users with local Unix account. This tutorial is going to show you how to create virtual mailboxes on Ubuntu mail server with PostfixAdmin, which is an open-source web-based interface to configure and manage a Postfix based email server for many domains and users.

With virtual mailboxes, we don’t need to create local Unix account for each email address. If you are going to set up a mail server for a company or organization, it’s always better to have an easy way to create virtual mailboxes in a web-based interface, which also allows users to change their passwords. That’s where PostfixAdmin comes in.

PostfixAdmin Features

  • manage mailboxes, virtual domains and aliases
  • vacation/out-of-office messages
  • alias domains (forwarding one domain to another with recipient validation)
  • users can manage their own mailbox (change alias, password and vacation message)
  • quota support for single mailboxes and total quota of a domain
  • display used quota
  • fetchmail integration: You can fetch emails from your original email address to your new email address.
  • command line client postfixadmin-cli for those who don’t want to click around in a web interface 😉

Note: Once you finish part 3, you can no longer use local Unix accounts as email addresses. You must create email addresses from the PostfixAdmin web interface.

Prerequisites

It’s required that you have followed part 1 and part 2 of this tutorial series before continuing reading this article. If you followed mail server tutorials on other websites, I recommend purging your configurations and start over with my tutorial series, so you are not going to be confused by different setup processes.

PostfixAdmin is written in PHP and requires a database (MySQL/MariaDB, PostgreSQL or SQLite). This article will use MariaDB database. You also need to run Apache or Nginx web server. So basically we are going to need a LAMP or LEMP stack.

If you prefer to use Apache web server, then set up a LAMP stack.

If you prefer to use Nginx web server, then set up a LEMP stack.

Once the above requirements are met, let’s install and configure PostfixAdmin.

Step 1: Install PostfixAdmin on Ubuntu Server

Log into your mail server and install PostfixAdmin from the default Ubuntu software repository.

sudo apt install postfixadmin

During the installation, you will be asked if you want dbconfig-common to configure the database. Choose Yes.

postfixadmin ubuntu 18.04

Then select the default database type: mysql.

postfixadmin mariadb mysql

Dbconfig-common will create the postfixadmin database and user. You need to set a password for this user. Note that the password should not contain the # character, or you might not be able to log in later.

postfixadmin database password

After PostfixAdmin is installed, you can log in to MySQL/MariaDB console with the following command. You will need to enter the password for the postfixadmin user.

mysql -u postfixadmin -p

And you can check what databases the user has permissions to access with the following command.

SHOW DATABASES;

Output:

+--------------------+
| Database           |
+--------------------+
| information_schema |
| postfixadmin       |
+--------------------+
2 rows in set (0.002 sec)

By default, the postfixadmin database contains no tables. You can log out of the MySQL/MariaDB console with the following command.

EXIT;

The installation will also create two configuration files: /etc/dbconfig-common/postfixadmin.conf and /etc/postfixadmin/dbconfig.inc.php, both of which contain the database access settings, including the database username and password. Note that if you use MariaDB instead of MySQL, you need to change the database type from mysql to mysqli in both of the two files.

The web files are installed under /usr/share/postfixadmin/ directory, which is owned by root. We need to give www-data user read, write and execute permissions on the Smarty template compile directory with the following command.

sudo setfacl -R -m u:www-data:rwx /usr/share/postfixadmin/templates_c/

Step 2: Create Apache Virtual Host or Nginx Config File for PostfixAdmin

Apache

If you use Apache web server, create a virtual host for PostfixAdmin.

sudo nano /etc/apache2/sites-available/postfixadmin.conf

Put the following text into the file. Replace postfixadmin.example.com with your real domain name and don’t forget to set DNS A record for it.

<VirtualHost *:80>
  ServerName postfixadmin.example.com
  DocumentRoot /usr/share/postfixadmin/

  ErrorLog ${APACHE_LOG_DIR}/postfixadmin_error.log
  CustomLog ${APACHE_LOG_DIR}/postfixadmin_access.log combined

  <Directory />
    Options FollowSymLinks
    AllowOverride All
  </Directory>

  <Directory /usr/share/postfixadmin/>
    Options FollowSymLinks MultiViews
    AllowOverride All
    Order allow,deny
    allow from all
  </Directory>

</VirtualHost>

Save and close the file. Then enable this virtual host with:

sudo a2ensite postfixadmin.conf

Reload Apache for the changes to take effect.

sudo systemctl reload apache2

Now you should be able to see the PostfixAdmin web-based install wizard at http://postfixadmin.example.com/setup.php.

Nginx

If you use Nginx web server, create a virtual host for PostfixAdmin.

sudo nano /etc/nginx/conf.d/postfixadmin.conf

Put the following text into the file. Replace postfixadmin.example.com with your real domain name and don’t forget to set DNS A record for it.

server {
   listen 80;
   server_name postfixadmin.example.com;

   root /usr/share/postfixadmin/;
   index index.php index.html;

   access_log /var/log/nginx/postfixadmin_access.log;
   error_log /var/log/nginx/postfixadmin_error.log;

   location / {
       try_files $uri $uri/ /index.php;
   }

   location ~ ^/(.+\.php)$ {
        try_files $uri =404;
        fastcgi_pass unix:/run/php/php7.2-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include /etc/nginx/fastcgi_params;
   }
}

Note: This tutorial is written for Ubuntu 18.04. If you are using Ubuntu 16.04, change php7.2-fpm to php7.0-fpm.

Save and close the file. Then test Nginx configuration.

sudo nginx -t

If the test is successful, reload Nginx for the changes to take effect.

sudo systemctl reload nginx

Now you should be able to see the PostfixAdmin web-based install wizard at http://postfixadmin.example.com/setup.php.

Step 3: Install Required and Recommended PHP Modules

Run the following command to install PHP modules required or recommended by PostfixAdmin.

sudo apt install php7.2-fpm php7.2-imap php7.2-mbstring php7.2-mysql php7.2-json php7.2-curl php7.2-zip php7.2-xml php7.2-bz2 php7.2-intl php7.2-gmp

The above command is for Ubuntu 18.04. Ubuntu 16.04 doesn’t have php7.2 in its repository, run the following command to install php7.0 modules on Ubuntu 16.04.

sudo apt install php7.0-fpm php7.0-imap php7.0-mbstring php7.0-mysql php7.0-json php7.0-curl php7.0-zip php7.0-xml php7.0-bz2 php7.0-intl php7.0-gmp

Then restart Apache. (If you use Nginx, you don’t need to restart Nginx.)

sudo systemctl restart apache2

Step 4: Enabling HTTPS

To encrypt the HTTP traffic, we can enable HTTPS by installing a free TLS certificate issued from Let’s Encrypt. Run the following command to install Let’s Encrypt client (certbot) on Ubuntu 18.04 server.

sudo apt install certbot

If you use Apache, install the Certbot Apache plugin.

sudo apt install python3-certbot-apache

And run this command to obtain and install TLS certificate.

sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d postfixadmin.example.com

If you use Nginx, then you also need to install the Certbot Nginx plugin.

sudo apt install python3-certbot-nginx

Next, run the following command to obtain and install TLS certificate.

sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d postfixadmin.example.com

Where

  • --nginx: Use the nginx plugin.
  • --apache: Use the Apache plugin.
  • --agree-tos: Agree to terms of service.
  • --redirect: Force HTTPS by 301 redirect.
  • --hsts: Add the Strict-Transport-Security header to every HTTP response. Forcing browser to always use TLS for the domain. Defends against SSL/TLS Stripping.
  • --staple-ocsp: Enables OCSP Stapling. A valid OCSP response is stapled to the certificate that the server offers during TLS.

The certificate should now be obtained and automatically installed, which is indicated by the message below.

postfixadmin ubuntu https

Step 5: Use Strong Password Scheme in PostfixAdmin and Dovecot

By default, PostfixAdmin and Dovecot use MD5-CRYPT, which is a weak password scheme. You can list available password schemes in Dovecot with the following command.

doveadm pw -l

Sample output:

MD5 MD5-CRYPT SHA SHA1 SHA256 SHA512 SMD5 SSHA SSHA256 SSHA512 PLAIN CLEAR CLEARTEXT PLAIN-TRUNC CRAM-MD5 SCRAM-SHA-1 HMAC-MD5 DIGEST-MD5 PLAIN-MD4 PLAIN-MD5 LDAP-MD5 LANMAN NTLM OTP SKEY RPA PBKDF2 CRYPT SHA256-CRYPT SHA512-CRYPT

To use stronger password schemes like Argon2, we need to upgrade Dovecot to v2.3. To check your Dovecot version, run

dovecot --version

Sample output:

2.2.33.2 (d6601f4ec)

We can install the latest version of Dovecot on Ubuntu 18.04 from the official upstream repository. (If you are using Ubuntu 19.10, you already have Dovecot 2.3.)

Create a repository file for Dovecot.

sudo nano /etc/apt/sources.list.d/dovecot.list

Add the following line in the file.

deb [arch=amd64] https://repo.dovecot.org/ce-2.3-latest/ubuntu/bionic bionic main

Save and close the file. Because this repository is using https, so we need to install the apt-transport-https package.

sudo apt install apt-transport-https

Then we need to import the Dovecot PGP key with the following two commands, so that packages downloaded from this repository can be verified.

curl https://repo.dovecot.org/DOVECOT-REPO-GPG | gpg --import
gpg --export ED409DA1 | sudo tee /etc/apt/trusted.gpg.d/dovecot.gpg

Now update repository and upgrade existing Dovecot packages.

sudo apt update
sudo apt upgrade

If you see a question like below in the upgrade process, it’s always a good idea to keep the local version and examine what needs to change later.

dovecot 2.3 argon password scheme

Once the upgrade is finished, check Dovecot version again.

dovecot --version

Output:

2.3.9.2 (cf2918cac)

list available password schemes in Dovecot with the following command.

sudo doveadm pw -l

Sample output:

SHA1 SSHA512 BLF-CRYPT PLAIN HMAC-MD5 OTP SHA512 SHA RPA DES-CRYPT CRYPT SSHA MD5-CRYPT SKEY PLAIN-MD4 PLAIN-MD5 SCRAM-SHA-1 LANMAN SHA512-CRYPT CLEAR CLEARTEXT ARGON2I ARGON2ID SSHA256 NTLM MD5 PBKDF2 SHA256 CRAM-MD5 PLAIN-TRUNC SHA256-CRYPT SMD5 DIGEST-MD5 LDAP-MD5

Now we have Argon2. Edit the PostfixAdmin configuration file.

sudo nano /etc/postfixadmin/config.inc.php

Find the following line.

$CONF['encrypt'] = 'md5crypt';

Change it to the following so that PostfixAdmin will use Dovecot’s ARGON2I password scheme.

$CONF['encrypt'] = 'dovecot:ARGON2I';

Then find the following line.

$CONF['dovecotpw'] = "/usr/bin/doveadm pw";

We need to add the number of rounds like 5 rounds. The minimum for ARGON2 is 3.

$CONF['dovecotpw'] = "/usr/bin/doveadm pw -r 5";

Save and close the file. We will configure password scheme for Dovecot in step 9.

Step 6: Finish the Installation in Web Browser

Go to postfixadmin.example.com/setup.php to run the web-based setup wizard. First, it will check if all dependencies are installed.

postfix host multiple domains

If you see the following error,

Invalid query: Specified key was too long; max key length is 1000 bytes

Then you need to log in to MySQL/MariaDB database server as root from command line,

sudo mysql -u root

and change the default collation from utf8mb4_general_ci to utf8_general_ci.

MariaDB [(none)]> alter database postfixadmin collate ='utf8_general_ci';

Exit MySQL/MariaDB console and reload the setup.php page. Once all requirements are satisfied, you can create a setup password for PostfixAdmin.

postfixadmin virtual domain

After creating the password hash, you need to open the /etc/postfixadmin/config.inc.php file to update the password hash. Replace changeme with your own password hash.

$CONF['setup_password'] = 'changeme';

Next, create the admin account.

postfixadmin ubuntu install

After that, you can log into PostfixAdmin at postfixadmin.example.com/login.php.

postfixadmin virtual mailbox domains

Step 7: Checking Tables in the Database

The PostfixAdmin setup process populates the postfixadmin database with some default tables. It’s helpful for us to know the names and structure of the tables. Log in to MySQL/MariaDB console.

sudo mysql -u root

Select the postfixadmin database.

USE postfixadmin;

List all tables in this database.

SHOW TABLES;

Output:

+------------------------+
| Tables_in_postfixadmin |
+------------------------+
| admin                  |
| alias                  |
| alias_domain           |
| config                 |
| domain                 |
| domain_admins          |
| fetchmail              |
| log                    |
| mailbox                |
| quota                  |
| quota2                 |
| vacation               |
| vacation_notification  |
+------------------------+
13 rows in set (0.001 sec)

The 3 most important tables are:

  • domain: contains information on the domains that are using your mail server to send and receive email.
  • mailbox: contains information on every email address, including hashed password and the location of mail files.
  • alias: contains the alias of each email address.

If you are interested, you can check what columns each table contains. For example, the following command will show us the columns in the domain table.

DESCRIBE domain;

Output:

+-------------+--------------+------+-----+---------------------+-------+
| Field       | Type         | Null | Key | Default             | Extra |
+-------------+--------------+------+-----+---------------------+-------+
| domain      | varchar(255) | NO   | PRI | NULL                |       |
| description | varchar(255) | NO   |     | NULL                |       |
| aliases     | int(10)      | NO   |     | 0                   |       |
| mailboxes   | int(10)      | NO   |     | 0                   |       |
| maxquota    | bigint(20)   | NO   |     | 0                   |       |
| quota       | bigint(20)   | NO   |     | 0                   |       |
| transport   | varchar(255) | NO   |     | NULL                |       |
| backupmx    | tinyint(1)   | NO   |     | 0                   |       |
| created     | datetime     | NO   |     | 2000-01-01 00:00:00 |       |
| modified    | datetime     | NO   |     | 2000-01-01 00:00:00 |       |
| active      | tinyint(1)   | NO   |     | 1                   |       |
+-------------+--------------+------+-----+---------------------+-------+

Log out of MySQL/MariaDB console.

EXIT;

Step 8: Configure Postfix to Use MySQL/MariaDB Database

By default, Postfix delivers emails only to users with a local Unix account. To make it deliver emails to virtual users whose information is stored in the database, we need to configure Postfix to use virtual mailbox domains.

First, we need to add MySQL map support for Postfix by installing the postfix-mysql package.

sudo apt install postfix-mysql

Then edit the Postfix main configuration file.

sudo nano /etc/postfix/main.cf

Add the following lines at the end of this file.

virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
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
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

Where:

  • virtual_mailbox_domains points to a file that will tell Postfix how to look up domain information from the database.
  • virtual_mailbox_maps points to files that will tell Postfix how to look up email addresses from the database.
  • virtual_alias_maps points to files that will tell Postfix how to look up aliases from the database.

We want to use dovecot to deliver incoming emails to the virtual users’ message store, so add the following line.

virtual_transport = lmtp:unix:private/dovecot-lmtp

Save and close the file. Next, we need to create the .cf files one by one. Create the sql directory.

sudo mkdir /etc/postfix/sql/

Create the mysql_virtual_domains_maps.cf file.

sudo nano /etc/postfix/sql/mysql_virtual_domains_maps.cf

Add the following content. Replace password with the postfixadmin password you set in Step 1.

user = postfixadmin
password = password
hosts = localhost
dbname = postfixadmin
query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'
#query = SELECT domain FROM domain WHERE domain='%s'
#optional query to use when relaying for backup MX
#query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1'
#expansion_limit = 100

Create the mysql_virtual_mailbox_maps.cf file.

sudo nano /etc/postfix/sql/mysql_virtual_mailbox_maps.cf

Add the following content.

user = postfixadmin
password = password
hosts = localhost
dbname = postfixadmin
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
#expansion_limit = 100

Create the mysql_virtual_alias_domain_mailbox_maps.cf file.

sudo nano /etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf

Add the following content.

user = postfixadmin
password = password
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'

Create the mysql_virtual_alias_maps.cf file.

sudo nano /etc/postfix/sql/mysql_virtual_alias_maps.cf

Add the following content.

user = postfixadmin
password = password
hosts = localhost
dbname = postfixadmin
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
#expansion_limit = 100

Create the mysql_virtual_alias_domain_maps.cf file.

sudo nano /etc/postfix/sql/mysql_virtual_alias_domain_maps.cf

Add the following content.

user = postfixadmin
password = password
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'

Create the mysql_virtual_alias_domain_catchall_maps file.

sudo nano /etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf

Add the following content.

# handles catch-all settings of target-domain
user = postfixadmin
password = password
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'

Since the database passwords are stored in plain text so they should be readable only by user postfix and root, which is done by executing the following two commands.

sudo chmod 0640 /etc/postfix/sql/*
sudo setfacl -R -m u:postfix:rx /etc/postfix/sql/

Now let’s open the Postfix main configuration file again.

sudo nano /etc/postfix/main.cf

Find the mydestination parameter, which contains a list of domain names that will receive emails delivered to local Unix accounts. Since we are going to use virtual mailbox, so we need to remove the apex domain name from the list. My apex domain name is linuxbabe.com, so I removed it from the mydestination parameter.

mydestination = $myhostname, mail.linuxbabe.com, localhost.linuxbabe.com, localhost

Then add the following lines at the end of this file.

virtual_mailbox_base = /var/vmail
virtual_minimum_uid = 2000
virtual_uid_maps = static:2000
virtual_gid_maps = static:2000

The first line defines the base location of mail files. The remaining 3 lines define which user ID and group ID Postfix will use when delivering incoming emails to the mailbox. We use the user ID 2000 and group ID 2000.

Save and close the file. Restart Postfix for the changes to take effect.

sudo systemctl restart postfix

Next, we need to create a user named vmail with ID 2000 and a group with ID 2000.

sudo adduser vmail --uid 2000 --disabled-login --disabled-password

Create the mail base location.

sudo mkdir /var/vmail/

Make vmail as the owner.

sudo chown vmail:vmail /var/vmail/ -R

Step 9: Configure Dovecot to Use MySQL/MariaDB Database

We also need to configure the Dovecot IMAP server to query user information from the database. First, run the following command to add MySQL support for Dovecot.

sudo apt install dovecot-mysql

Then edit the 10-mail.conf file.

sudo nano /etc/dovecot/conf.d/10-mail.conf

In part 2, we used the default mail_location.

mail_location = mbox:~/mail:INBOX=/var/mail/%u

Since we are using virtual mailbox domain now, we need to change the mail_location to:

mail_location = maildir:/var/vmail/%d/%n

Edit the 10-auth.conf file.

sudo nano /etc/dovecot/conf.d/10-auth.conf

In part 2, we used the following value for auth_username_format.

auth_username_format = %n

The %n would drop away the domain if it was given. Because in part 2 we were using local Unix account for the username of every email address, we must use %n to drop away the domain, so users were able to login with the full email address.

Now we are using virtual mailbox domains, which means the username of every email address includes the domain part, so we need to change the auth_username_format as follows. %u won’t drop away the domain. This allows users to login with the full email address.

auth_username_format = %u

Uncomment the following line so Dovecot can query user information from the database.

!include auth-sql.conf.ext

It can be helpful to add the following two lines in this file to debug login issues. The login errors would be logged into /var/log/mail.log file. (Once users can login without problems, you can comment out the following two lines.)

auth_debug = yes
auth_debug_passwords = yes

Edit the dovecot-sql.conf.ext file.

sudo nano /etc/dovecot/dovecot-sql.conf.ext

Here is the content that you should have. Replace password with the postfixadmin password you set in Step 1.

driver = mysql

connect = host=localhost dbname=postfixadmin user=postfixadmin password=password

default_pass_scheme = ARGON2I

password_query = SELECT username AS user,password FROM mailbox WHERE username = '%u' AND active='1'

user_query = SELECT maildir, 2000 AS uid, 2000 AS gid FROM mailbox WHERE username = '%u' AND active='1'

iterate_query = SELECT username AS user FROM mailbox

Restart Dovecot.

sudo systemctl restart dovecot

When a user tries to log in, Dovecot would use the Argon2 algorithm to generate a password hash from the password entered by the user, then compare it with the password hash stored in the database.

Step 10: Add Domain and Mailboxes in PostfixAdmin

Log in to PostfixAdmin web interface as the admin. Click the Domain List tab and select New Domain to add a domain. You can choose how many aliases and mailboxes are allowed for this domain.

postfixadmin add domain

Then click Virtual List tab and select Add Mailbox to add a new email address for your domain.

postfixadmin add mailbox

Next, you can open your desktop email client such as Mozilla Thunderbird and add a mail account.

  • In the incoming server section, select IMAP protocol, enter mail.your-domain.com as the server name, choose port 143 and STARTTLS. Choose normal password as the authentication method.
  • In the outgoing section, select SMTP protocol, enter mail.your-domain.com as the server name, choose port 587 and STARTTLS. Choose normal password as the authentication method.

modoboa-mail-server-desktop-mail-client-configuration-automx

You should now be able to connect to your own email server and also send and receive emails with your desktop email client!

Change User Password in PostfixAdmin

Users can log into PostfixAdmin at https://postfixadmin.example.com/users/login.php, then change their passwords.

Troubleshooting

It seems there’s a bug in PostfixAdmin 3.0.2, which always redirect users to the login page after clicking any link in the web interface.

To fix, edit the common.php file in the PostfixAdmin web root directory and comment out the following lines. (Add // at the beginning of each line.) The latest version of PostfixAdmin doesn’t have these lines in common.php file.

if (defined('POSTFIXADMIN_LOGOUT')) {
        session_unset();
        session_destroy();
        session_start();
}

Save and close the file. You should be able to use PostfixAdmin.

Next Step

I hope this tutorial helped you install and use PostfixAdmin on Ubuntu to create virtual mailboxes. In part 4, I will show you how to set up SPF and DKIM with Postfix to improve email deliverability and in a future tutorial, I’m going to show you how to host multiple domains with PostfixAdmin. As always, if you found this post useful,  subscribe to our free newsletter to get more tips and tricks. Take care 🙂

Rate this tutorial
[Total: 5 Average: 5]

131 Responses to “Part 3: PostfixAdmin – Create Virtual Mailboxes on Ubuntu Mail Server

  • Hi, great tutorials! I followed your parts and everything worked so far, but when I try to login to rainloop (for the first time), I briefly see the loading screen before being redirected to the login page. I looked into /var/log/mail.log and found an error, that dovecot is missing the permission to create the necessary sub directories in /var/vmail/:

    Dec 30 11:06:05 my-domain dovecot: imap([email protected]): Namespace '': mkdir(/var/vmail/my-domain.com/test) failed: Permission denied (euid=1001(lennart) egid=1001(lennart) missing +w perm: /var/vmail, dir owned by 2000:2000 mode=0755) in=0 out=343
    

    Do I have to adjust some settings so that dovecot uses the vmail user to create the directories?

    Thanks for your help.

    • Looks like you didn’t remove your apex domain name from the mydestination parameter, so Postfix and Dovecot think your emails belong to a canonical domain, not a virtual domain managed by PostfixAdmin.

      • Thanks for the fast reply. The mydestination parameter looks like this:

        mydestination = mail.my-domain.com, localhost.my-domain.com, localhost
        

        Looks fine for me. This is only specified in /etc/postfix/main.cf right?

    • Oops, there’s a typo in this article. In the /etc/dovecot/dovecot-sql.conf.ext file, the user_query should be

      user_query = SELECT maildir, 2000 AS uid, 2000 AS gid FROM mailbox WHERE username = '%u' AND active='1'

      Your mydestination parameter is correct.

      • Yeah, that makes sense. Nice catch! Everything works as expected now.

  • Hi,
    Dovecot uses MD5-CRYPT for passwords when a user try to login with postfixadmin.
    Is possible to use a more secure encryption mechanism for that login?

    Which one is the recommended in production?

  • Constantinos
    3 months ago

    Thank you very very much for doing all this work!
    What I got wrong and might help others is the necessary password needed in files of Step 7 and Step 8. The password you have to use is the one from Step 1 not any of those in Step 5. I made this mistake and I wasn’t able to connect to any of my emails from thunderbird.

  • Dann-Emil
    3 months ago

    Hi!

    I can’t get over this command:
    sudo setfacl -R -m u:www-data:rwx /usr/share/postfixadmin/templates_c/
    Error during run is “a:rwx /usr/share/postfixadmin/templates_c/
    s”

    Help is highly appreciated. Thank you!

  • Hey, i got some problems, im goin step by step from your “how to”, and now i get one problem with Roundcube.
    I can send emails out, but i don’t recive any emails.
    They are not creating in /var/vmail/DOMAIN/USER/cur and anywhere…

    /var/log/mail.log looks like:

    Jan 15 18:21:20 HOST postfix/smtpd[28394]: connect from mail-ed1-f44.google.com[209.85.208.44]
    Jan 15 18:21:20 HOST postfix/smtpd[28394]: Anonymous TLS connection established from mail-ed1-f44.google.com[209.85.208.44]: TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)
    Jan 15 18:21:20 HOST postfix/smtpd[28394]: D2F7C2E3002: client=mail-ed1-f44.google.com[209.85.208.44]
    Jan 15 18:21:20 HOST postfix/cleanup[28399]: D2F7C2E3002: message-id=
    Jan 15 18:21:20 HOST postfix/qmgr[28381]: D2F7C2E3002: from=, size=3616, nrcpt=1 (queue active)
    Jan 15 18:21:20 HOST postfix/lmtp[28400]: D2F7C2E3002: to=, relay=none, delay=0.08, delays=0.06/0.02/0/0, dsn=4.4.1, status=deferred (connect to mail.xxx.com[private/dovecot-lmtp]: No such file or directory)
    Jan 15 18:21:20 HOST postfix/smtpd[28394]: disconnect from mail-ed1-f44.google.com[209.85.208.44] ehlo=2 starttls=1 mail=1 rcpt=1 data=1 quit=1 commands=7

    I see mails still coming to /var/mail/* .

    Any ideas what i can mess?

    • From the mail log, I can see that Postfix can’t connect to dovecot-lmtp. Make sure dovecot-lmtpd is installed.

      sudo apt install dovecot-lmtpd

      Edit the Dovecot main configuration file.

      sudo nano /etc/dovecot/dovecot.conf

      Add lmtp to the supported protocols.

      protocols = imap lmtp

      Save and close the file. Then edit the Dovecot 10-master.conf file.

      sudo nano /etc/dovecot/conf.d/10-master.conf

      Change the lmtp service definition to the following.

      service lmtp {
       unix_listener /var/spool/postfix/private/dovecot-lmtp {
         group = postfix
         mode = 0600
         user = postfix
        }
      }

      Restart Postfix and Dovecot.

      sudo systemctl restart posfix dovecot

      PS: The above process has been explained in Part 2 of this tutorial series.

      • My fault – of course i miss this section.

        Thank you – greate job with that tutorial!

  • Hi, clear instructions in your tutorial. My problem is that the installation process doesn’t present the screens to choose and create the database. But even if that’s not an immediate problem, when i navigate to 192.160.0.11/postfix admin I get tge nessage:
    “The Postfix Admin directory layout changed.

    “Please update your webserver config so that the DocumentRoot or Alias points to the directory “public”.”

    There’s no apache2 sites available created during the installation so I have no idea where to edit the virtual host postfixadmin.conf.

    Do I have to create it and also the database entries?
    Thanks.

    • In this Prerequisites section, I said you should set up a LAMP stack or LEMP stack before installing PostfixAdmin. Then if you install PostfixAdmin from the default Ubuntu repository, it will present the screen to configure database. If it doesn’t show, then run the following command to reconfigure.

      sudo dpkg-reconfigure postfixadmin

      A standard Apache installation on Ubuntu will have the /etc/apache2/sites-available/ directory.

      You should use a domain name, instead of an IP address, to set up a mail server, or you won’t have an email address on your own domain.

      This article shows configuring Apache and Nginx to serve the PostfixAdmin web interface from a sub-domain, not from a sub-directory.

      • Thanks for your reply Guoan.

        My problem isnt with my server setup as far as I can see but it could well be. I’m running Apache2 2.4x, php 7.3, Mariadb 10.2 on Ubuntu 19.10.x and installed PostfixAdmin with apt-get from the repository. I uninstalled and reinstalled and it did not create some files and directories which I’ve manually created. I also had to create the virtual host file and enable the postfixadmin virtual host.

        I created a virtual host and found that setting the document root to /usr/share/postfixadmin/public without the trailing slash was a big help in accessing setup.php in the browser.

        It just seems to be a hit or miss installer because I see through my searches that many people have encountered the same or similar problems.

        I finally could access /setup.php and it reported a missing database connection because I created two empty php config files where the installation was looking for them. Here’s the output to the browser from postfixadmin.site.com/setup.php after I created the template_c directory and the empty php config files:

        "Postfix Admin Setup Checker
        
        Running software: 
        
        PHP version 7.3.11-0ubuntu0.19.10.2
        
        Apache/2.4.41 (Ubuntu)
        
        Checking for dependencies: 
        
        Magic Quotes: Disabled - OK
        
        Depends on: presence config.inc.php - OK
        
        Checking $CONF['configured'] - OK 
        
        Warning: config.local.php - NOT FOUND
        
        It's Recommended to store your own settings in config.local.php instead of editing config.inc.php
        Create the file, and edit as appropriate (e.g. select database type etc)
        
        Depends on: MySQL 4.1 - OK 
        (change the database_type to 'mysqli' in config.local.php if you want to use MySQL) 
        
        Error: Can't connect to database
        Please edit the $CONF['database_*'] parameters in config.local.php. 
        
        DEBUG INFORMATION:
        Invalid $CONF['database_type']! Please fix your config.inc.php! 
        
        Depends on: session - OK
        
        Depends on: pcre - OK
        
        Depends on: multibyte string - OK
        
        Depends on: IMAP functions - OK
        
        Please fix the errors listed above."

        If I could see two example files for the database, I’d create the db and enter the relevant info in the files.

        Meantime, I’ll try your recommendation on running dpkg-reconfigure and report the outcome.

        Mark

        • Result of running dpkg-reconfigure:

          apache2_invoke postfixadmin: already enabled
    • Your situation is a bit strange. I did a test on Ubuntu 19.10 and it worked like a charm.

      If the database configure wizard didn’t show up, I think your system is missing the dbconfig-common or dbconfig-mysql package.

      sudo apt install dbconfig-common dbconfig-mysql

      Then you can purge PostfixAdmin and reinstall it.

      sudo apt purge postfixadmin
      sudo apt install postfixadmin

      If the database configure wizard still won’t show up, you need to download PostfixAdmin from upstream and manually configure the database. I recently wrote a similar PostfixAdmin article for CentOS, where it shows how to install manually install PostfixAdmin and configure the database. Follow step 1 to step 4 in that article, replace the directory path where appropriate.

      • You may be right about the effect of dbconfig-common on the process. I do have it installed but when I opened Synaptic I also noticed that something called dbconfig-no-thanks is also installed and the blurb says “If a package relies on the dbconfig-common framework for database setup and maintenance, installing dbconfig-no-thanks instead of one of dbconfig’s database-specific packages will block this function. It is intended for cases where the system administrator desires or requires full control of the database or where dbconfig-common makes bad choices, and typically leaves the depending packages non-functional until manually configured.”

        I don’t know if that was installed as a dependency of some other package but it might be the problem.

        I followed another article and did a ,ot of manual creation of directories and files and PostfixAdmin finally worked. Whether all features are available I don’t know because it seems to be very limited in what it does.

        Thanks very much for all your help.

    • My system doesn’t have dbconfig-no-thanks package. It’s not pre-installed on Ubuntu.

      Well, Postfixadmin is for managing virtual mailboxes from a web interface. If the mail server is used by yourself only, you might not find it very useful.

  • Ken Wright
    2 months ago

    I’ve followed your instructions, but for some reason when I try to run postfixadmin.mydomain.com I get a 404 status. I’ve set up the A record, but I’m still getting a 404.

    Obviously I’ve made a horrible mistake.

    Any suggestions?

    • Can you visit postfixadmin.yourdomain.com/setup.php?

      • Ken Wright
        2 months ago

        No. That gets me 404 as well.

        • Ken Wright
          2 months ago

          Well, I finally got postfixadmin.mydomain.com/setup.php to open, and after a few tries I finally got the admin account set up. I proceeded to login.php, but whenever I try to click a link it takes me back to the admin login screen. I’m thinking this isn’t the expected behavior. Any ideas?

    • This seems to be a bug in PostfixAdmin 3.0.2.

      To fix, edit the common.php file in the PostfixAdmin web root directory and comment out the following lines. (Add // at the beginning of each line.) The lastest version of PostfixAdmin doesn’t have these lines in common.php file.

      if (defined('POSTFIXADMIN_LOGOUT')) {
              session_unset();
              session_destroy();
              session_start();
           }
      

      Save and close the file and you should be able to use PostfixAdmin.

      • Ken Wright
        2 months ago

        It worked! Thanks, but now I seem to have a Thunderbird problem. It’s just not able to login to the server.

    • When you login from Thunderbird, you can check if there’s any error in the mail log (/var/log/mail.log).

      • Ken Wright
        2 months ago

        Here’s what I see most recently in the mail log:

        Feb 2 02:07:18 grace postgrey[1411]: Process Backgrounded
        Feb 2 02:07:18 grace postgrey[1411]: 2020/02/02-02:07:18 postgrey (type Net::Server::Multiplex) starting! pid(1411)
        Feb 2 02:07:18 grace postgrey[1411]: Resolved [localhost]:10023 to [127.0.0.1]:10023, IPv4
        Feb 2 02:07:18 grace postgrey[1411]: Binding to TCP port 10023 on host 127.0.0.1 with IPv4
        Feb 2 02:07:18 grace postgrey[1411]: Setting gid to “126 126”
        Feb 2 02:07:18 grace postgrey[1411]: Setting uid to “123”
        Feb 2 02:07:20 grace opendkim[1651]: OpenDKIM Filter v2.11.0 starting (args: -x /etc/opendkim.conf)

        I checked the log immediately after trying to log in from Thunderbird, which is still giving me the following error:

        Unable to log in at server. Probably wrong configuration, username or password.

        I hope this helps!

    • The above log messages is not related to login issue.

      You should add the following two lines in /etc/dovecot/conf.d/10-auth.conf file to debug login issues.

      auth_debug = yes
      auth_debug_passwords = yes

      Restart Dovecot and login again. Then you should be able to see dovecot errors in the /var/log/mail.log file.

      • Ken Wright
        2 months ago

        After I restarted Dovecot, I found this error in the log:

        Feb 2 06:40:53 grace dovecot: auth-worker(6367): Warning: mysql: Query failed, retrying: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‘=1’ at line 1

        Clearly, I’ve got a typo in an SQL table; the question is which one? I’ve looked at all seven in /etc/postfix/sql/ but they’re all good. When I look at /etc/dovecot/conf.d I don’t see anything that says sql or auth-worker, so I’m kind of stumped. Can you point me in the right direction?

    • Login is handled by Dovecot, not Postfix. You should look at your SQL syntax in the /etc/dovecot/dovecot-sql.conf.ext file. The content of this file should be:

      driver = mysql
      
      connect = host=localhost dbname=postfixadmin user=postfixadmin password=password
      
      default_pass_scheme = ARGON2I
      
      password_query = SELECT username AS user,password FROM mailbox WHERE username = '%u' AND active='1'
      
      user_query = SELECT maildir, 2000 AS uid, 2000 AS gid FROM mailbox WHERE username = '%u' AND active='1'
      
      iterate_query = SELECT username AS user FROM mailbox
      
      • Ken Wright
        2 months ago

        This is turning into quite a bughunt! Now the log says it can’t find the “imap-sieve” plugin in /usr/share/dovecot/modules.

    • Run the following command to install sieve.

      sudo apt install dovecot-sieve dovecot-managesieved
      
      • Ken Wright
        2 months ago

        Sieve is already installed, but I made a typo in /etc/dovecot/conf.d/20-imap.conf; I typed “imap-sieve” instead of “imap_sieve” so it kinda choked.

        So I’m now able to log into the server, but I can’t send email. I get an error message saying the SMTP server is either unavailable or is refusing SMTP connections. I’ve checked the SMTP server settings and they match what you’ve got in the tutorial.

    • Have you enabled the submission service in Postfix? Is port 587 open on your server? You can list running services and the associated ports on your server with:

      sudo netstat -lnpt
      • Ken Wright
        2 months ago

        I’ve opened port 587. How do I enable the submission service?

    • If ported 587 is listed in the output of sudo netstat -lnpt, then you have enabled the submission service in Postfix. Steps of enabling submission service is described in part 2.

    • The sudo netstat -lnpt command list running services and the associated port on your server.

      Go to part 2 to enable submission service.

      • Ken Wright
        2 months ago

        Well, after a good night’s sleep, I went back through Part 2 and found a few mistakes I made. Typo’s and the like, but significant all the same. Anyway, I fixed the errors, restarted Postfix, and checked netstat again, and now port 587 is open.

        I tried sending an email from the new server, but this time I got an error message saying the connection timed out. I’m sure I’ve made another mistake, but I don’t know where!

    • Is the error message like this?

      connect to gmail-smtp-in.l.google.com[74.125.206.27]:25: Connection timed out

      This indicates that port 25 (outbound) is blocked by your ISP or hosting provider, so you can’t send email directly to the recipient. You need to set up SMTP relay to bypass port 25 blocking.

      • Ken Wright
        2 months ago

        No, it’s just a timeout message. Here it is:

        Sending of the message failed.
        The message could not be sent because the connection to Outgoing server (SMTP) grace.koalatyworks.com timed out. Try again.
    • Always check the error messages in the /var/log/mail.log file. If you don’t see any error message in the /var/log/mail.log file. This could mean that port 587 is still closed.

      Run the following command to open port 587 in firewall.

      sudo ufw allow 587/tcp
      • Ken Wright
        2 months ago

        Port 587’s open in the firewall. Tried sending another message, and the mail log shows the following:

        Feb  3 04:40:22 grace postfix/tlsmgr[2876]: fatal: do not use the same TLS cache file btree:/var/lib/postfix/smtpd_scache for smtpd and smtp
        Feb  3 04:40:23 grace postfix/master[30266]: warning: process /usr/lib/postfix/sbin/tlsmgr pid 2876 exit status 1
        Feb  3 04:40:23 grace postfix/master[30266]: warning: /usr/lib/postfix/sbin/tlsmgr: bad command startup -- throttling

        Which file should I check? /etc/postfix/main.cf or /etc/postfix/master.cf?

    • In the /etc/postfix/main.cf file, find the following two lines.

      smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
      
      smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

      This first parameter is the for the smtpd daemon, the second paramter is for the smtp client. Make sure they use different file names.

      • Ken Wright
        2 months ago

        Fixed that! Now the problem seems to be I’ve neglected to include mail.mydomain.com in my LetsEncrypt certificate. Is there a way to expand the certificate, or do I need to trash it and get a new one?

    • You can expand the certificate to include more domain name. First, edit the Nginx virtual host for grace.koalatyworks.com. Add a new hostname in the server_name directive.

      server_name grace.koalatyworks.com mail.koalatyworks.com;

      If there are two server_name directives, you need to change both of them.

      Reload nginx, then run the following command to obtain a certificate with two names on it.

      sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d grace.koalatyworks.com,mail.koalatyworks.com --cert-name grace.koalatyworks.com

      If the certificate is successfully obtained, restart Postfix and dovecot in order to pick up the new certificate.

      sudo systemctl restart postfix dovecot
      • Ken Wright
        2 months ago

        I tried this, and it wants to take koalatyworks.com, www.koalatyworks.com, postfixadmin.koalatyworks.com, and nextcloud.koalatyworks.com off the certificate. I really don’t want to lose those!

    • Then why not create a dedicated virtual host for mail.koalatyworks.com, and obtain a separate certificate?

    • By the way, your domain koalatyworks.com doesn’t have MX record. You should create MX record as described in part 1.

      • Ken Wright
        2 months ago

        Okay, I set the MX record and expanded my LetsEncrypt certificate to include grace.koalatyworks.com, but now I get this when I try to send an email:

        An error occurred while sending mail. The mail server responded:
        451 4.3.5 Server configuration error.

        I think I see the light at the end of the tunnel, but I hope it’s not an oncoming freight train!

    • Always check the /var/log/mail.log file.

      • Ken Wright
        2 months ago

        Here it is, but I don’t see any obvious error messages. If there’s an unobvious one, please show me what to look for.

        Feb  4 03:54:00 grace dovecot: imap([email protected]): Logged out in=106 out=577
        Feb  4 03:55:48 grace dovecot: auth: Debug: auth client connected (pid=2161)
        Feb  4 03:55:48 grace dovecot: auth: Debug: client in: AUTH#0111#011PLAIN#011service=imap#011secured#011session=4QniA7idxMvAqCwB#011lip=192.168.44.10#011rip=192.168.44.1#011lport=993#011rport=52164#011local_name=grace.koalatyworks.com
        Feb  4 03:55:48 grace dovecot: auth: Debug: client passdb out: CONT#0111
        Feb  4 03:55:48 grace dovecot: auth: Debug: client in: CONT#0111#011AHdpemFyZEBrb2FsYXR5d29ya3MuY29tAEIzY2NAYjAw (previous base64 data may contain sensitive data)
        Feb  4 03:55:48 grace dovecot: auth-worker(2163): Debug: Loading modules from directory: /usr/lib/dovecot/modules/auth
        Feb  4 03:55:48 grace dovecot: auth-worker(2163): Debug: Module loaded: /usr/lib/dovecot/modules/auth/lib20_auth_var_expand_crypt.so
        Feb  4 03:55:48 grace dovecot: auth-worker(2163): Debug: Module loaded: /usr/lib/dovecot/modules/auth/libdriver_mysql.so
        Feb  4 03:55:48 grace dovecot: auth-worker(2163): Debug: sql([email protected],192.168.44.1,): query: SELECT username AS user,password FROM mailbox WHERE username = '[email protected]' AND active='1'
        Feb  4 03:55:48 grace dovecot: auth: Debug: client passdb out: OK#0111#[email protected]
        Feb  4 03:55:48 grace dovecot: auth: Debug: master in: REQUEST#0113663724545#0112161#0111#01133f4421b5ab2716410d57f715e60ab09#011session_pid=2164#011request_auth_token
        Feb  4 03:55:48 grace dovecot: auth-worker(2163): Debug: sql([email protected],192.168.44.1,): SELECT maildir, 5000 AS uid, 5000 AS gid FROM mailbox WHERE username ='[email protected]' AND active = '1'
        Feb  4 03:55:48 grace dovecot: auth: Debug: master userdb out: USER#0113663724545#[email protected]#011maildir=koalatyworks.com/wizard/#011uid=5000#011gid=5000#011auth_token=7c1c12c49d02914d86d75de7f1151396174b8d4c
        Feb  4 03:55:48 grace dovecot: imap-login: Login: user=, method=PLAIN, rip=192.168.44.1, lip=192.168.44.10, mpid=2164, TLS, session=

        Does this help?

    • No. This is Dovecot log. You should look for Postfix log in the file. Try to send an email and look for any error message.

      • Ken Wright
        2 months ago

        I tried sending another email but nothing new showed up in the mail log. The only error message I see is the one I sent you earlier.

    • If you followed my tutorial series in the proper order, the situation would have been much better.

      I suggest reading the articles from part 1 to part 3 and compare the configurations.

      • Ken Wright
        2 months ago

        It’s working now!

        I rechecked /etc/postfix/master.cf and found I had put a period in one of the recipient restrictions instead of a comma. I fixed the typo, restarted Postfix, and now it’s working.

        Your tutorial series is DA BOMB! Thanks for the effort, and thanks for all the help you’ve given me the last few nights!

  • Ken Wright
    2 months ago

    Is the /usr/share/postfixadmin/templates_c/ directory supposed to be empty?

  • Hey great series so far! I’ve completed this section but I’m having trouble with a few of the address of that I’ve added. When I try to login via IMAP I get an unknown user error because it looks like its not passing the @domain. I can login via the postfixadmin user interface and change the password of the mail box. If I changed the devcot sql file to use local_part instead of username I could login. But I can’t send email from outside to the mail box so I’m sure I missed something…

    • Can you run the following command and show the output here?

      doveconf auth_username_format
      • Hey! I ran into some issues as well. Authentication with Outlook for Android does not work for me. By running this command I got the following warning:

        doveconf: Warning: please set ssl_dh= /etc/dovecot/dh.pem

        Do you have any idea how this could be the cause of my problem?

        • Edit SSL/TLS config file.

          sudo nano /etc/dovecot/conf.d/10-ssl.conf

          Set DH parameters.

          ssl_dh=</etc/dovecot/dh.pem

          Save and close the file. Then generate the DH parameter.

          dd if=/var/lib/dovecot/ssl-parameters.dat bs=1 skip=88 | openssl dhparam -inform der | sudo tee /etc/dovecot/dh.pem

          Then restart Dovecot.

          sudo systemctl restart dovecot
  • Hi! I followed the steps but when I try to go to https://postfixadmin.mydomain.com/setup.php it gives me the following error: File not found.

    do you know how to fix this?

    Much appreciated! and awesome tutorials 🙂

    • Any idea how to fix the error “File not found” when going to postfixadmin.mydomain.com/setup.php?

    • Perhaps you can try removing the trailing slash of document root in the Apache configuration file.

      From this:

      /usr/share/postfixadmin/

      To this:

      /usr/share/postfixadmin
  • Feb  2 16:02:13 mail postfix/smtpd[1358]: connect from unknown[92.118.38.40]
    Feb  2 16:02:16 mail postfix/smtpd[1358]: disconnect from unknown[92.118.38.40] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
    Feb  2 16:03:08 mail postfix/smtpd[1358]: warning: hostname ip-38-40.ZervDNS does not resolve to address 92.118.38.40: Name or service not known
    
    
    Feb  2 15:29:48 mail postfix/qmgr[10484]: 5CFD845862: from=, size=3665, nrcpt=1 (queue active)
    Feb  2 15:29:48 mail postfix/lmtp[1007]: 5CFD845862: to=, relay=none, delay=306683, delays=306683/0.02/0/0, dsn=4.4.1, status=deferred (connect to mail.insittes.com.br[private/dovecot-lmtp]: Connection refused)
    

    Help?

    • Have you followed part 2 to enable and configure the dovecot-lmtp service?

    • Yes, I followed part 1 and 2, all right, but you don’t receive email when I activate lmtp, these are the error logs.

    • Run the following command to check who is the owner.

      sudo ls -lh /var/spool/postfix/private/dovecot-lmtp

      Also check if Dovecot is running.

      systemctl status dovecot
    • [email protected]:~$ sudo ls -lh /var/spool/postfix/private/dovecot-lmtp
      srw——- 1 postfix postfix 0 Jan 29 19:29 /var/spool/postfix/private/dovecot-lmtp

    • The owner is correct. It should be postfix. Perhaps your Dovecot server isn’t running?

    • [email protected]:~$ dovecot -F
      doveconf: Fatal: Error in configuration file /etc/dovecot/conf.d/10-ssl.conf line 14: ssl_cert: Can't open file /etc/letsencrypt/live/mail.insittes.com.br/fullchain.pem: Permission denied
      

      I think this error should be the problem, how to fix the permission for the file?

    • I think that’s not the problem. If you run the command with sudo, the error would disappear.

      sudo dovecot -F

      Instead, you can check the dovecot log with:

      sudo journalctl -eu dovecot
    • [email protected]:~$ sudo dovecot -F
      doveconf: Fatal: Error in configuration file /etc/dovecot/conf.d/10-ssl.conf line 67: Unknown setting: protocolos
      [email protected]:~$ sudo journalctl -eu dovecot
      Feb 02 15:13:35 mail.insittes.com.br dovecot[898]: doveconf: Fatal: Error in configuration file /etc/dovecot/dovecot.conf: mailbox Rascunho: unknown special_use: \Rascu
      Feb 02 15:13:35 mail.insittes.com.br systemd[1]: dovecot.service: Main process exited, code=exited, status=89/n/a
      Feb 02 15:13:35 mail.insittes.com.br systemd[1]: dovecot.service: Failed with result 'exit-code'.
      Feb 02 15:18:26 mail.insittes.com.br systemd[1]: Started Dovecot IMAP/POP3 email server.
      Feb 02 15:18:26 mail.insittes.com.br dovecot[959]: doveconf: Fatal: Error in configuration file /etc/dovecot/dovecot.conf: mailbox Rascunho: unknown special_use: \Rascu
      Feb 02 15:18:26 mail.insittes.com.br systemd[1]: dovecot.service: Main process exited, code=exited, status=89/n/a
      Feb 02 15:18:26 mail.insittes.com.br systemd[1]: dovecot.service: Failed with result 'exit-code'.
      Feb 02 16:45:45 mail.insittes.com.br systemd[1]: Started Dovecot IMAP/POP3 email server.
      Feb 02 16:45:45 mail.insittes.com.br dovecot[1701]: doveconf: Fatal: Error in configuration file /etc/dovecot/dovecot.conf: mailbox Rascunho: unknown special_use: \Rasc
      Feb 02 16:45:45 mail.insittes.com.br systemd[1]: dovecot.service: Main process exited, code=exited, status=89/n/a
      Feb 02 16:45:45 mail.insittes.com.br systemd[1]: dovecot.service: Failed with result 'exit-code'.
      Feb 02 17:07:18 mail.insittes.com.br systemd[1]: Started Dovecot IMAP/POP3 email server.
      Feb 02 17:07:18 mail.insittes.com.br dovecot[1990]: doveconf: Fatal: Error in configuration file /etc/dovecot/conf.d/10-ssl.conf line 67: Unknown setting: protocolos
      Feb 02 17:07:18 mail.insittes.com.br systemd[1]: dovecot.service: Main process exited, code=exited, status=89/n/a
      Feb 02 17:07:18 mail.insittes.com.br systemd[1]: dovecot.service: Failed with result 'exit-code'.
      Feb 02 17:08:40 mail.insittes.com.br systemd[1]: Started Dovecot IMAP/POP3 email server.
      Feb 02 17:08:41 mail.insittes.com.br dovecot[2199]: doveconf: Fatal: Error in configuration file /etc/dovecot/conf.d/10-ssl.conf line 67: Unknown setting: protocolos
      
    • In the /etc/dovecot/conf.d/10-ssl.conf file, you have a typo. It should be “protocols”, instead of “protocolos”.

  • I do thank you for this great tutorial.
    I have a problem with the DNS A record in step 2 after creating the Apache virtual host and the setup file of postfixadmin does not open as a result. How do I have to create this A record in Linux?

    • You should create DNS record at your domain registrar’s website (such as NameCheap).

      Since you are asking this question, I think you don’t have a domain name. You should buy one in order to set up your own email server. And I think you didn’t read part 1 and part 2 of this tutorial series. You should start reading from part 1.

  • Hello,

    First of all, your tutorial is the best we can find on Internet. I searched a lot and I don’t know how I came to this one, but that’s the one I was looking for ! Keep up the good work !

    The thing is, I had issues and I solved a lot of them. I am a the end of the tutorial, and I have problems with user authentication and maybe creation. Postfix Admin works fine, no errors when I create users, but when I try to connect whit a client, I get thoses logs.

     pam_unix(dovecot:auth): check pass; user unknown
    Feb 10 21:31:34 mail.rt-lanparty.fr auth[12999]: pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot ruser=webmaster rhost=37.165.138.104
    Feb 10 21:31:36 mail.rt-lanparty.fr dovecot[12928]: auth-worker(12999): pam(webmaster,37.165.138.104,): pam_authenticate() failed: Authentication failure (Password mismatch?) (given password: Dragon1807-)
    Feb 10 21:31:36 mail.rt-lanparty.fr dovecot[12928]: auth-worker(12999): Debug: sql(webmaster,37.165.138.104,): query: SELECT username AS user,password FROM mailbox WHERE username = 'webmaster' AND active='1'
    Feb 10 21:31:36 mail.rt-lanparty.fr dovecot[12928]: auth-worker(12999): sql(webmaster,37.165.138.104,): unknown user
    Feb 10 21:31:38 mail.rt-lanparty.fr dovecot[12928]: auth: Debug: client passdb out: FAIL        3        user=webmaster
    Feb 10 21:31:38 mail.rt-lanparty.fr dovecot[12928]: imap-login: Disconnected (auth failed, 3 attempts in 20 secs): user=, method=PLAIN, rip=37.165.138.104, lip=144.91.87.246, TLS, session=
    Feb 10 21:31:38 mail.rt-lanparty.fr dovecot[12928]: auth: Debug: auth client connected (pid=13020)
    Feb 10 21:31:38 mail.rt-lanparty.fr dovecot[12928]: auth: Debug: client in: AUTH        1        PLAIN        service=imap        secured=tls        session=2BVToD6eZuElpYpo        lip=144.91.87.246        rip=37.165.138.104        lport=
    Feb 10 21:31:38 mail.rt-lanparty.fr dovecot[12928]: auth: Debug: client passdb out: CONT        1
    Feb 10 21:31:38 mail.rt-lanparty.fr dovecot[12928]: auth: Debug: client in: CONT        1        AHdlYm1hc3RlckBydC1sYW5wYXJ0eS5mcgBEcmFnb24xODA3LQ== (previous base64 data may contain sensitive data)
    Feb 10 21:31:38 mail.rt-lanparty.fr dovecot[12928]: auth-worker(12999): Debug: pam([email protected],37.165.138.104,): lookup service=dovecot
    Feb 10 21:31:38 mail.rt-lanparty.fr dovecot[12928]: auth-worker(12999): Debug: pam([email protected],37.165.138.104,): #1/1 style=1 msg=Password:
    Feb 10 21:31:38 mail.rt-lanparty.fr auth[12999]: pam_unix(dovecot:auth): check pass; user unknown
    Feb 10 21:31:38 mail.rt-lanparty.fr auth[12999]: pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot [email protected] rhost=37.165.138.104
    Feb 10 21:31:40 mail.rt-lanparty.fr dovecot[12928]: auth-worker(12999): pam([email protected],37.165.138.104,): pam_authenticate() failed: Authentication failure (Password mismatch?) (given password: Dragon1807-)
    Feb 10 21:31:40 mail.rt-lanparty.fr dovecot[12928]: auth-worker(12999): Debug: sql([email protected],37.165.138.104,): query: SELECT username AS user,password FROM mailbox WHERE username = '[email protected]
    Feb 10 21:31:40 mail.rt-lanparty.fr dovecot[12928]: auth: Debug: client passdb out: OK        1        [email protected]
    Feb 10 21:31:40 mail.rt-lanparty.fr dovecot[12928]: auth: Debug: master in: REQUEST        539230209        13020        1        c1388aff0741bba9988080839a747a4a        session_pid=13031        request_auth_token
    Feb 10 21:31:40 mail.rt-lanparty.fr dovecot[12928]: auth-worker(12999): Debug: passwd([email protected],37.165.138.104,): lookup
    Feb 10 21:31:40 mail.rt-lanparty.fr dovecot[12928]: auth-worker(12999): passwd([email protected],37.165.138.104,): unknown user
    Feb 10 21:31:40 mail.rt-lanparty.fr dovecot[12928]: auth-worker(12999): Debug: sql([email protected],37.165.138.104,): user_query = SELECT maildir, 2000 AS uid, 2000 AS gid FROM mailbox WHERE username = 'webmaster
    Feb 10 21:31:40 mail.rt-lanparty.fr dovecot[12928]: auth-worker(12999): Warning: sqlpool(mysql): Query failed, retrying: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right 
    Feb 10 21:31:40 mail.rt-lanparty.fr dovecot[12928]: auth-worker(12999): Error: sql([email protected],37.165.138.104,): User query failed: You have an error in your SQL syntax; check the manual that corresponds to 
    Feb 10 21:31:40 mail.rt-lanparty.fr dovecot[12928]: auth: Debug: master userdb out: FAIL        539230209
    Feb 10 21:31:40 mail.rt-lanparty.fr dovecot[12928]: imap: Error: Internal auth failure (auth connected 0 msecs ago, handshake 0 msecs ago, request took 0 msecs, client-pid=13020 client-id=1)
    Feb 10 21:31:40 mail.rt-lanparty.fr dovecot[12928]: imap-login: Internal login failure (pid=13020 id=1): user=, method=PLAIN, rip=37.165.138.104, lip=144.91.87.246, mpid=13031, TLS, session=
    
    

    Can you please give me a hint on this ?

    Cordialy.

    • You should look at your SQL syntax in the /etc/dovecot/dovecot-sql.conf.ext file. The content of this file should be:

      driver = mysql
      
      connect = host=localhost dbname=postfixadmin user=postfixadmin password=password
      
      default_pass_scheme = ARGON2I
      
      password_query = SELECT username AS user,password FROM mailbox WHERE username = '%u' AND active='1'
      
      user_query = SELECT maildir, 2000 AS uid, 2000 AS gid FROM mailbox WHERE username = '%u' AND active='1'
      
      iterate_query = SELECT username AS user FROM mailbox
      
      
      • Thank you ! I just re-read my conf file and I wrote user_query = user_query… that is why it wasn’t working.

        May I ask another question ? Is it normal that the password is display in clear in the logs ?

    • The password is hashed with MD5-CRYPT. It’s not a clear-text password.

      • Yes, It should be, I know.

        But see :

        auth-worker(2310): pam([email protected],144.91.87.246): pam_authenticate() failed: Authentication failure (Password mismatch?) (given password: password)
    • Disable login debugging in dovecot after you fixed the error.

      • i configured /etc/dovecot/dovecot-sql.conf.ext file as your instruction but i have problem like below :

        Mar 03 12:40:33 vidtu dovecot[313]: auth: Debug: client in: AUTH 2 PLAIN service=imap s
        Mar 03 12:40:37 vidtu dovecot[313]: auth-worker(885): Debug: pam([email protected],91.249.130.15,<khjem/KfbPZb+Z
        Mar 03 12:40:37 vidtu dovecot[313]: auth-worker(885): Debug: pam([email protected],91.249.130.15,<khjem/KfbPZb+Z
        Mar 03 12:40:37 vidtu auth[885]: pam_unix(dovecot:auth): check pass; user unknown
        Mar 03 12:40:37 vidtu auth[885]: pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot
        Mar 03 12:40:39 vidtu dovecot[313]: auth-worker(885): pam([email protected],91.249.130.15,): p
        Mar 03 12:40:39 vidtu dovecot[313]: auth-worker(885): Debug: sql([email protected],91.249.130.15,<khjem/KfbPZb+Z
        Mar 03 12:40:39 vidtu dovecot[313]: auth-worker(885): sql([email protected],91.249.130.15,): u
        Mar 03 12:40:41 vidtu dovecot[313]: auth: Debug: client passdb out: FAIL 2 [email protected]
        Mar 03 12:40:53 vidtu dovecot[313]: imap-login: Disconnected (auth failed, 2 attempts in 24 secs): user=<[email protected]
        lines 7-29/29 (END)

        Checking for dependencies:

        Magic Quotes: Disabled – OK
        Depends on: presence config.inc.php – OK
        Checking $CONF['configured'] – OK
        Depends on: presence config.local.php – OK
        Depends on: MySQL 4.1 – OK
        Testing database connection (using mysqli) – OK
        Depends on: session – OK
        Depends on: pcre – OK
        Depends on: multibyte string – OK
        Warning: Depends on: IMAP functions – NOT FOUND
        To install IMAP support, install php5-imap
        Without IMAP support, you won't be able to create subfolders when creating mailboxes.
        Everything seems fine… attempting to create/update database structure

        Database is up to date: 1841/0

        Do you have any suggest ?

        • I login mailbox in Thunderbird successful and try to sent mail to other mailbox but it seem not working

          ar 03 13:02:20 vidtu dovecot[313]: auth-worker(2883): Debug: pam([email protected],91.249.130.15,<mIkG6vKfn/hb+
          Mar 03 13:02:22 vidtu dovecot[313]: auth-worker(2883): pam([email protected],91.249.130.15,):
          Mar 03 13:02:22 vidtu dovecot[313]: auth-worker(2883): Debug: sql([email protected],91.249.130.15,<mIkG6vKfn/hb+
          Mar 03 13:02:22 vidtu dovecot[313]: auth: Debug: client passdb out: OK 1 [email protected]
          Mar 03 13:02:22 vidtu dovecot[313]: auth: Debug: master in: REQUEST 1055916033 2992 1 f
          Mar 03 13:02:22 vidtu dovecot[313]: auth-worker(2883): Debug: passwd([email protected],91.249.130.15,<mIkG6vKfn/
          Mar 03 13:02:22 vidtu dovecot[313]: auth-worker(2883): passwd(an[email protected],91.249.130.15,
          Mar 03 13:02:22 vidtu dovecot[313]: auth-worker(2883): Debug: sql([email protected],91.249.130.15,<mIkG6vKfn/hb+
          Mar 03 13:02:22 vidtu dovecot[313]: auth: Debug: master userdb out: USER 1055916033 [email protected]
          Mar 03 13:02:22 vidtu dovecot[313]: imap-login: Login: user=, method=PLAIN, rip=91.249.130.15
          ~

  • Hello there,
    After completing “Step 10: Add Domain and Mailboxes in PostfixAdmin” I can send emails but cannot reveing emails. Here is the error:
    Final-Recipient: rfc822; [email protected]
    Original-Recipient: rfc822;[email protected]
    Action: failed
    Status: 5.1.1
    Diagnostic-Code: X-Postfix; unknown user: “USER1”

    Can anyone help with?

    • Check the mail log (/var/log/mail.log) to find out what’s wrong.

      • That is too technical to understand but looks like DEVOCOT is reacting:

        mail dovecot: imap-login: Disconnected (no auth attempts in 0 secs): user=, rip=XXX, lip=XXX, TLS handshaking: SSL_accept() failed: error:1417A0C1:SSL routines:tls_post_process_client_hello:no shared cipher, session=

        All emails sent to my server are not rejected and nor received. The server looks dumb.

    • If you can, please post all warnings and errors in the mail log file.

      • /var/log/mail.log is a huge file.

        the last error I can see is this:
        Feb 20 10:25:18 mail dovecot: auth-worker(6353): pam([email protected],2002:8a1:6df5:ca00:6464:72e6:b14c:c976,): pam_authenticate() failed: Authentication failure (Password mismatch?) (given password: PASSWORD)

    • Send an email to your email address, then open the mail log file and scroll down to the end of the file.

      • – When I send an email from my mail client to gmail, gmail receives it.
        – When I send an email from gmail to my server I can’t see at my mail client nor at /var/vmail/XXX/YYY/cur.
        – Now, if I drag and drop an email at mail client from one ICLOUD to INBOX of my server I can see it at /var/vmail/XXX/YYY/cur as well. If I delete it I can see a file at .Trash. as well.
        – here it goes the lines at /var/log/mail.log:

        Feb 20 11:10:13 mail postfix/smtpd[7185]: connect from unknown
        Feb 20 11:10:13 mail postfix/smtpd[7185]: NOQUEUE: reject: RCPT from unknown[156.96.116.52]: 454 4.7.1 : Relay access denied; from= to= proto=ESMTP helo=
        Feb 20 11:10:13 mail postfix/smtpd[7185]: disconnect from unknown[156.96.116.52] ehlo=1 mail=1 rcpt=0/1 rset=1 quit=1 commands=4/5
        Feb 20 11:11:11 mail dovecot: auth-worker(7155): Debug: conn unix:auth-worker (pid=7154,uid=112): Disconnected: Connection closed (fd=-1)
        Feb 20 11:11:23 mail postfix/smtpd[7185]: connect from mail-oln040092073024.outbound.protection.outlook.com[40.92.73.24]
        Feb 20 11:11:23 mail postfix/smtpd[7185]: Anonymous TLS connection established from mail-oln040092073024.outbound.protection.outlook.com[40.92.73.24]: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
        Feb 20 11:11:23 mail postfix/smtpd[7185]: 8B6293FB94: client=mail-oln040092073024.outbound.protection.outlook.com[40.92.73.24]
        Feb 20 11:11:23 mail postfix/cleanup[7190]: 8B6293FB94: message-id=
        Feb 20 11:11:23 mail postfix/qmgr[2553]: 8B6293FB94: from=, size=6339, nrcpt=1 (queue active)
        Feb 20 11:11:23 mail postfix/lmtp[7191]: 8B6293FB94: to=, relay=none, delay=0.08, delays=0.07/0.01/0/0, dsn=4.4.1, status=deferred (connect to DOMAIN[private/dovecot-lmtp]: No such file or directory)
        Feb 20 11:11:23 mail postfix/smtpd[7185]: disconnect from mail-oln040092073024.outbound.protection.outlook.com[40.92.73.24] ehlo=2 starttls=1 mail=1 rcpt=1 data=1 quit=1 commands=7
        Feb 20 11:13:37 mail dovecot: imap([email protected]): Logged out in=495 out=4253 deleted=0 expunged=0 trashed=0 hdr_count=0 hdr_bytes=0 body_count=0 body_bytes=0

    • This line:

      (connect to DOMAIN[private/dovecot-lmtp]: No such file or directory)

      indicates that Dovecot-LMTP is not working correctly. Please read the Dovecot LMTP instructions in part 2 carefully.

  • Thank You so much.
    For a reason I dont know I skipped the “Using Dovecot to Deliver Email to Message Store”.
    I am now on “7 Effective Tips for Blocking Email Spam with Postfix SMTP Server”.

  • – How di I redo completely this “sudo apt install postfixadmin”?
    – I did something wrong and now when I type this command it does not going from the beginning to all the steps.

  • How do I add a NOREPLY email address?

  • The nginx configuration for 18.04 requires that php-fpm be installed and as such, step 3 is missing the step:

    sudo apt install php-fpm

    • If you follow my LAMP stack or LEMP stack tutorial, you should have php-fpm installed already. I guess people would always ignore the prerequisites section when reading my articles 🙂

      • David Coles
        2 weeks ago

        Thank you Xiao, these are some of the best tutorials I’ve ever followed. My comment about php-fpm is that your LAMP tutorial just says it *may* be required, which suggests it is optional. Given that is a separate tutorial to this series, it isn’t obvious whether this tutorial series requires “Apache PHP module” or “PHP-FPM”. Having seen this comment, I will complete the last bit of the LAMP tutorial and switch to PHP-FPM. Thanks again.

  • I had a problem with a missing, respevtively faulty dovecot configuration in the /postfix/master.cf file. I always got following message:

    Mar  2 11:02:39 mail postfix/pipe[1158]: 89E24A24D0: to=, relay=dovecot, delay=596, delays=596/0/0/0.02, dsn=4.3.0, status=deferred (temporary failure. Command output: pipe: fatal: pipe_command: execvp /usr/libexec/dovecot/deliver: No such file or directory )
    

    I opened the configuration and added following:

    dovecot   unix  -       n       n       -       -       pipe
      flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${user}@${nexthop}
    

    thus making it possible to send a mail to another Mail account. Worth mentioning is, that I skipped all the encryption part and setting everything locally. It took few tries but all in all, it is working now.

  • Zsolt Nagy
    1 month ago

    Hello!
    I have followed the 1,st 2nd and 3rd parts of your tutorial. I set up virtual mailbox with Postgres instead of MySQL/MariaDB. I can send emails and it appears in e.g. gmail, but can’t receive any. Emails sent from postfixadmin are received.
    Gmail sent me the following:

    "The recipient server did not accept our requests to connect. Learn more at https://support.google.com/mail/answer/7720 [mail..com. : timed out]"

    There is no error in “mail.log” nor “mail.err”. Can’t find any error in journal neither.

    I had spam authentication issue, but commented out “auth-system.conf.ext”, because I use “auth-sql.conf.ext”:

     #!include auth-system.conf.ext
    !include auth-sql.conf.ext
    

    Furthermore, I also modified /etc/postfix/main.cf and now it looks like (tried it without the comment as well):

    virtual_transport = lmtp:unix:private/dovecot-lmtp
    #mailbox_transport = lmtp:unix:private/dovecot-lmtp
    smtputf8_enable = no
    

    Any suggestions?

    • The recipient server did not accept our requests to connect. Learn more at https://support.google.com/mail/answer/7720 [mail..com. : timed out]”

      This means that incoming connection to port 25 of your email server is blocked by a firewall. Make sure you have opened port 25 in iptables/ufw.

      There might also be another firewall sitting in front of your own email server. If that’s the case, you need to open port 25 in that firewall as well.

      You can use nmap command on another Linux machine to check if the inbound port 25 is open on your email server.

      sudo nmap mail.your-domain.com

      What do you mean by “spam authentication issue”?

      • Zsolt Nagy
        1 month ago

        Exactly, that was the problem. After I allowed port 25 it has started to work.
        “What do you mean by “spam authentication issue”?” just a typo, I wanted to write “pam”.
        Thank you very much 🙂

  • I’ve got this error:

    dovecot[6965]: auth: Fatal: sql: Unknown database driver ‘mysql’
    dovecot[6953]: master: Error: service(auth): command startup failed

    Can you help?

  • Hi Great tutorials, I have followed part 1 and 2, (I did install a later stable version of php 7.4) but struggling with the end of Step 2.
    http://postfixadmin.example.com/setup.php gets a file not found. It definitely hits my server, however I think it is still pointing to my other virtual host… mail.example.com.
    Following your previous advice, I have tried removed the trailing ‘/’, this had no luck. I also tried playing about with /public/ which is where the setup.php file resides.
    And I have tried removing the log file information.
    I am now fairly sure that it has something to do with Virtual host setup.
    Any help would be appreciated
    Next idea will be to try and move the folder to a sub-directory of my default option although I am sure that you suggested its location separate for good reason?
    N

    • UPDATE
      I solved above issue. I had entered https, which didn’t help – as it meant it would not resolve on my safari , on my iPad the page loaded with errors.
      I had to create a /templates_c folder/
      and redirect to ‘public’ although this was advised by the URL
      …..But hey – I have leant a lot about name-based virtual hosts.

      I then got stuck with a 451 error but I had accidentally skipped a lot of your material out… and hadn’t created the cf files.
      I didn’t reinstall the php stuff as I did that with the LAMP stack.
      Thanks again – onto the next part which coincidentally was something i was going to ask 🙂

  • Terence Love
    1 week ago

    Great tutorials. I’m learning a lot. Thank you.
    When I create Thunderbird user, it times out checking password (everything else good).
    Mail.log shows
    “Mar 29 13:16:30 mail dovecot: auth-worker(3486): Error: mysql(localhost): Connect failed to database (postfixadmin): Access denied for user ‘postfixadmin’@’localhost’ (using password: YES) – waiting for 25 seconds before retry”

    I’ve checked all code in Parts 1, 2 and 3 several times. Mysql opens with mysql -u postfixadmin -p and the copied password I’ve used in
    /etc/dbconfig-common/postfixadmin.conf
    /etc/postfixadmin/dbconfig.inc.php
    /etc/postfix/sql/mysql_virtual_domains_maps.cf
    /etc/postfix/sql/mysql_virtual_mailbox_maps.cf
    /etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
    /etc/postfix/sql/mysql_virtual_alias_maps.cf
    /etc/postfix/sql/mysql_virtual_alias_domain_maps.cf
    /etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf

    I welcome your advice on what I’ve missed.
    Best regards,
    Terry

    • Most likely your password was entered incorrectly in the .cf files.

      • Terence Love
        1 week ago

        Thank you Xiao Guoan,

        I have very carefully checked again each one of the .cf files and all contain the mysql database password correctly. I’m assuming this postfixadmin database password is the correct password for these cf files?

        One thought – Is it possible that having an # in the password is causing the problem?

        Another thought – I’ve just noticed 2 associated errors in the mail.err.1 log and these precede the failure to connect for postfixadmin :

        Mar 29 06:20:46 mail dovecot: auth-worker(24866): Error: sql(admin,X.X.X.X,): Password query failed: Not connected to database  [IP address and password removed by me]
        
        Mar 29 06:20:46 mail dovecot: auth: Error: auth worker: Aborted PASSV request for admin: Lookup timed out.

        Do these indicate anything that I need to change?

    • Terence Love
      1 week ago

      Hi Xiao Guo’an
      The error was a postfixadmin password that contained #.
      Perhaps good to suggest to readers to avoid symbols in passwords else identify which symbols cause problems?
      Many thanks for your wonderful tutorials. I’m looking forward to the next.
      Best wishes,
      Terence

    • Great. Thanks for the tip.

  • Hi, I’m getting this error

    … relay=none, delay=0.07, delays=0.02/0.01/0.04/0, dsn=5.4.6, status=bounced (mail for … loops back to myself)

    Thanks!

  • alias_database = hash:/etc/aliases
    alias_maps = hash:/etc/aliases
    append_dot_mydomain = no
    biff = no
    compatibility_level = 2
    inet_interfaces = all
    inet_protocols = all
    mailbox_size_limit = 0
    mydestination = mail.***.eu, localhost.***.eu, localhost
    myhostname = mail.***.eu
    mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
    myorigin = /etc/mailname
    readme_directory = no
    recipient_delimiter = +
    smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
    smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
    smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
    smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
    smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
    smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
    smtpd_use_tls = yes
    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
    virtual_gid_maps = static:2000
    virtual_mailbox_base = /var/vmail
    virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
    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
    virtual_minimum_uid = 2000
    virtual_transport = lmtp:unix:private/dovecot-lmtp
    virtual_uid_maps = static:2000

    Thank you for answering!

    • It seems you didn’t follow part 1 and part 2 of this tutorial series. Purge your Postfix and Dovecot configuration.

      sudo apt purge postfix dovecot

      And start reading from part 1.

  • Hi,
    I’m following all tutorials to configure a mail server on my Raspberry Pi 4 with Ubuntu 18.04 LTS server.
    After the first two tutorials everything works like a charm: I installed Roundcube and I was able to send and receive emails with my Ubuntu account credentials. Now I followed this third tutorial for install Postfix Admin and manage virtual accounts.
    Postfix Admin installations was successful but now I can’t login to Roundcube webmail, I get “unable to connect to IMAP server”.
    I tried to configure Microsoft Outlook but it says it is unable to connect to IMAP server.

    I didn’t update Dovecot version to 2.3 because there isn’t arm64 build in repositories so I’m using version 2.2.33.2 and I chose SHA512-CRYPT password scheme.

    Can you help me, please?

    • *Edit: the correct error message in English is “Connection to storage server failed.”

    • You can upgrade to Ubuntu 19.10, or wait two weeks and upgrade to 20.04, so you will have Dovecot 2.3.

      • I’d prefer to stay with 18.04, it’s very complicated for me reconfigure the entire system (it hosts Nextcloud, WordPress, Plex and many other services…). I don’t think the problem is Dovecot version (and its password encryption scheme), can you suggest me sothing to do, please?

  • Thank you so much for such detailed and beginner friendly tutorial.

    I just have one issue, I am able to send the E-Mails but unable to receive any from External IDs (e.g. gmail). My mail.log also does not have any error.

    Relevant application ports for ufw app like Postfix, Postfix SMTPS, Postfix Submission, Dovecot IMAP, Dovecot POP3, Dovecot Secure IMAP, Dovecot Secure IMAP, Dovecot Secure POP3, 25/tcp
    are also open on the server, not sure what is wrong in my config.

    Would appreciate if you have any advice on how I can resolve this issue.

    postconf -n

     alias_database = hash:/etc/aliases
    alias_maps = hash:/etc/aliases
    append_dot_mydomain = no
    biff = no
    compatibility_level = 2
    inet_interfaces = all
    inet_protocols = all
    mailbox_command = procmail -a "$EXTENSION"
    mailbox_size_limit = 0
    mailbox_transport = lmtp:unix:private/dovecot-lmtp
    milter_default_action = accept
    milter_protocol = 6
    mydestination = localhost.$mydomain, localhost, $mydomain, mail.tealmail.com
    myhostname = mail.tealmail.com
    mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
    myorigin = /etc/mailname
    non_smtpd_milters = $smtpd_milters
    policyd-spf_time_limit = 3600
    readme_directory = no
    recipient_delimiter = +
    relayhost =
    smtp_tls_loglevel = 1
    smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
    smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
    smtp_tls_security_level = may
    smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
    smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
    smtpd_milters = local:opendkim/opendkim.sock
    smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, check_policy_service unix:private/policyd-spf
    smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
    smtpd_tls_cert_file = /etc/letsencrypt/live/mail.tealmail.com/fullchain.pem
    smtpd_tls_key_file = /etc/letsencrypt/live/mail.tealmail.com/privkey.pem
    smtpd_tls_loglevel = 1
    smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
    smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
    smtpd_tls_security_level = may
    smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
    smtpd_use_tls = yes
    smtputf8_enable = no
    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
    virtual_gid_maps = static:2000
    virtual_mailbox_base = /var/vmail
    virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
    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
    virtual_minimum_uid = 2000
    virtual_transport = lmtp:unix:private/dovecot-lmtp
    virtual_uid_maps = static:2000
    
    • You don’t have a valid MX record. You are using 648986190.pamx1.hotmail.com as your MX host. Instead, your MX record should point to mail.tealmail.com.

  • Hello, do you have any idea why catchall does’nt work? I’ve add alias @my.domain to [email protected] and add mysql_virtual_alias_domain_catchall_maps.cf like in your tutorial but somehow the catchall doesn’t work, I can send email to [email protected] but not caught by [email protected], this mail server of mine already runs fine for years but I just tried to use catchall right now.

Leave a Comment

  • Comments with links are moderated by admin before published.
  • Your email address will not be published.
  • Use <pre> ... </pre> HTML tag to quote the output from your terminal/console.
  • Please use the community (https://community.linuxbabe.com) for questions unrelated to this article.
  • I don't have time to answer every question. Making a donation would incentivize me to spend more time answering questions.