Part 3: PostfixAdmin – Create Virtual Mailboxes on Ubuntu 20.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 accounts. This tutorial is going to show you how to create virtual mailboxes on Ubuntu 20.04 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 a local Unix account for each email address. If you are going to set up a mail server for a company or organization, it’s always better to have an easy way to create virtual mailboxes in a web-based interface, which also allows users to change their passwords. That’s where PostfixAdmin comes in.
PostfixAdmin Features
- manage mailboxes, virtual domains, and aliases
- vacation/out-of-office messages (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 😉
Note: Once you finish part 3, you can no longer use local Unix accounts as email addresses. You must create email addresses from the PostfixAdmin web interface.
Prerequisites
It’s required that you have followed part 1 and part 2 of this tutorial series before continuing to read this article. If you followed mail server tutorials on other websites, I recommend purging your configurations (sudo apt purge postfix dovecot-core
) 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 20.04.
sudo apt install mariadb-server mariadb-client
After it’s installed, MariaDB server should be automatically started. Use systemctl to check its status.
systemctl status mariadb
Output:
● mariadb.service - MariaDB 10.3.22 database server
Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2020-04-10 14:19:16 UTC; 18s ago
Docs: man:mysqld(8)
https://mariadb.com/kb/en/library/systemd/
Main PID: 9161 (mysqld)
Status: "Taking your SQL requests now..."
Tasks: 31 (limit: 9451)
Memory: 64.7M
CGroup: /system.slice/mariadb.service
└─9161 /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.
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. )
Step 2: Install PostfixAdmin on Ubuntu 20.04 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
During the installation, 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.
Then select the default database type: mysql
, if you use MySQL or MariaDB.
Next, choose the default connection method: Unix socket
.
Then choose the default authentication plugin for MySQL/MariaDB.
Press Enter to choose the default database name for PostfixAdmin.
Press Enter to choose the default 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.
Finally, choose the default 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. PostfixAdmin requires a templates_c
directory, so create it.
sudo mkdir /usr/share/postfixadmin/templates_c
We need to give www-data
user read, write and execute permissions on this 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/public
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/public/;
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.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
}
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.4-fpm php7.4-imap php7.4-mbstring php7.4-mysql php7.4-json php7.4-curl php7.4-zip php7.4-xml php7.4-bz2 php7.4-intl php7.4-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 20.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.
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.
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
Argon2 is a fairly strong password scheme. To use it, we need to edit the PostfixAdmin configuration file, which by default is /usr/share/postfixadmin/config.inc.php
, but we can create a separate file (config.local.php
) to store our modifications, so they won’t be overwritten when a new version of PostfixAdmin is installed in the future.
sudo nano /usr/share/postfixadmin/config.local.php
Add the following lines in the file to use Argon2 password scheme.
<?php $CONF['encrypt'] = 'dovecot:ARGON2I'; $CONF['dovecotpw'] = "/usr/bin/doveadm pw -r 5"; if(@file_exists('/usr/bin/doveadm')) { // @ to silence openbase_dir stuff; see https://github.com/postfixadmin/postfixadmin/issues/171 $CONF['dovecotpw'] = "/usr/bin/doveadm pw -r 5"; # debian }
Save and close the file. We can also create a symlink in the /etc/postfixadmin/
directory, just in case PostfixAdmin can’t find the file.
sudo ln -s /usr/share/postfixadmin/config.local.php /etc/postfixadmin/config.local.php
We will configure password scheme for Dovecot in step 10.
Step 7: 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.
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.
After creating the password hash, you need to open the /usr/share/postfixadmin/config.local.php
file and add the setup password hash at the end of the file like below. Of course, you need to use your own password hash.
Next, create the admin account.
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/
Once the superadmin account is created, you can log into PostfixAdmin at postfixadmin.example.com/login.php
.
Step 8: 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 9: 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
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 10: 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/
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 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 at the end of this file, so Dovecot can query user information from MySQL/MariaDB 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
Save and close the file.
Edit the dovecot-sql.conf.ext
file.
sudo nano /etc/dovecot/dovecot-sql.conf.ext
Here is the content that you should have in this file. By default, all lines in this file are commented out, so you can simply copy and paste them at the bottom. 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
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 11: Add Domain and Mailboxes in PostfixAdmin
Log in to PostfixAdmin web interface as the admin. Click the Domain List
tab and select New Domain
to add a domain. You can choose how many aliases and mailboxes are allowed for this domain.
Then click Virtual List
tab and select Add Mailbox
to add a new email address for your domain.
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. Choosenormal 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. Choosenormal password
as the authentication method.
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.
Troubleshooting Tips
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 login 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.
iOS Mail App
If you use the iOS Mail app to log into your mail server and encounter the following error.
You can try to fix it by enforcing SSL encryption, for both SMTP and IMAP.
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.
Change User Password in PostfixAdmin
Users can log into PostfixAdmin at https://postfixadmin.example.com/users/login.php
, then change their passwords.
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 20.04 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 🙂
Hi Xiao,
Thanks for this part 3 of the Email Server. I have followed Part 1 and 2.
I’m new with Email server so just to confirm that I can start a fresh server and install this Part 3 to use Email Server with PostfixAdmin. And following installation from Part 4 – Part 9 for a EMAIL SERVER PRODUCTION?
Can we both install Postfix and PostfixAdmin as follow the full installation from Part1 – Part9 as this site: “https://www.linuxbabe.com/mail-server/setup-basic-postfix-mail-sever-ubuntu”?
Thanks so much.
Kind regards,
Quang
In the “prerequisites” section of this article, there’s a sentence: “It’s required that you have followed part 1 and part 2 of this tutorial series before continuing reading this article.”
Hi Xiao,
Thanks so much for the reply. Yes, I followed till nearly the end of Part 2.
However, I still couldn’t setup the email account with ThunderBird for both user1 & user2. Do not know what I did wrong. I am very careful with your detail instructions with step by step following.
It says: “Thunderbird failed to find the settings for your email account.” I also tried the other Port 993 & 465 with normal password as the Unix Password.
Should I just continue to the Cronjob part at the last session and go on to Part 3 with the virtual Mailbox? Feeling stuck here!
Much appreciated for your support.
Can you tell me what’s your domain name? If you don’t like to show your domain name in public, you can reply in email.
First, you MX record is wrong. You should create MX for your apex domain name like below.

Second, only port 22, 80 and 443 on your server are open.
Hi Xiao,
All working good now. Thanks so much. Learning new stuff every day by making a mistake!!!
Hello Xiao,
Thanks for the quick fix.
– Good news: I have got the email send and receive successfully after Part 2 with Thunderbird! Note: I set up Postfix with this subdomain: https://mail.mysite.com. I got score 8/10 at Mail-Tester.com due to have not set up SPF and DKIM in part 4 and 5 yet.
– Bad news: after Part 3, I stuck at Step 7: Finish the Installation in Web Browser. Go to postfixadmin.example.com/setup.php
I get this error at my website: https://mail.mysite.com – 403 Forbidden – nginx/1.14.0 (Ubuntu)
I think I made a terrible mistake when I started Part 3 by setting up the subdomain: postfixadmin.example.com as the same with postfix: https://mail.mysite.com in Part2 for Postfix.
To clarify my understanding as below:
I need to host one server as server 1: 111.222.333.444 for Part 1+2 with Postfix and point the A records DNS to https://mail.mysite.com?
And host another server as server 2: 555.666.777.888 for Part 3 to set up with PostfixAdmin and point the A records DNS to https://postfixadmin.mysite.com?
What am I doing wrong? Can we install both Postfix and PostfixAdmin in one server with the subdomain https://mail.mysite.com only?
Thanks again for your wonderful support and very quick reply.
Regards,
Quang
You can point mail.example.com and postfixadmin.example.com to the same IP address when creating DNS A record.
Hello Xiao Guoan. I have used your lessons more than once, and it always went well. This time I decided to deploy my own mail server and everything went fine until the end of 3rd lesson. It was necessary using the client to connect to the mailbox that was previously created through postfixadmin, but I did not succeed. I found an error in the logs which says that the passwords from dovecot and sql are different. I understand that dovecot encrypts passwords using ARGON2I, but sql doesn’t. Please tell how to fix it. I am enclosing an excerpt from the log file. I’m using raspberry pi 4, 4Gb Ram and Ubuntu server 20.04.
This line
Indicates dovecot encrypts password with ARGONG2I, but the password stored in the database is encrypted with MD5. Please follow step 6 to configure PostfixAdmin to use Argon2 password scheme.
Then delete the old email address in Postfixadmin and create a new one.
Hello Xiao Guoan. I have completed Step 6 The error was that postfixadmin is not using (config.local.php). I have made the changes you provided in (config.inc.php). I have deleted the mailbox through postfixadmin and created a new one. After this operation my mail client was able to connect, but I ran into a new problem. Given that lesson 3 was completed to the end, the password for logging into the admin panel of postfixadmin was created with the old encryption, and therefore I was no longer able to log into the admin panel of postfixadmin. It seems I will have to remove postfixadmin and reinstall it, but what will happen with the databases that postfixadmin has already created?
You don’t have to reinstall PostfixAdmin. Go to
postfixadmin.example.com/setup.php
to create a new superadmin account. Then delete the old superadmin account.Same system, same problem here!
I think Postfixadmin doesn’t use
config.local.php
becauseconfig.inc.php
try to include it from/etc/postfixadmin/
not from/usr/share/postfixadmin/
…If PostfixAdmin doesn’t use it, you can create a symlink, so PostfixAdmin can find this file.
Hi – great tutorials!
I just tried to use
sudo setfacl -R -m u:www-data:rwx /usr/share/postfixadmin/templates_c/
and ubuntu 20.04 returns: sudo: setfacl: command not found
Maybe you could add the hint to install the acl package
sudo apt install acl
BR
Thanks for the tip.
Hey Xiao
I have finished part 3 tutorial and have come across an error when trying to send mail with thunderbird
An error occurred while sending mail. The mail server responded:
451 4.3.0 : Temporary lookup failure.
Please check the message recipient “Destination email address again” and try again.
I’ve checked the mail log and i believe it to be an error with
warning: proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf lookup error for “Redacted Email Address”
It could be there’s no such email address created in Postfixadmin.
It’s likely that you didn’t enter a correct password for the
postfixadmin
user in the .cf file under /etc/postfix/sql/ directory.Ni hao, Xiao!
I’m still having trouble getting Thunderbird to log into the server. I’ve even gone so far as to wipe the server and start over, but I still can’t log in from Thunderbird. What do you need to help me diagnose the problem?
Read the troubleshooting tips at the end of the article 🙂
Here’s the output from my mail log:
It looks to me like there’s a problem with the encryption of my password. Is there something I need to do with ARGON2I to make it work?
Maybe your config.loca.php file is missing the <?php opening tag.
Add the opening tag at the beginning of this file.
Then you should delete the old email address in PostfixAdmin and create a new one. If you can’t log into Postfixadmin, then go to the setup page https://postfixadmin.example.com/setup.php to create a new superadmin account.
That did it!
This is great stuff!
The last mail server I built was on Ubuntu 16.04 from the instructions at exratione dotcom, and it’s been working great.
But… recently, I decided it was time to move my mail server offsite to a VPS (my ISP won’t give me a PTR record for the static IP I’m paying for).
Just finished with part 3, and Thunderbird logs in and sends mail just fine!
I am following along, and everything seems to be working. I’ve only had a couple of challenges. But they were user error. Your instructions are very good. Log files are your friend (except with letsencrypt, because their logs aren’t that helpful lol).
Just a suggestion: if you’ve got t-shirts or mugs, I’d be thrilled to buy them.
Thanks,
Ron
Generally, this is all working very well. I had a hiccup though with KMail.
“Failed to transport message. Error during SSL handshake: error:1408F10B:SSL routines:ssl3_get_record:wrong version number.”
I think this was because I tried to sign the email. What’s happening here?
The email client can’t establish TLS connection with Postfix or Dovecot. Try a different email client.
But it’s KMail. I really like KMail and so I’d prefer to keep using it. Is there a setting somewhere either in KMail or maybe in my server config files that can enable this connection?
Ahh never mind. My bad. KMail somehow detected the wrong smtp port plus left out the fact i needed username and password for smtp.
I put the correct port and supplied my credentials and it works.
thanks!
Tq for good Tutorial,
how setup Postfix and multiple SSL certificates with postfixadmin? i if have setup 10-200 domain in same machine
Please read this article: How to Host Multiple Mail Domains in PostfixAdmin on Ubuntu
Hello everyone,
I’m trying to prepend the name of the user in the From section to be like this:
– From: My Full Name
Notice that the name is stored in the database the Mailbox table.
Can someone help me to deal with this ?
From: name is controlled in your mail client. (Thunderbird, Roundcube webmail, etc.)
It can be used with relay services?
Yes. Please read this article: How to Set up Postfix SMTP Relay on Ubuntu with Mailjet. As long as you use the Postfix SMTP server, you can follow this guide to set up SMTP relay.
ni hao ma, I read all articles not even one is good for what I need. If you can help me I will be grateful by running a Postifx in browser by using Ubuntu 20.4 along with Sendgrid. I searched all the internet for clues and all youtube and nothing found. Can you help?
You mean you need a web-based admin panel that allows you to configure SMTP relay (sendgrid) without having to edit configuration files from the command line?
ni hao ma xie xie for your reply. All I want is to send/receive/read emails on my Google Cloud platform. I read all articles related to SMTP Integrating with the SMTP API, Postfix etc. I don’t have a start point how to start and what to do to solve this.
I installed Postfix and configured it to relay on Sendgrid. I want to send emails/receive/read them in my web interface. How can I do this? What are the steps do I must follow to enable a web interface of Postfix?
Hello Xiao,
one question, please:
is it possible with this configuration(POstfix-Dovecot-Postfixadmin-Roundcube) to send an automatic message to a user(emailaccount) that they should change their password at a certain period? or for this is necessary to use a control panel like webmin
Thanks!
You can use the Postfixadmin to send a broadcast message to all email accounts on the mail server. (Send email -> Broadcast message).
Unfortunately, the postfixadmin-cli doesn’t support this feature, so you can’t use add this task in Cron, but have to manually broadcast the message in PostfixAdmin web interface.
Hi Xiao, I am new to Linux and tried to follow your tutorial to the letter…….. however, I must have made a typo or missed a step as i can’t get Thunderbird to connect to my server and get the following message and whe I check the status of dovecot.
Your feedback would be appreciated.
The error indicates the
postfixadmin
user can’t log into MySQL/MariaDB database server.Check the
.cf
files under/etc/postfix/sql/
directory. The postfixadmin user password is included in those files. Make sure the password is correct. You can try to login as the postfixadmin user with this command.You will need to enter the password for the postfixadmin user.
You should also check the
/etc/dovecot/dovecot-sql.conf.ext
file, which incudes the postfixadmin user password. Make sure it’s entered correctly.Also note that the postfixadmin password should not contain the # character.
When inspecting /etc/dovecot/dovecot-sql.conf.ext I realised I haven’t replaced “password” in
with the password I have set in step 2 when installing postfixadmin.
When restarting dovecot and postfix the error messages in /var/log/mail.log changed and are now: (I tried to remove a repetitive section of the error message lower down)
Well, “password mismatch” indicates you entered a wrong password in the /etc/dovecot/dovecot-sql.conf.ext file.
Is your mail server able to receive emails from other SMTP servers?
On second thought, it seems you are trying to login from a mail client via IMAP service, but the password for your email address wasn’t entered correctly.
Hi Xiao,
Thanks for your feedback. Your “second thought” regarding the incorrect mail client password pointed me to the answer.
I triple checked all my passwords and all were entered correctly.
It turned out that when I removed the ^ from my email address password the mail client (Thunderbird) was able to connect to the IMAP and SMTP services and I can now send and receive emails.
Now I will start on the other sections of your great tutorials.
Many thanks. Linuxbabe server guides are the gold standard for server setups.
Turns out my 20.04 was missing dependencies for mysql and that was the big deal; to get mysql installed again, filling in the missing dependencies, then purging it all! Reinstalling it all, (because of an intentional bug I allege), then one thing after another until something couldn’t go wrong, then again another zillion of other things were fixed that were very wrong, then finally this wonderful updated single line “connect = host=localhost dbname=postfixadmin user=postfixadmin password=password!” Yes indeed, in which you did update within the last 48 hours or so huh! Well if I may just say so myself, updated so eloquently thank you very much! I did notice, so I am pleased to inform you and everyone else, everything email wise is working as of now again and I couldn’t be more ecstatic today because of all this terrible nonsense completely and totally radically “fixed!” Thank you so very much for your wonderful informative and invaluable information that you freely provided to everyone without any doubt, of course willing to learn and it’s so fun that you make it so much darn fun too!
Have a Great Day,
ZUH
Could you explain how to configure the display of quota usage?
Please read the following article to set up quota in PostfixAdmin.
https://www.linuxbabe.com/mail-server/user-quota-postfixadmin-dovecot
For those with your “ubuntu 20.04LTS LEMP installation” already done do We need to “sudo apt install mysql-server” ? Is it not already installed ?
Thank You so much.
As I said, you only need to run “sudo apt install mysql-server” if you have previously installed MySQL on your server and PostfixAdmin removed the “mysql-server” package from your server.
Hello Xiao
This tutorial is amazing ! thanks for that.
Unfortunately I can’t send email. but receiving it’s ok.
/var/log/mail.log
I don’t understand “unknown user” , everything looks fine in database.
thanks for your help
Best regards
Because you didn’t include the
@domain.tld
part in the username. The username should be your full email address.Thank for your fast reply.
Effectively the @domain.tdl was missing in username (incoming/outgoing) field in Thunderbird.
Like this https://i.imgur.com/aemBKe3.png everything work fine. thank again.
And yes, this is the best tutorial on internet for mail server 🙂
amazing work !
Hi sir
is it possible to remove or edit the previous log and removing sensitive information (ip adress, mail adress) ? please
Sensitive information are now removed.
Hi Xiao,
I have followed your tutorials with great success and have a functioning Postfix/Dovecot/Postfixadmin/Roundcube setup on Ubuntu 20.04, but I’m hitting a problem with the Fetchmail feature in Postfixadmin. Do you have any suggestions based on the error message in the log?
Thank you for your great work,
Eamonn
[Wed Aug 26 15:28:22.934975 2020] [proxy_fcgi:error] [pid 1065] [client xxx.xxx.xxx.xxx:52263] AH01071: Got error ‘PHP message: __LANG.pFetchmail_database_save_success used via read_f, but nothing replaced (value )’, referer: https://postfixadmin.mydomain.com/edit.php?table=fetchmail
Hi Xiao,
Thank you for your great tutorial. I followed them until this step (sudo dpkg-reconfigure postfixadmin) and I got errors as below:
/var/lib/dpkg/info/postfixadmin.prerm: 33: [: =: unexpected operator
/var/lib/dpkg/info/postfixadmin.config: 144: .: Can’t open /usr/share/dbconfig-common/internal/mysql
I checked mysql-server-8.0 is working. there was no mysql in the folder /usr/share/dbconfig-common/internal/
Thanks, John
Hi, I have followed your tutorials series – awesome and thank you! Everything has been working properly, but I encountered an issue with aliases I described here https://sourceforge.net/p/postfixadmin/discussion/676076/thread/6c7c7ce29a/
Could you look at it? Thank you in advance!
Hello Xiao,
first, thanks for this amazing tutorial!
I have a GlassFish application server running on my machine. I have also phppgadmin running on a different port, let say 5555 and configured with apache.
I use Nginx as a Reverse Proxy in front of GlassFish. (Ssl and configs for port 443 hasn’t been set yet.)
So now my problem: Creating a virtual host for PostfixAdmin like described above is not working for me. Visiting http://postfixadmin.my_domain/setup.php I get only a 404 from glassfish.
A DNS A record for the subdomain is set.
What is wrong with my configurations?
Thanks so much.
Kind regards,
Banifou
I solved my Problem by avoiding to create a virtual host for Postfixadmin. Instead, I just used nginx to forward everything from
to
.
Generating another SSL certificate is not necessary.
Everything works fine.
Hello Xiao,
Many thanks for your tutorials!
I have an issue with the encryption ARGON2ID. I have an issue during the authentification:
My file /usr/share/postfixadmin/config.local.php is like this:
I’ve add the authlib just in case, nevertheless it doesn’t work without it ether.
I’ve deleted and created a new email just in case… but this still doesn’t work 🙁
I’m expecting you will tell me to change for ARGON2I… still should we add the
Thanks!
If you use ARGON2ID to generate the password hash in Postfixadmin, you also need to use ARGON2ID in Dovecot.
And also edit
/etc/dovecot/conf.d/10-master.conf
, findARGON2ID is RAM-hungry. Set the virtual memory size to at least 2G.
Hi Xiao,
I did follow all your tutorial since here, I cannot login on postfix, it reloads the login page and on logs I find “…postfixadmin login failed…”
I tried to check and resetup password but I’m stucked. I’m using my gmail account as admin user,.
Please if you have any tip on how to solve it let me know.
Thanks,
Simone
Hi Xiao,
first – mega howto! Thanks a lot for this great job!
It worked from the beginning on my Debian10 box. But I have one question.
Is there a way when I use many differnt domains from different customers, that each domain can use the own domain name for smtp and imap mailserver? Thunderbird send a error about the certificate. In the past was never a problem, but it would be nice when every customer can use his own domain name.
Please read this tutorial: How to Host Multiple Mail Domains in PostfixAdmin on Ubuntu
Hi, thanks.. i found a few hours later.
But now I have the next problem… can you explain how this quota for each user works?
I was use a few snippets from my old system – but it dont work.
Last night I thought I understand this combination after so many years 😀
It will be forever a black hole 🙂
Hi Lucky,
Please read the following article to set up quota in PostfixAdmin.
How to Configure User Quota in Dovecot & PostfixAdmin
Hi! Your tutorial is GREAT. Thank you for helping all of us with our mail servers. I really appreciate it.
However can you please tell what I might did wrong? It seams everything works fine – I can send messages to myself from my mail server and I receive it in Thunderbird, I can sent a messages to gmail account and I see them there too but I cant receive any messages from outside world.
Can you please help? I also new to Linux so I don’t know what should I attach so you can see my mistake.
It’s me again. I’v noticed that my postfix is not listening on port 25. It this a problem?
[email protected]:~$ sudo netstat -lnpt | grep master
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 1059/nginx: master
tcp 0 0 0.0.0.0:587 0.0.0.0:* LISTEN 2136/master
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1059/nginx: master
tcp 0 0 0.0.0.0:465 0.0.0.0:* LISTEN 2136/master
tcp6 0 0 :::443 :::* LISTEN 1059/nginx: master
tcp6 0 0 :::80 :::* LISTEN 1059/nginx: master
Possible causes of not receiving emails
1. Your MX record is wrong.
2. Your mail server hostname doesn’t have DNS A record.
3. Your firewall doesn’t allow incoming connection to port 25.
4. Postfix isn’t listening on the public IP address.
5. Check the mail log (/var/log/mail.log) to find out if there are other errors in your configuration.
Yes, Postfix should be listening on port 25, in order to receive emails.
Of course. Thank you.
I don’t know how but I had commented this line
smtp inet n – y – – smtpd
so postfix wasn’t listening on port 25. This line fixed everything. Thank you!!
Xiao, This is a great writeup! Thanks for posting it.
I do have a question RE: PTR records.
In part one, I built a server and set the PTR record properly, like mail.domain1.com
At the conclusion of part three, if I then add other virtual domains like mail.domain2.com and mail.domain3.com.
How is that handled? Would domain2 and domain3 have issues with other MTA’s not “liking” what the server is set to?
As you stated in part one:
“Many MTAs accept email only if the server is really responsible for a certain domain. You should definitely set a PTR record for your email server so your emails have a better chance of landing in the recipient’s inbox instead of the spam folder.”
I’m sure I’m not explaining myself very well, sorry.
Your rDNS should just be set to one hostname, i.e. the hostname set in Postfix.
You don’t need to set rDNS for all your domains.
Hosted email services like G Suite and Microsoft Exchange Online all use one hostname for a server to send email for their customers.
Emails sent from G Suite users all use google.com in the hostname and emails sent from Microsoft Exchange Online users all use outlook.com in the hostname.
This is also true for other emails service providers like Mailchimp, Mailjet, SendPluse, etc. They all use one hostname for a single server and one IP address has just one rDNS record.
Please read the following article to find out how to get your email into the recipient’s inbox.
How to Stop Your Emails Being Marked as Spam
Hi Xiao,
Im receiving the following error when i try to create a super admin account in postfixadmin.
When check the log files of postfixadmin its telling me the following:
Fatal: Error in configuration file /etc/dovecot/conf.d/10-ssl.conf line 12: ssl_cert: Can’t open file /etc/letsencrypt/live/xxxx.xxxxxx.com/fullchain.
This means that somehow the cert cannot be read from the browser hence causing the error.
Do you know how to solve this?
Are you using Ubuntu 18.04?
Im using Ubuntu 20.10.
It’s because the www-data user doesn’t have permission to read Let’s Encrypt TLS certificate. To fix it, run the following two commands to grant permissions.
Hi Xiao,
Thank you for the response.
Can I install postfixadmin if I am using iredmail solution?
No. They are not compatible, and there’s really no need to install PostfixAdmin when you already have iRedMail.
Some of the options in iredmail are paid only (in the web admin interface) and that’s why I was asking..
Postfixadmin has much less features compared to the iRedAdmin panel in iRedMail.
Hi Xiao,
Thank you for the great tutorials. I have successfully created my mail server with postfix, dovecot and postfixadmin. But after a while I have the problem, that postfixadmin / postfix will not create a user directory for a newly created user in the backend. Login to the new user is fine, but receiving emails does not work. Dovecot gives me the following error:
Error: Namespace ”: Mail storage autodetection failed with home=/var/vmail/mydomain.de/newMailUser/
The directory newMailUser is not existent in the vmail/mydomain.de directory. All existent other mail users can send and receive mails just fine.
When I created the vmail user the user is created but not as system user:
The user `vmail’ already exists, but is not a system user. Exiting.
Deleting and recreating does not change that.
Do you have any suggestions where the source of this problem might be? Thanks in advance.
Regards
Mario
Hi Xiao,
i have ruined my Postfixadmin installation.
Tryed to re-install it but no luck.
I dont have a /etc/postfixadmin/ folder any more, and it is not getting re-created by a reinstall.
Do you have a tip on how to reinstall postfixadmin?.
Regards
thomas
Started all over 🙂
Could you describe a way to use wildcard certificate with postfix/dovecot?
regards
thomas
what if I have some databases in the same server, is this progress will remove any existing DB in the same mysql server?
I thought I’d try ARGON2ID but it doesn’t seem to be working.
I’m getting a password mismatch but comparing the hashes manually shows that they do.
Example:
ARGON2ID(password123) != ‘$argon2id$v=19$m=1048576,t=5,p=1$pvDQ2QrZRU0+auulfxb3Kw$c7hihLU/4zpXlURaN7FuuCRE7zVfGttf2178IcxwTpA’
You can check it with https://argon2.online
Anyway, switching back to ARGON2I is good enough for now.
Edit /etc/dovecot/conf.d/10-master.conf, find
ARGON2ID is RAM-hungry. Set the virtual memory size to at least 2G.
Then restart Dovecot.
Ah… thank you! Sorry for the duplication question just noticed the one 3 months ago
Hi Xiao,
i’ve got things to work now 🙂
Thank you for your great guides.
Is where a way to send a welcome email, to new users, like “here is your new mail box, this is your mail address and pw. You are forced to change pw at first login”?
Regards Thomas
I love your guides. I had postfixadmin working in the past, but with some upgrades I can no longer login.
I’m seeing this in my apache2 logs:
Hi, I have the same problem. If you can find the solution, please feel free to share it. Thank you! 🙂
Except that in my case it is directly linked to a file in “/etc/letsencrypt/live/mail…./privkey.pem”. I will add that I have run the commands:
I had to make sure Dovecot had access to my cert and key, as well as the dh.pem file. And then I could login to Postfixadmin, but some pages threw a Server 500 error and wouldn’t load. I had to add two new settings to my config.inc.php file for database_socket and password_expiry and that fixed those errors. I only really figured out what I needed to do by watching apache2 error logs and some trial and error. I don’t know if my setup is as secure as it should be now sadly.
Hi, I have noticed that after implementing this configuration, when sending messages from Thunderbird, I am getting an issue stating that the message cannot be placed in the “sent” folder. I’m wondering what could have gone wrong, because with earlier confirguration (Postfix + Dovecot) I didn’t have such error. Do you know what could be the cause ?
Below I put the exact message:
“The message was sent but a copy of the message has not been placed in the Sent folder due to network or file access errors”
postfixadmin messed up with my existing environment i set up days ago. i already installed lnmp stack, after installing postfixadmin(apt install postfixadmin), mysql server could not start, and mariadb, php7.4, apache2 was installed by postfixadmin
i should install from source instead
You can remove MariaDB and Apache. Then restart MySQL server and Nginx.
I’ve been follow your tutorials with great results so far, but in this tutorial, everything seems to go right, sending email from outlook, setting up account using email clients, everything except receiving an incoming email. I’ve looked into /var/log/mail.log, and found that the email that is supposed to be delivered has the following msg:
any suggestions? thanks in advance for your help.
From the mail log, I can see that Postfix can’t connect to
dovecot-lmtp
. Make suredovecot-lmtpd
is installed.Edit the Dovecot main configuration file.
Add lmtp to the supported protocols.
Save and close the file. Then edit the Dovecot 10-master.conf file.
Change the lmtp service definition to the following.
Restart Postfix and Dovecot.
PS: The above process has been explained in Part 2 of this tutorial series.
Thanks a lot! really helped. Now everything is working fine.
Hi Xiao,
thanks for your tutorials! I got stuck 🙁
Before I started this chapter I was able to send and receive emails. But now Im able to send email locally and externally, receive email locally, but not externally. External mail server error log:
No entry in postfix log about receive email.
Do you have any idea? Thank you in advance.
SOLVED:
I blocked port 25 in firewall by mistake
solution:
sudo ufw allow 25/tcp
Hi,
i have followed the tutorial series up to this part(3) and have a fully functioning email server that works with virtual users now. YEY!!
Now the question is:
Is there a way to migrate users and their current passwords from an old mail server that uses local user accounts instead of virtual, to this new and shiny email server i just created? Also, old server doesnt use database in anyway.
I know i can copy/paste emails/folders from old server’s “/home/user/maildir” to new server’s “/var/vmail/domain/user/maildir” and it works, if i manually create a new user from postfixadmin GUI, but i havent managed to found a way to do what i asked above.
I hope i dont have to manually create 50+ accounts via postfixadmin and set new passwords for all users and mail them to each user individually :/
Hello Xiao,
– My Server will all steps of your tutorials as been working for months.
– Since the latest upgrade of Dovecot, accessing to postfixadmin is no longer available. When I enter email and password nothing happens and no error is giving.
– Here it goes the error at log of postfixadmin:
—
Kindest Regards,
Ale
It’s probably because you renewed the TLS certificate, so the
www-data
user doesn’t have permission to read Let’s Encrypt TLS certificate again. To fix it, run the following two commands to grant permissions.You can add the two commands to your Cron job so you don’t need to worry about it again.
– Thank You so much. That was the solution.
– The new dovecot version as something to do with the problembecause in my case /etc/letsencrypt/ was root:root since the installation day. The certificate was renewed 42 days ago and since than I already used postfixadmin.
—
Kindest Regards,
Ale
Hi Xiao Guoan, excellent tutorial, I got stuck creating the Postfixadmin Administrator, it started giving me error “setup password not specified correctly” and I have not been able to move forward. i configured the file /usr/share/postfixadmin/config.local.php, as you specified as follows:
create the Symlink:
.
I’m really sorry I couldn’t do it right and I’m asking you for some mistake made by me, thank you very much for your help.
Translated with www.DeepL.com/Translator (free version)
Hello, the problem has been solved, thank you very much.
I’ve just tried reinstalling Postfixadmin using PHP8.0 but all I’m getting is the white screen of death. Any suggestions?
Switch back to PHP7.4. The PostfixAdmin in the Ubuntu 20.04 repository currently doesn’t support PHP8.0.
Thanks for the great tutorial so far. I wanted to ask if postfixadmin can be installed into a web server that is different from my mail server? I’d like to avoid installing a webserver on my mail server, and just manage the mail server from a different server. Is this possible? Thanks again.
d
Yes, you can install PostfixAdmin on a separate host, but you need to set up MariaDB to allow remote connection and enable TLS encryption in MariaDB. Then edit PostfixAdmin configuration files to make it connect to a remote MariaDB database.
If you are worried about web server security, you can follow the tutorial below to secure your email server from hacking.
How to Secure Email Server Against Hacking with VPN (Debian/Ubuntu)
It explains how you can set up self-hosted VPN server and block public access to the web server. This is my preferred way to secure an email server, so I don’t have to separate the web server from the email server.
Got everything to work, except user folders are missing
/var/mail, /var/vmail and /~ are all completely empty (but exist).
When I open the mailbox on Thunderbird, I see only `Inbox` but it’s always empty. I sent a couple of e-mails from my gmail to my mail server and still nothing. Gmail reports my messages as successfully sent. What could be the issue?
Creating and deleting the mailbox via postfixadmin did not work.
What’s the value of
auth_username_format
in/etc/dovecot/conf.d/10-auth.conf
?Currently it’s
%u
, the default was%Lu
as far as I remember.Dovecot 2.3.7.2 (3c910f64b)
Postfix mail_version 3.4.13
What’s the value of
virtual_transport =
in /etc/postfix/main.cf file? And can you see any error messages in /var/log/mail.log when sending emails from Gmail to your own domain?Thank you a lot for helping me with this.
virtual_transport = lmtp:unix:private/dovecot-lmtp
Upon sending a message, no, but I did see the following in this file:
(DOMAIN.COM is replaced with my actual domain).
The same error is also seen, but prefixed with
Error: lmtp-server: conn unix:pid=10...
Maybe I have misconfigured something, where can I look to change this setting?
Oh, yes, I see the problem. Instead of adding
mail_home = /var/vmail/%d/%n/
, I set the mail_location to that. My bad, will fix, restart and retry.Yes! That fixed it. Thank you a lot for publishing this tutorial and for helping me debug this again, I will make a donation.
Everything works well so far except I have reached step 7 using the web-based install. Every time I try to connect the only thing I get is “This site can’t be reached. postfixadmin.domain.com refused to connect” from google chrome and I am unable to start anything at all. Is there any port that needs to be opened that I don’t know about? Domain is set correctly from what I can tell.
Go to https://dnsmap.io/ to check if the DNS record is propagated to the Internet. Also, make sure TCP port 80 and 443 are open on your server.
Hello Xiao,
The mail setup document is really good. The post you wrote was very instructive for me. Thank you for your hard work.
I have applied all of the documents of Part 1, part 2, part 3, part 4, part 5, “How to Host Multiple Mail Domains in PostfixAdmin on Ubuntu”, “Install Roundcube Webmail on Ubuntu 20.04 with Apache / Nginx”. All works except connecting from outlook android app.
After I made all the settings in the second part, I was able to connect to the server via the outlook android app and from other mails. Mail sending and receiving everything was working fine. I am using ssl ports. imap 993 smtp 465.
After I made the settings in the third part, I started unable to connect to the server from outlook android app. But I can connect from local mail program on my huawei phone. This may have happened due to what setting. After registering virtual users to the database and changing the encryption method? Or another setting?
Has anyone experienced this problem and solved it?
Ubuntu 20.04.2, Nginx, MariaDB, PHP
Ufw Status
———————–
gmail original post
---------------------------------
/var/log/mail.log
------------------------
Thank you for this beautiful series of email server tutorials! I’ve been having really good luck with everything until I tried adding postfixadmin so I can use virtual mailboxes/users. I’m using postgres instead of mariadb but that shouldn’t make much a difference.
Anyway, the error I get is: “Sender address rejected: not owned by user “. I tried logging the sql queries and it appears the username is getting cut off from the domain even though I have “auth_username_format = %u” so I think it’s not finding the alias. Here are the SQL queries when sending an email from the postfixadmin account “[email protected]” to an alias of that account “[email protected]”:
SELECT username AS user,password FROM mailbox WHERE username = ‘[email protected]’ AND active=’1′
SELECT goto FROM alias WHERE address=’example.com’ AND active = ‘1’
SELECT maildir FROM mailbox WHERE username=’example.com’ AND active = ‘1’
SELECT goto FROM alias WHERE address=’example.com’ AND active = ‘1’
SELECT maildir FROM mailbox WHERE username=’example.com’ AND active = ‘1’
SELECT goto FROM alias WHERE address=’example.com’ AND active = ‘1’
SELECT maildir FROM mailbox WHERE username=’example.com’ AND active = ‘1’
Shouldn’t it be looking up the full ‘[email protected]’ from the alias table? It’s using ‘%s’ in the config file to form the sql query. Any help would be greatly appreciated! Thank you!
I figured it out! I had this in master.cf under
so I replaced it with the database as the source and it worked!
My question is, I see you have “smtpd_sender_login_maps” in main.cf so what’s the difference between having it in main.cf or under submission in master.cf? When I completely remove it from master.cf I get the error again so now I have it both files.
Nevermind my last question. I had put smtpd_sender_login_maps in main.cf by mistake for testing so you don’t have that.
But why did I need to include it in master.cf? I don’t think your tutorial has that option under submission. Thanks again!
Hello Xiao,
For the past week I am looped at connecting email address to Thunderbird. I am getting the error “unable to login at server. probably wrong configuration username or password”.
I followed Part 1, 2 and 3 and as far as I know everything is configured except SSL certificate.
Why do I get password mismatch at the logs below?
auth-worker(27358): sql([email protected],127.0.0.1,): Password mismatch
Apr 13 21:44:40 postfix dovecot[2731]: auth-worker(27358): Debug: sql([email protected],127.0.0.1,): ARGON2I(user123) != ‘$1$d34950b9$No8iJiz>
Apr 13 21:44:40 postfix dovecot[2731]: auth: Debug: sql([email protected],127.0.0.1,): Finished passdb lookup
Apr 13 21:44:40 postfix dovecot[2731]: auth: Debug: auth([email protected],127.0.0.1,): Auth request finished
Apr 13 21:44:40 postfix dovecot[2731]: auth-worker(27358): Debug: sql([email protected],127.0.0.1,): Finished passdb lookup
Apr 13 21:44:40 postfix dovecot[2731]: auth-worker(27358): Debug: conn unix:auth-worker (pid=27271,uid=113): auth-worker: Finished
Apr 13 21:44:42 postfix dovecot[2731]: auth: Debug: client passdb out: FAIL 1 [email protected]
Apr 13 21:44:42 postfix dovecot[2731]: imap-login: Disconnected (auth failed, 1 attempts in 2 secs): user=, method=PLAIN, rip=127.0.0.1, lip>
Apr 13 21:45:40 postfix dovecot[2731]: auth-worker(27358): Debug: conn unix:auth-worker (pid=27271,uid=113): Disconnected: Connection closed (fd=-1)
The “postfixadmin/focal,now 3.2.1-3” installation on my raspberry pi, seems to be some sort of metapackage that automatically installs Apache, as well as many Apache extensions and plugins (php etc.). Since I am running Nginx, after the installation, I had to do “sudo apt purge *apache” and “sudo apt purge apache*”. This seemed to uninstall and clean up MOST of the unneccessary stuff that the postfixadmin automatically installed. My question is, is there a better way of doing this, or possibly preventing the postfixadmin package from installing unnecessary packages in the first place?
Step 2: Install PostfixAdmin on Ubuntu 20.04 Server
For “choose the default database administrative user”, My default database admin user (on ubuntu 20.04), show up as “root”.
However, in your picture in the tutorial, your default database administrative user shows up as “debian-sys-maint”. Which “default”
database user name shoudl I be using?; “debian-sys-maint” or “root”?
I just want to mention that I ran into some issues with the SQL queries in following files when using Postgresql instead of MySQL/MariaDB:
– /etc/postfix/sql/mysql_virtual_alias_domain_maps.cf
– /etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
– /etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf
It’s this part of the CONCAT in the query that cause issues:
It caused some issues with sending emails to external addresses and took some diving into the log files to figure out. The fix was adding single quotes like in the other parts where active was checked against 1.
Thought it could save someone the time to figure it out themselves if they run into the same issue as I did.