Part 3: PostfixAdmin – Create Virtual Mailboxes on Ubuntu 18.04 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.

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. This tutorial is for Ubuntu 18.04. If you are using Ubuntu 20.04, you should follow this PostfixAdmin guide instead.

PostfixAdmin Features

  • manage mailboxes, virtual domains and aliases
  • vacation/out-of-office messages (Personally I think it’s better done in Roundcube Webmail.)
  • 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
  • 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 😉

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.

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

Step 1: Install MariaDB Database Server

PostfixAdmin is written in PHP and requires a database (MySQL/MariaDB, PostgreSQL or SQLite). This article will use MariaDB database, which is a drop-in replacement for MySQL. It is developed by former members of MySQL team who are concerned that Oracle might turn MySQL into a closed-source product. Enter the following command to install MariaDB on Ubuntu 18.04.

sudo apt install mariadb-server mariadb-client

After it’s installed, MariaDB server should be automatically stared. Use systemctl to check its status.

systemctl status mariadb

Output:

● mariadb.service - MariaDB database server
   Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2018-05-17 02:39:57 UTC; 49s ago
 Main PID: 21595 (mysqld)
   Status: "Taking your SQL requests now..."
    Tasks: 27 (limit: 2059)
   CGroup: /system.slice/mariadb.service
           └─21595 /usr/sbin/mysqld

If it’s not running, start it with this command:

sudo systemctl start mariadb

To enable MariaDB to automatically start at boot time, run

sudo systemctl enable mariadb

Now run the post installation security script.

sudo mysql_secure_installation

When it asks you to enter MariaDB root password, press Enter key as the root password isn’t set yet. Then enter y to set the root password for MariaDB server.

ubuntu 18.04 install lemp stack

Next, you can press Enter to answer all remaining questions, which will remove anonymous user, disable remote root login and remove test database. This step is a basic requirement for MariaDB database security. (Notice that Y is capitalized, which means it is the default answer. )

How to Install LEMP stack on Ubuntu 18.04

Step 2: Install PostfixAdmin on Ubuntu Server

Log into your mail server. Because some readers use MariaDB server, while others use MySQL, which makes things complicated, so before installing PostfixAdmin, we install the dbconfig-no-thanks package to prevent the postfixadmin package from launching the database configure wizard.

sudo apt install dbconfig-no-thanks

Then install PostfixAdmin from the default Ubuntu software repository.

sudo apt install postfixadmin

Note: If you have previously installed mysql-server on Ubuntu, the installation of PostfixAdmin will probably remove the mysql-server package from your system. You can re-install it by running the following command.

sudo apt install mysql-server

Now we need to remove the dbconfig-no-thanks package.

sudo apt remove dbconfig-no-thanks

Then launch the database configure wizard for PostfixAdmin.

sudo dpkg-reconfigure postfixadmin

You will be asked if you want to reinstall database for PostfixAdmin. This simply means creating a database named postfixadmin, it won’t remove your existing databases. Press the Tab key to choose Yes.

reinstall databae for postfixadmin

Then select the default database type: mysql, if you use MySQL or MariaDB.

postfixadmin mariadb mysql

Next, choose the default connection method: Unix socket.

postfixadmin connection method for mysql

Then choose the default authentication plugin for MySQL/MariaDB.

postfixadmin authentication plugin for MySQL MariaDB

Press Enter to choose the default database name for PostfixAdmin.

postfixadmin-ubuntu-18.04-LTS

Press Enter to choose the default database username for PostfixAdmin.

database username for PostfixAdmin

After that, 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
Finally, choose the default database administrative user.

postfixadmin database administrative user

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. We need to change the database type from mysql to mysqli in both of the two files.

sudo nano /etc/dbconfig-common/postfixadmin.conf

Change

dbc_dbtype='mysql'

to

dbc_dbtype='mysqli'

Then edit the second file.

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

Change

$dbtype='mysql';

to

$dbtype='mysqli';

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/

If your system can’t find the setfacl command, you need to install the acl package.

sudo apt install acl

Step 3: 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;
   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 4: 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 5: 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 6: 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 11.

Step 7: Enable Statistics in Dovecot

PostfixAdmin needs to read Dovecot statistics. Edit the Dovecot configuration file.

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

Add the following lines to the end of this file. If you use Nginx, change apache to nginx.

service stats {
    unix_listener stats-reader {
    user = www-data
    group = www-data
    mode = 0660
}

unix_listener stats-writer {
    user = www-data
    group = www-data
    mode = 0660
  }
}

Save and close the file.  Then add the web server to the dovecot group.

sudo gpasswd -a www-data dovecot

Restart Dovecot.

sudo systemctl restart dovecot

Step 8: 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 and create the database tables.

postfixadmin setup checker ubuntu 18.04

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

If you see the following error when trying to create a superadmin account,

can’t encrypt password with dovecotpw, see error log for details

It’s because the www-data user doesn’t have permission to read Let’s Encrypt TLS certificate. To fix it, run the following command to grant permissions.

sudo setfacl -R -m u:www-data:rx /etc/letsencrypt/live/ /etc/letsencrypt/archive/

After the superadmin is created, you can log into PostfixAdmin at postfixadmin.example.com/login.php.

postfixadmin virtual mailbox domains

Step 9: 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 10: 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 also add the following line at the end of this file.

virtual_transport = lmtp:unix:private/dovecot-lmtp

Configure-Postfix-to-Use-MySQL-MariaDB-Database-ubuntu

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 2.

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/

Next, we need to change the value of the mydestination parameter in Postfix. Display the current value:

postconf mydestination

Sample output:

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

The mydestination parameter contains a list of domain names that will receive emails delivered to local Unix accounts. In part 1, we added the apex domain name (like linuxbabe.com) to mydestination. Since we are going to use virtual mailbox, we need to remove the apex domain name from the list by issuing the following command.

sudo postconf -e "mydestination = \$myhostname, localhost.\$mydomain, localhost"

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

sudo nano /etc/postfix/main.cf

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 --system --group --uid 2000 --disabled-login --no-create-home

Create the mail base location.

sudo mkdir /var/vmail/

Make vmail as the owner.

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

Step 11: 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 following mail_location. Email messages are stored under the Maildir directory under each user’s home directory.

mail_location = maildir:~/Maildir

Since we are using virtual mailbox domain now, we need to enable mail_home for the virtual users by adding the following line in the file, because virtual users don’t have home directories by default.

mail_home = /var/vmail/%d/%n

virtual mailbox home directory

Save and close the file. Then 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 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

Now you probably don’t want local Unix users to send emails without registering email addresses in PostfixAdmin, then comment out the following line by adding the # character at the beginning, so Dovecot won’t query the local /etc/passwd or /etc/shadow file.

#!include auth-system.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

dovecot mysql Password database

Save and close the file.

Edit the dovecot-sql.conf.ext file.

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

By default all lines are commented out. You can copy the following lines and paste them at the end of the file. Replace password with the postfixadmin password you set in Step 2.

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

Save and close the file. 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 12: Add Domain and Mailboxes in PostfixAdmin

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

To fix, edit the /usr/share/postfixadmin/common.php file 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.

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.

ubuntu postfix dovecot letsencrypt https

Hint: You can also use port 993 with SSL/TLS encryption for IMAP, and use port 465 with SSL/TLS encryption for SMTP. You should not use port 25 as the SMTP port in mail clients to submit outgoing emails.

You should now be able to connect to your own email server and also send and receive emails with your desktop email client! Note that you cannot use local Unix accounts to login now. You must log in with the virtual user created from PostfixAdmin web interface.

Change User Password in PostfixAdmin

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

Troubleshooting

As a rule of thumb, you should always check the mail log (/var/log/mail.log) on your mail server when an error happens. The following is a list of specific errors and troubleshooting tips.

Can’t log in from Mail Clients

If you can’t log into your mail server from a desktop mail client, scan your mail server to find if the ports are open. Note that you should run the following command from another Linux computer or server. If you run it on your mail server, then the ports will always appear to be open.

sudo nmap mail.your-domain.com

And check if Dovecot is running.

systemctl status dovecot

You can also check the mail log (/var/log/mail.log), which may give you some clues. If Dovecot fails to start, the error might not be logged to the /var/log/mail.log file, you can run the following command to see what’s wrong.

sudo journalctl -eu dovecot

If you see the following error in the mail log, it’s likely that you didn’t set a correct password in the .cf files under /etc/postfix/sql/ directory.

postfix/trivial-rewrite[28494]: warning: virtual_alias_domains: proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf: table lookup problem
postfix/trivial-rewrite[28494]: warning: virtual_alias_domains lookup failure

If you see the following error in the mail log, it’s because you forgot to add mail_location = maildir:~/Maildir in the /etc/dovecot/conf.d/10-mail.conf file.

open(/var/mail/[email protected]) failed: Permission denied (euid=2000(vmail) egid=2000(vmail) missing +w perm: /var/mail, we're not in group 8(mail), dir owned by 0:8 mode=0775

Cloudflare DNS

As I said in part 1, if you use Cloudflare DNS service, you should not enable the CDN (proxy) feature when creating DNS A record and AAAA record for the hostname of your mail server. Cloudflare doesn’t support SMTP or IMAP proxy.

Relay Access Denied

If you see the “relay access denied” error when trying to send emails from a mail client, it’s most likely that you use port 25 as the SMTP port in your mail client. As I said a while ago, you should use port 587 or 465 as the SMTP port in mail clients (Mozilla Thunberbird, Microsoft Outlook, etc) to submit outgoing emails. Port 25 should be used for SMTP server to SMTP server communications.

postfix dovecot relay access denied

iOS Mail App

If you use the iOS Mail app to log into your mail server and encounter the following error.

ios the mail server is not responding

You can try to fix it by enforcing SSL encryption, for both SMTP and IMAP.

ios mail enforce SSL encryption

Fun fact: It seems the iOS Mail app has difficulty in supporting STARTTLS on IMAP port 143, but it supports STARTTLS on the submission port 587.

Automatically Clean the Junk Folder and Trash Folder

To delete emails in Junk folder for all users, you can run

sudo doveadm expunge -A mailbox Junk all

To delete emails in Trash folder, run

sudo doveadm expunge -A mailbox Trash all

I think it’s better to clean emails that have been in the Junk or Trash folder for more than 2 weeks, instead of cleaning all emails.

sudo doveadm expunge -A mailbox Junk savedbefore 2w

Then add a cron job to automate the job.

sudo crontab -e

Add the following line to clean Junk and Trash folder every day.

@daily doveadm expunge -A mailbox Junk savedbefore 2w;doveadm expunge -A mailbox Trash savedbefore 2w

To receive report when a Cron job produces an error, you can add the following line above all Cron jobs.

MAILTO="[email protected]"

Save and close the file. And you’re done.

Restricting Access to Sendmail

By default, any local user can use the sendmail binary to submit outgoing emails. Now that your mail server is using virtual mailboxes, you might want to restrict access to the sendmail binary to trusted local users only, so a malicious user can’t use it to send a large volume of emails to damage your mail server’s reputation. Edit the Postfix main configuration file.

sudo nano /etc/postfix/main.cf

Add the following line to the end of this file, so only the root and www-data user can submit emails via sendmail. You can also add other usernames.

authorized_submit_users = root,www-data

Save and close the file. Then restart Postfix.

sudo systemctl restart postfix

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.

If you want to access emails from a web browser, then I recommend Roundcube, which is a very popular and featured-rich open-source webmail client. 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: 6 Average: 5]

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

  • Constantinos
    2 years ago

    Thank you very very much for doing all this work!

  • elanon
    2 years ago

    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.

      • elanon
        2 years ago

        My fault – of course i miss this section.

        Thank you – greate job with that tutorial!

  • Ken Wright
    2 years 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 years ago

        No. That gets me 404 as well.

        • Ken Wright
          2 years 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
        1 year 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
        1 year 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
        1 year 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
        1 year 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
        1 year 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
        1 year 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
        1 year 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
        1 year 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
        1 year 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
        1 year 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
        1 year 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
        1 year 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
        1 year 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
        1 year 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
        1 year 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 years ago

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

  • Gunnar
    2 years ago

    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
      • Luca
        1 year ago

        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
  • Jeroen
    1 year ago

    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 🙂

    • Jeroen
      1 year ago

      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
  • Raffael
    1 year ago
    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?

    • Raffael
      1 year ago

      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
    • Raffael
      1 year ago

      [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?

    • Raffael
      1 year ago
      [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
    • Raffael
      1 year ago
      [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”.

  • Arash
    1 year ago

    I do thank you for this great tutorial.
    I have a problem with the DNS A record in step 3 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.

  • Etienne
    1 year ago

    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        us[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
      
      
      • Etienne
        1 year ago

        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 ARGON2I. It’s not a clear-text password.

      • Etienne
        1 year ago

        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.

  • Alex
    1 year ago

    Hello there,
    After completing “Step 12: 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.

      • Alex
        1 year ago

        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.

      • Alex
        1 year ago

        /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.

      • Alex
        1 year ago

        – 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.

  • Alex
    1 year ago

    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”.

  • Alex
    1 year ago

    – 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.

  • Alex
    1 year ago

    How do I add a NOREPLY email address?

    • Use the Postfixadmin web interface to add mailboxes. Plain and simple.

      • Alex
        1 year ago

        Thank you. But those email addresses accepts incoming email and a NOREPLY email address does not accept incoming email.

    • You can set a filter in the roundcube webmail for the noreply address to reject every incoming email. Plain and simple.

  • David Coles
    1 year 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.

  • Cole
    1 year ago

    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 year 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 year 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 🙂

  • Alex
    1 year ago

    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?

  • Neil
    1 year ago

    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 3.
    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

    • Neil
      1 year ago

      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 year 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 year 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 year 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.

      • Danny
        7 months ago

        It appears that all special characters may cause this issue. I had the same error when using

        .

        and

        !
  • 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.

      • Wow, that was stupid. Sorry for bothering you.

  • Sahil
    1 year ago

    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.

  • Raffael Carvalho
    1 year ago

    Hello!
    (I write only in Portuguese, I’m sorry for the direct translation on google to English).
    Once again I thank you for your great tutorial. I need to implement an email sending limit per sasl user, that email would be daily. I tried to configure Postfwd and policyd-rate-threshold more without success. Do you have any tools to refer me? It would be very positive to include an item in your tutorial to create email sending limit policies per user, this will help prevent attacks on email accounts for sending spam.
    Thank you in advance.

  • Erik Olsen
    1 year ago

    I MADE IT THROUGH! 😀

    Seriously, thank you for these tutorials, I have been trying to get a Linux-based email server up for my business and they never seemed to work right. I followed your three guides plus the DKIM/SPF/DMARC add-ons and I am successfully able to send email to everywhere but Yahoo.com. I think their DNS updates are VERY slow so I am going to try it again later. GMAIL and other domains are fine; in fact, a few suppliers who I never bothered to change my email address with have been emailing my account since I finished the last settings you outlined.

  • Hi Xiao
    once again all appreciation for the best tutorial about a mail server.
    need some help again
    first off all, that issue with the redirection to login page everytime you click on a link in the web interface of postfix admin didn’t fix(at least for me) by commented those line in common.php. Checked on internet and found a fix from one guy(cristian boltz) that says it is a cookie issue and he sugested to create an empty file inside our postfixadmin web directory /usr/share/postfixadmin named favicon.ico and doing that fixed the issue

    then, when I reply from my yahoo account back to my new created email account i gert in yahoo a rejection return saying that: 550.1.1 recipient address rejected. User unknown in local recipient table

    thanks for some support

    • What is the output of this command:postconf mydestination and postconf myhostname

      • Here you are. Thank You!

        ~$ postconf mydestination
        mydestination = $myhostname, mail.10qconcept.com, localhost.com, , localhost

        ~$ postconf myhostname
        myhostname = 10qconcept.com

    • You should not use 10qconcept.com as the hostname. Run the following command to set mail.10qconcept.com as the hostname.

      sudo postconf -e "myhostname = mail.10qconcept.com"

      Then restart Postfix.

      sudo systemctl restart postfix
  • Jeremias Bohn
    1 year ago

    Hi,
    while most people have problems with receiving mails, my issue is the exact opposite: I can receive mails just fine, but I cannot send any mails.

    Content of /var/log/mail.log:

    13 17:31:52 h2835485 postfix/master[8060]: daemon started -- version 3.3.0, configuration /etc/postfix
    Jun 13 17:32:24 h2835485 postfix/smtpd[8066]: connect from [REDACTED]
    Jun 13 17:32:24 h2835485 postfix/smtpd[8066]: Anonymous TLS connection established from [REDACTED]: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
    Jun 13 17:32:24 h2835485 postfix/smtpd[8066]: NOQUEUE: reject: RCPT from [REDACTED]: 454 4.7.1 : Relay access denied; from= to= proto=ESMTP helo=
    Jun 13 17:32:24 h2835485 postfix/smtpd[8066]: disconnect from [REDACTED] ehlo=2 starttls=1 mail=1 rcpt=0/1 quit=1 commands=5/6
    

    Output of 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
    mydestination = $myhostname, localhost.$mydomain, localhost, mail.jeremias-bohn.de
    myhostname = mail.jeremias-bohn.de
    myorigin = /etc/mailname
    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_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
    smtpd_tls_cert_file = /etc/letsencrypt/live/mail.jeremias-bohn.de/fullchain.pem
    smtpd_tls_key_file = /etc/letsencrypt/live/mail.jeremias-bohn.de/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
    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

  • Jeremias Bohn
    1 year ago

    Thank you so much, Windows’s standard Mail app apparently doesn’t have a specific port field, you have to specify it with the URL! That’s why I forgot to do this!

    Also thanks for the great tutorial!

  • Olaawo Oluwapelumi
    1 year ago

    Thank you so much for the well detailed tutorial and the time spent to answer questions as regards this post.

    I was able to achieve the part every part covered so far except that mails sent from third party providers like GMAIL does get delivered to my inbox.

    E.G mail sent from ****@gmail.com doesnt get delivered to [email protected]

    I know this has to do with my hostname but i couldn’t notice where i messed things up.

    Below is the result of running : postconf mydestination

     mydestination = $myhostname, localhost.$mydomain, localhost 

    Also below are the last few lines of my /etc/postfix/main.cf

    smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
    myhostname = mail.my-domain.com
    alias_maps = hash:/etc/aliases
    alias_database = hash:/etc/aliases
    myorigin = /etc/mailname
    mydestination = $myhostname, localhost.$mydomain, localhost
    relayhost =
    mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
    mailbox_size_limit = 0
    recipient_delimiter = +
    inet_interfaces = all
    inet_protocols = all
    message_size_limit = 52428800
    mailbox_transport = lmtp:unix:private/dovecot-lmtp
    smtputf8_enable = no
    virtual_mailbox_base = /var/vmail
    virtual_minimum_uid = 2000
    virtual_uid_maps = static:2000
    smtp_header_checks = regexp:/etc/postfix/smtp_header_checks
    

    I hope you find time to look into my situation.

    Thanks.

    • Olaawo Oluwapelumi
      1 year ago

      Also running

       tail -f /var/log/mail.log 

      Then sending a mail to the server gives the following response

      Jun 23 10:00:31 mail postfix/smtpd[26872]: connect from mail-vs1-f52.google.com[209.85.217.52]
      Jun 23 10:00:31 mail postfix/smtpd[26872]: Anonymous TLS connection established from mail-vs1-f52.google.com[209.85.217.52]: TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)
      Jun 23 10:00:32 mail postfix/smtpd[26872]: NOQUEUE: reject: RCPT from mail-vs1-f52.google.com[209.85.217.52]: 454 4.7.1 : Relay access denied; from= to= proto=ESMTP helo=
      Jun 23 10:00:32 mail postfix/smtpd[26872]: disconnect from mail-vs1-f52.google.com[209.85.217.52] ehlo=2 starttls=1 mail=1 rcpt=0/1 data=0/1 quit=1 commands=5/7
      Jun 23 10:01:09 mail dovecot: auth-worker(26866): Debug: conn unix:auth-worker (pid=26865,uid=112): Disconnected: Connection closed (fd=-1)
      Jun 23 10:03:52 mail postfix/anvil[26874]: statistics: max connection rate 1/60s for (smtp:37.49.224.106) at Jun 23 10:00:20
      Jun 23 10:03:52 mail postfix/anvil[26874]: statistics: max connection count 1 for (smtp:37.49.224.106) at Jun 23 10:00:20
      Jun 23 10:03:52 mail postfix/anvil[26874]: statistics: max cache size 2 at Jun 23 10:00:31
      Jun 23 10:13:42 mail postfix/smtpd[26990]: warning: database /etc/aliases.db is older than source file /etc/aliases
      
      
    • You didn’t follow step 10.

      • Olaawo Oluwapelumi
        1 year ago

        Thank you so much for attending to me.

  • Olaawo Oluwapelumi
    1 year ago

    I found that i left out the part that actually linked to the virtual maps

    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
    virtual_transport = lmtp:unix:private/dovecot-lmtp
    

    It works very well now.

    Thank you so much for providing this information completely for free and still being willing to attend to someone who missed his steps.

  • peacecop kalmer:
    1 year ago

    I did the setup before changing the hash type so I couldn’t log in afterwards and had to rewrite the hash in the config file and create a new admin user. After that, I could log in and change the password of the previous admin account.

  • The Americans
    1 year ago

    A problem was found with your Postfix virtual maps : The map source mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf cannot be used : Failed to query table : 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 ‘from where = limit 1’ at line 1

    Any ideas?

    • The error message is self-explanatory. The SQL syntax is wrong. Open the /etc/postfix/sql/mysql_virtual_alias_maps.cf file and fix the syntax error.

      • The Americans
        1 year ago

        10.5.4-MariaDB-1:10.5.4+maria~focal mariadb.org binary distribution

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

    • You have apostrophes in the “query” line. They should be single quotes instead.

      PS: It seems you are using Ubuntu 20.04. You should follow this PostfixAdmin tutorial.

  • The Americans
    1 year ago

    Yes, yes we did follow 20.04; ended up here by a Google search accident see you over there @ 20.04 >>> Thanks ! ! !

  • Roy Esterhuizen
    1 year ago

    How do we go about enabling or getting the vacation/ out of office to work in postfixadmin?

  • RS BARI
    1 year ago

    I have trouble when step:

    Create superadmin account
    
    Setup password:
    Admin:
    Password:
    Password (again):
    

    Admin, Password and Password (again) leave empty?
    I can’t Add Admin on this step. Can you help me Xiao? Thanks

    • RS BARI
      1 year ago

      Sorry Xioa, now everthing is fine. Hehe

  • RS BARI
    1 year ago

    “To fix, edit the common.php file in the PostfixAdmin web root directory and comment out the following lines.”

    Where is location this file?

    • It’s /usr/share/postfixadmin/common.php 🙂

      • RS BARI
        1 year ago

        Ok, I found it. Thank you so much for attending to me 🙂

      • RS BARI
        1 year ago

        One question again please:

        Jul 17 12:04:57 vultr dovecot: config: Warning: NOTE: You can get a new clean config file with: doveconf -Pn > dovecot-new.conf
        Jul 17 12:04:57 vultr dovecot: config: Warning: Obsolete setting in /etc/dovecot/conf.d/10-ssl.conf:58: ssl_protocols has been replaced by ssl_min_protocol
        

        That is my mail.log, what is the meaning of this warning Xiao?

    • That’s because you upgraded Dovecot 2.2 to 2.3. ssl_protocols has been replaced by ssl_min_protocol in v2.3.

      Edit /etc/dovecot/conf.d/10-ssl.conf file, find the following line.

      ssl_protocols = !SSLv3 !TLSv1 !TLSv1.1

      Comment it out and add the following line.

      ssl_min_protocol = TLSv1.2

      Save and close the file. Then restart Dovecot.

      sudo systemctl restart dovecot
  • Valkje
    12 months ago

    Hi Xiao,

    I have a rather strange issue about which I could not find that much online. When setting up the admin account on postfixadmin.example.org/setup.php (where example.org is of course my own domain), the page responds with “can’t encrypt password with dovecotpw, see error log for details”. The error log reports the following:

    FastCGI sent in stderr: "PHP message: PHP Warning:  Cannot assign an empty string to a string offset in /usr/share/postfixadmin/variables.inc.php on line 31PHP message: dovecotpw password encryption failed.PHP message: STDERR output: doveconf: Fatal: Error in configuration file /etc/dovecot/conf.d/10-ssl.conf line 12: ssl_cert: Can't open file /etc/letsencrypt/live/mail.example.org/fullchain.pem: Permission denied
    

    It seems dovecotpw cannot access the certificate and thus fails to encrypt the password. Running dovecotpw with sudo privileges from the command line works as intended, so there should not be any typos in 10-ssl.conf. I’ve checked with systemctl, and dovecot itself is running normally, if that’s of any help. My dovecot version is 2.3.11.3.

    I could of course start changing permissions on the live or archive folders of my Nginx installation, but I am hesitant to do so. Do you have an alternative solution?

    • Ozzypig
      12 months ago

      Oh my god, I’m having the same problem. I’m this guide for the second time, except using dovecot 2.3.11.3 (502c39af9). I’ve tried to chown and chmod the letencrypt/live directory to no avail – I’m almost convinced this is a bug in dovecot, but I can’t say for certain.

      I’ve double checked to a tee all my configurations – it’s all kosher. I’m about to try downgrading dovecot to the exact version used in this article. Xiao, if you have any suggestions we’re all ears!

    • Ozzypig
      12 months ago

      Found a solution to this! I downgraded dovecot to the version used in this article, dovecot 2.3.9.2 (cf2918cac), and it seems to be working. The first time I went through this tutorial, I used dovecot 2.3.10.1 (a3d0e1171) and it also works. So, this is probably just a problem with dovecot 2.3.11 most likely.

      Anyway… here’s how you can downgrade. Edit the dovecot.list file you made while following the tutorial:

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

      Change to the specific dovecot version. I used 2.3.9.2 and it worked:

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

      Remove then re-install all the dovecot packages:

      sudo apt remove dovecot-core dovecot-imapd dovecot-lmtpd dovecot-pop3d
      sudo apt install dovecot-core dovecot-imapd dovecot-lmtpd dovecot-pop3d
      

      Remember, when prompted be sure to keep local configurations (unless you plan on following the guide again). Otherwise you might lose some progress.

      Good luck!

      • Anderson
        12 months ago

        Wow, I am trying for two days to fix this issue as well. One server is working normally but the new server I got stuck in that.

        My old server is using dovecot 2.3.4.1 and the new is 2.3.11.3.

        I lost the count how many times I started from scratch thinking I made some mistake.

        I will try your suggestion and hope it works.

        Thank you for sharing!

      • DiegoJ
        11 months ago

        Thanks a lot Ozzypig. I was lost man. Just one thing, after re-installing dovecot, I run:

         sudo apt-get update && sudo apt-get upgrade

        That’s beacuse you install an older version of dovecot after re-installing (run: dovecot –version), updating and/or upgrading (I can’t tell the difference) you get the 2.3.9.2 version you told us.

        THANKS.

        Hope Xiao can tell us something about this thing, why can’t we update/upgrade dovecot. I had the same error as Shabu and this was my solution because I couldn’t log in to the postfix Admin panel. I do update/upgrade almost 2 times a week at least, after the last dovecot update it was showing me the errors.

        THANKS a lot

        • DiegoJ
          11 months ago

          Hi Guys, after reinstalling an older version of dovecot, you have to keep in mind that you need to re-install other packages too. In my case, and after a couple of days, I found I missed the dovecot-mysql package. There was an error in the logs telling : unknown driver:mysql…..it wasn’t a typo but that package that wasn’t installed.
          You just have to install it with:

          sudo apt install dovecot-mysql 
        • RizeXor
          11 months ago

          Same problem here

      • Danny
        9 months ago

        thanks so much Ozzypig!

  • Shabu Khan
    11 months ago

    I redid all of it from the beginning – followed the tutorial to a tee.

    Worked like a charm.

    Thank you Xiao. You are a R0ckstar!

  • I have verified that everything works perfectly (once again, after backtracking) to the beginnings of step 9, when I move on to using the Mariadb data base. I should note that I have uninstalled and reinstalled all of the components of postfixadmin and it’s database then tried again. When it comes time to login to postfixadmin I link my domain, create another email account and Postfixadmin works fine. However, my ability to login from Thunderbird on my laptop and Spark on my Iphone is gone. Also, so is the ability to complete the test config with Roundcube.

    So, heres where it gets interesting… (as I began to ask about in tutorial 2) I use *$sudo tail -f /var/log/syslog | grep dovecot* to watch for errors and get an error that states *unknown user* during the auth-worker process. After some thought and research it seems like it’s not getting anything from the Mariadb database, so I opened it up in myphpadmin to take a look (bear with me here, I have never used MySQL or Myphpadmin before), I went to the Postfixadmin table and looked into the mailbox collumn. I inserted my user name into the name field, my password into the password field and my vmail path into the mairdir field. Phpmyadmin showed an error when I did. That lead me to this link (https://devanswers.co/problem-php-7-2-phpmyadmin-warning-in-librariessql-count/), documenting a bug in php 7.2 which was easy to fix and turned out to be inconsequential to my issues. Upon trying to re-login, I got an error stating that passwords mismatched and to use a PLAIN encryption scheme.

    A little more research/fiddling around and I had reverted the encryption in /etc/postfixadmin/config.inc.php back to ‘md5crypt’ and changed /etc/dovecot/dovecot-sql.conf.ext value to default_pass_scheme = PLAIN-MD5, then I went into Phpmyadmin and edited the mailbox collumn’s password funtion to MD5. That got me connected remotely to my mailserver. Cool.

    But… there was only two boxes displayed under my account in Thunderbird, “Inbox” and “Trash”, that seemed odd. So, I sent a test email to my icloud account, which arrived just fine. Clearly I’m connected. Then I tried replying to that email and it was returned to sender. Using sudo tail -f /var/log/syslog | grep postfix I looked at the error, and the server was rejecting it. I tried sending from a different email account and got the same issue. I have lost the log entry stating what the error was, but researching it, it was rejecting them as if they were firewalled or maybe blacklisted. My ports are opened correctly and Im not running any blacklisting methods.

    This morning I retested everything and now the postfix error is stating:

    A855813B83C: to=, relay=mail.example.com[private/dovecot-lmtp], delay=0.12, delays=0.07/0.02/0.02/0.02, dsn=5.1.1, status=bounced (host mail.example.com[private/dovecot-lmtp] said: 550 5.1.1  User doesn't exist: [email protected] (in reply to RCPT TO command))
    

    I just sent one from [email protected], so I’m certain that it exists, lol.

    So heres a few things that I gather… I feel like from your tutorials that I shouldn’t need to manually enter my user name, password or mail path into the database and that it should have accepted the ARGON2I encryption format. Also, I should not be having emails returned to sender once I am able to login. All of these issues only happen once I begin the processes of using the MySQL/Mariadb database. I’ve gone over your tutorials and cross referenced them with a few others and this is all very straightforward and matches what you and others have done, but my results are wildly different.

    At this point I am down to wiping out my VPS, reinstalling Ubuntu and trying again from scratch under the assumption that somewhere there was an install flaw. The only things I have done other than attempt to complete your tutorials have been setting the LAMP stack, setting up ssh, installing wordpress and setting up FTP. There just isn’t too many possibilities for conflicts and I am at a loss for causes.

    I know this doesn’t offer anyone a solution, but I hope if anyone else runs into similar symptoms that I can save them the massive waste of time I’ve gone through to troubleshoot this, and if a solution presents itself (up to wiping the server) I will post it here to try and save them the headache. Any insights added by anyone would be appreciated too.

    Thanks.

  • Hello. Hope you are doing well! I did all the steps and I think it is all ok right now. Even nmap mail.domain.com gave me all ports and it means it’s all working.
    But I have a problem with roundcube.
    When I log into roundcube, I get 504 gateway time-out, and in log file, I get such errors. I’m sure I’m using the correct password, and have no idea what is wrong here!
    Roundcube was working correctly before this tutorial, now the problem is with database. What is the problem? Thank you for your help.

    • Make sure you have entered the correct password for the postfixadmin database user in /etc/dovecot/dovecot-sql.conf.ext file.

      • Hey Xiao! Thank you again for your amazing tutorials.
        Problem was not incorrect password.
        Problem was, I had ‘#’ in my password!
        I wrote the solution here, just because this is almost impossible to figure out this is the problem.
        So, the guy who is reading this comment, make sure you don’t use # in your postfixadmin account in database!

  • peacecop kalmer:
    8 months ago

    I followed your instructions in July and created the mail server successfully. However, now, I can’t log in to postfixadmin anymore. It says that the username or password is incorrect. It can’t be incorrect as I’ve stored them in Google and “Chrome”. I have two admin accounts and none of them can’t be used for logging in. So I changed the main password with “setup.php” and copied that hash into the configuration file. Then, I deleted one of the admin accounts directly in the database from the table “admin”. Finally, I tried to recreate that deleted admin account using “setup.php”. I get the following error message: “can’t encrypt password with dovecotpw, see error log for details”. I don’t even know where to look for that log. It isn’t postfixadmin’s log as there are no errors reported. And “dovecot”‘s service’s status is active – no problems, only two warnings after restart regarding to creating clean config file and and obsolete setting in SSL config file. So how can I restore the access to postfixadmin?

    • peacecop kalmer:
      8 months ago

      I had a look into the error log file of postfixadmin and found these complaints:

      [Wed Dec 02 02:33:37.551048 2020] [authz_core:debug] [pid 30540] mod_authz_core.c(809): [client 192.168.1.65:54948] AH01626: authorization result of Require all granted: granted, referer: https://postfixadmin.tennis24.ee/setup.php
      [Wed Dec 02 02:33:37.551070 2020] [authz_core:debug] [pid 30540] mod_authz_core.c(809): [client 192.168.1.65:54948] AH01626: authorization result of : granted, referer: https://postfixadmin.tennis24.ee/setup.php
      [Wed Dec 02 02:33:37.551280 2020] [php7:warn] [pid 30540] [client 192.168.1.65:54948] PHP Warning: Cannot assign an empty string to a string offset in /usr/share/postfixadmin/variables.inc.php on line 31, referer: https://postfixadmin.tennis24.ee/setup.php
      [Wed Dec 02 02:33:37.568128 2020] [php7:notice] [pid 30540] [client 192.168.1.65:54948] dovecotpw password encryption failed., referer: https://postfixadmin.tennis24.ee/setup.php
      [Wed Dec 02 02:33:37.568155 2020] [php7:notice] [pid 30540] [client 192.168.1.65:54948] STDERR output: doveconf: Fatal: Error in configuration file /etc/dovecot/conf.d/10-ssl.conf line 13: ssl_cert: Can't open file /etc/letsencrypt/live/test.tennis24.ee/fullchain.pem: Permission denied\n, referer: https://postfixadmin.tennis24.ee/setup.php
      [Wed Dec 02 02:33:37.568897 2020] [deflate:debug] [pid 30540] mod_deflate.c(854): [client 192.168.1.65:54948] AH01384: Zlib: Compressed 1320 to 732 : URL /setup.php, referer: https://postfixadmin.tennis24.ee/setup.php
      

      Is the issue connected to the permission problem? If so why is the permission denied?

    • It’s because the www-data user doesn’t have permission to read Let’s Encrypt TLS certificate. To fix it, run the following command to grant permissions.

      sudo setfacl -R -m u:www-data:rx /etc/letsencrypt/live/ /etc/letsencrypt/archive/
      
  • Hi Xiao,

    Thank you ever so much for your tutorial. There are probably plenty of people who know how to do all this, but it takes someone special to put it down for anyone to understand it in the way you did. This is unfortunately quite rare in the linux-community.

    I just wanted to mention that I ran into a little problem with one of the queries in step 10. My system is Debian 10 with postgresql 11.9.
    I got an SQL-error with the following 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'

    The trouble was with “alias.active = 1” it was missing single quotes around the 1.

    Anyway, I just bought you a beer.

  • Block M
    6 months ago

    Hi Xiao,

    Thanks for this awesome tutorial, all 3 parts ! My question is regarding a part I find mentioned on the PostFixadmin sourceforge page but not in any tutorial. How does one get postfixadmin-cli on ubuntu 18.04 ? I’d like to create virtual mailboxes for users by triggering a script.

    Thanks
    B.M

  • Quang Mai
    4 months ago

    Dear Xiao,
    Thank you for this wonderful instruction. I have this email server up and running for over a year now. Love it so much. There is one thing which I couldn’t find out how to do it, I searched here at your site but couldn’t find it either.

    How do I upgrade the postfix to the newer version? I’m running v3.0.2 but the latest is 3.3.6!
    Thank you so much in advance for this.
    Sincerely yours,
    Quang

  • Rohan Abbas
    3 months ago

    Hello, great tutorial.

    How do I transfer my existing mails in unix account to virtual mailbox account ?

  • fernando
    3 months ago

    Do you know if this post is worth installing of postfixadmin with iredmail?

Comments are closed. For paid support, please contact [email protected]