How to Install PostfixAdmin on an Existing iRedmail Server (Ubuntu)

In previous articles, we discussed how to quickly set up your own email server on Ubuntu with iRedmail. However, the free iRedMail edition doesn’t allow you to create aliases. If you want to create alias addresses, alias domains, and catch-all alias, but don’t want to upgrade to the premium iRedmail-Pro edition, then you can install PostfixAdmin on your iRedmail server.

PostfixAdmin Features

  • Manage mailboxes, virtual domains, and aliases
  • alias domains (forwarding one domain to another with recipient validation)
  • users can manage their own mailbox (change alias, password, and vacation message)

Alias is a very effective tool to combat spam. You don’t want to give your real email address to every website/newsletter you sign up for. If one of them leaks your data, then you will be haunted by spammers until your change your email address, which is a pain in itself. Luckily, you can use create an alias for each website/newsletter you sign up for. If you receive spam at one alias address, simply delete that alias address and your real email address won’t be affected.

PostfixAdmin allows you to create alias for the same domain name, and create an alias for an email address hosted on other domains. An alias can also have multiple target addresses, which means if the alias address receives an email, that email can be redirected to multiple email addresses.

Requirements

PostfixAdmin should be installed after iRedMail, so make sure you have set up iRedmail server.

Step 1: Install PostgreSQL Database Server on Ubuntu

PostfixAdmin is written in PHP and requires a database (MySQL/MariaDB, PostgreSQL, or SQLite). This article will use the PostgreSQL database. Enter the following command to install PostgreSQL on Ubuntu.

sudo apt install postgresql postgresql-contrib

After it’s installed, PostgreSQL database server will automatically start and listens on 127.0.0.1:5432, as can be shown with:

sudo ss -lnpt | grep 5432

Sample output:

LISTEN 0      244        127.0.0.1:5432       0.0.0.0:*    users:(("postgres",pid=24074,fd=5))

If you don’t see any output in the command line window, then PostgreSQL isn’t running. Start it with this command:

sudo systemctl start postgresql

To enable PostgreSQL to automatically start at boot time, run

sudo systemctl enable postgresql

If it still refuses to start, you need to check the log file under /var/log/postgresql/ to find out what went wrong.

Step 2: Download PostfixAdmin on Ubuntu Server

Log into your mail server, then download PostfixAdmin codes onto your server. Go to PostfixAdmin Gitbub page to download the latest version. You can use the wget tool to download it from the command line. The download link is always available in the format below. If a new version comes out, simply replace 3.3.11 with the new version number.

sudo apt install wget

wget https://github.com/postfixadmin/postfixadmin/archive/postfixadmin-3.3.11.tar.gz

Once downloaded, extract the archive to /var/www/ directory and rename it to postfixadmin.

sudo mkdir -p /var/www/

sudo tar xvf postfixadmin-3.3.11.tar.gz -C /var/www/

sudo mv /var/www/postfixadmin-postfixadmin-3.3.11 /var/www/postfixadmin

Step 3: Setting Up Permissions

PostfixAdmin requires a templates_c directory, and the web server needs read and write access to this directory. So run the following commands.

sudo mkdir -p /var/www/postfixadmin/templates_c

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

Starting with Dovecot 2.3.11, the web server user needs permission to read Let’s Encrypt TLS certificate in order to do password hashing. Run the following two commands to grant permissions.

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

Step 4: Create a Database and User for PostfixAdmin

Log into PostgreSQL as the postgres user.

sudo -u postgres -i psql

Create the postfixadmin database. I named it postfixadmin, but you can use whatever name you like. (Don’t leave out the semicolon.)

CREATE DATABASE postfixadmin;

Create a database user (postfixadmin) and set a password. Replace postfixadmin_password with your preferred password. Note that the password should not contain the # character, or you might not be able to log in later.

CREATE USER postfixadmin WITH PASSWORD 'postfixadmin_password';

Grant permissions to the database user.

ALTER DATABASE postfixadmin OWNER TO postfixadmin; 

GRANT ALL PRIVILEGES ON DATABASE postfixadmin TO postfixadmin;

Press Ctrl+D to log out of the PostgreSQL console.

Then run the following command to test if you can log in to PostgreSQL as postfixadmin user.

psql -h 127.0.0.1 -d postfixadmin -U postfixadmin -W

Press Ctrl+D to log out.

Step 5: Configure PostfixAdmin

The default PostfixAdmin configuration file is config.inc.php. We need to create a config.local.php file and add custom configurations.

sudo nano /var/www/postfixadmin/config.local.php

Add the following lines in the file, so PostfixAdmin can connect to PostgreSQL database. Replace postfixadmin_password with the real PostfixAdmin password created in step 4.

<?php
$CONF['configured'] = true;
$CONF['database_type'] = 'pgsql';
$CONF['database_host'] = 'localhost';
$CONF['database_port'] = '5432';
$CONF['database_user'] = 'postfixadmin';
$CONF['database_password'] = 'postfixadmin_password';
$CONF['database_name'] = 'postfixadmin';
$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. Note that we will use the ARGON2I password scheme. 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

Step 6: Create Nginx Virtual Host for PostfixAdmin

Create a virtual host for PostfixAdmin.

sudo nano /etc/nginx/sites-enabled/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 /var/www/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 127.0.0.1:9999;
        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 7: 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 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.
  • --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.
  • --email: Email used for registration and recovery contact.
  • -d flag is followed by a list of domain names, separated by comma. You can add up to 100 domain names.

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

postfixadmin ubuntu https

Step 8: Launch the Web-Based Setup Wizard

Go to postfixadmin.example.com/setup.php to run the web-based setup wizard. First, you need to create a setup password for PostfixAdmin.

postfixadmin generate setup password

After creating the password hash, PostfixAdmin will display a line like below.

$CONF['setup_password'] = '$2y$10$58fIawuOb5y538RMBol/DOoqv2bJ7zhPRzRO.4Xq7MLeQJHmaFwF2';

You need to open the config.local.php file.

sudo nano /var/www/postfixadmin/config.local.php

Add the line displayed on the PostfixAdmin setup page to the end of the file like below.

ubuntu postfixadmin setup password hash

After saving the file, you need to refresh the PostfixAdmin setup page and enter the setup password again, then create the admin account. Please don’t use a Gmail, Yahoo Mail, or Microsoft email address for the admin account, or you might not be able to log in later. Use an email address on your own domain. You can create the email address later in PostfixAdmin.

postfixadmin create superadmin account

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

Password Hashing - attempted to use configured encrypt backend (dovecot:ARGON2I) triggered an error: /usr/bin/doveadm pw -r 5 failed, 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/

Sometimes, you might also need to run the following command to fix this error.

sudo setfacl -R -m u:www-data:rwx /var/run/dovecot/stats-reader /var/run/dovecot/stats-writer

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

postfixadmin login page debian

Step 9: Configure Postfix to Use PostgreSQL Database

To make Postfix 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 PostgreSQL map support for Postfix by installing the postfix-pgsql package.

sudo apt install -y postfix-pgsql

Then edit the Postfix main configuration file.

sudo nano /etc/postfix/main.cf

Find the following lines.

virtual_mailbox_domains =
    proxy:mysql:/etc/postfix/mysql/virtual_mailbox_domains.cf

relay_domains =
    $mydestination
    proxy:mysql:/etc/postfix/mysql/relay_domains.cf

virtual_mailbox_maps =
    proxy:mysql:/etc/postfix/mysql/virtual_mailbox_maps.cf

virtual_alias_maps =
    proxy:mysql:/etc/postfix/mysql/virtual_alias_maps.cf
    proxy:mysql:/etc/postfix/mysql/domain_alias_maps.cf
    proxy:mysql:/etc/postfix/mysql/catchall_maps.cf
    proxy:mysql:/etc/postfix/mysql/domain_alias_catchall_maps.cf

By default, Postfix will lookup user information from the databases created by iRedmail.

  • 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.
  • relay_domains points to files that tell Postfix if an email should be relayed to another SMTP server.

Now we need to add the PostgreSQL database (pgsql) to the list.

virtual_mailbox_domains =
    proxy:mysql:/etc/postfix/mysql/virtual_mailbox_domains.cf
    proxy:pgsql:/etc/postfix/pgsql/virtual_domains_pgsql.cf

relay_domains =
    $mydestination
    proxy:mysql:/etc/postfix/mysql/relay_domains.cf
    proxy:pgsql:/etc/postfix/pgsql/relay_domains_pgsql.cf

virtual_mailbox_maps =
    proxy:mysql:/etc/postfix/mysql/virtual_mailbox_maps.cf
    proxy:pgsql:/etc/postfix/pgsql/virtual_mailbox_pgsql.cf

virtual_alias_maps =
    proxy:mysql:/etc/postfix/mysql/virtual_alias_maps.cf
    proxy:mysql:/etc/postfix/mysql/domain_alias_maps.cf
    proxy:mysql:/etc/postfix/mysql/catchall_maps.cf
    proxy:mysql:/etc/postfix/mysql/domain_alias_catchall_maps.cf
    proxy:pgsql:/etc/postfix/pgsql/virtual_alias_pgsql.cf

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

sudo mkdir -p /etc/postfix/pgsql/

Create the virtual_domains_maps.cf file.

sudo nano /etc/postfix/pgsql/virtual_domains_pgsql.cf

Add the following content. Replace postfixadmin_password with the postfixadmin database password you set in step 4.

user = postfixadmin
password = postfixadmin_password
hosts = localhost
dbname = postfixadmin
#query = SELECT domain FROM domain WHERE domain='%s' AND active = true
#optional query to use when relaying for backup MX
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = false and active = true

Create the virtual_mailbox_maps.cf file.

sudo nano /etc/postfix/pgsql/virtual_mailbox_pgsql.cf

Add the following content.

user = postfixadmin
password = postfixadmin_password
hosts = localhost
dbname = postfixadmin
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = true

Create the virtual_alias_maps.cf file.

sudo nano /etc/postfix/pgsql/virtual_alias_pgsql.cf

Add the following content.

user = postfixadmin
password = postfixadmin_password
hosts = localhost
dbname = postfixadmin
query = SELECT goto FROM alias WHERE address='%s' AND active = true

Create the relay_domains.cf file.

sudo nano /etc/postfix/pgsql/relay_domains_pgsql.cf

Add the following content.

user = postfixadmin
password = postfixadmin_password
hosts = localhost
dbname = postfixadmin
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = true

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/pgsql/*
sudo setfacl -R -m u:postfix:rx /etc/postfix/pgsql/

Restart Postfix.

sudo systemctl restart postfix

Step 10: Configure Dovecot to Use PostgreSQL Database

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

sudo apt install -y dovecot-pgsql

Then edit the Dovecot config file.

sudo nano /etc/dovecot/dovecot.conf

Find the following lines.

# Virtual mail accounts.
userdb {
    args = /etc/dovecot/dovecot-mysql.conf
    driver = sql
}
passdb {
    args = /etc/dovecot/dovecot-mysql.conf
    driver = sql
}

By default, Dovecot is configured to query user info from the database created by iRedmail. Now we need to add the PostgreSQL database to the list.

# Virtual mail accounts.
userdb {
    args = /etc/dovecot/dovecot-mysql.conf
    driver = sql
}
passdb {
    args = /etc/dovecot/dovecot-mysql.conf
    driver = sql
}

userdb {
    args = /etc/dovecot/dovecot-pgsql.conf.ext
    driver = sql
}
passdb {
    args = /etc/dovecot/dovecot-pgsql.conf.ext
    driver = sql
}

Save and close the file. Next, create the dovecot-pgsql.conf.ext file.

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

Here is the content that you should have in this file.  Replace postfixpassword with the postfixadmin password you set in Step 4.

driver = pgsql

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

default_pass_scheme = ARGON2I

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

user_query = SELECT '/var/vmail/vmail1/' || maildir AS home, 2000 AS uid, 2000 AS gid FROM mailbox WHERE username = '%u' AND active = true

iterate_query = SELECT username AS user FROM mailbox

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

When Dovecot restarts, it will reset the file permissions on /var/run/dovecot/stats-reader and /var/run/dovecot/stats-writer. And we will need to run the following command again.

sudo setfacl -R -m u:www-data:rwx /var/run/dovecot/stats-reader /var/run/dovecot/stats-writer

To run it automatically, we can create a systemd service.

sudo nano /etc/systemd/system/dovecot-setfacl.service

Add the following lines to this file.

[Unit]
Description=Grant permission to the nginx user on Dovecot files
After=dovecot.service

[Service]
Type=oneshot
ExecStartPre=/bin/sleep 10
ExecStart=/bin/bash -c '/usr/bin/setfacl -R -m u:www-data:rwx /var/run/dovecot/stats-reader /var/run/dovecot/stats-writer'

[Install]
WantedBy=multi-user.target

Save and close the file. Then edit the Dovecot systemd config file.

sudo mkdir -p /etc/systemd/system/dovecot.service.d/

sudo nano /etc/systemd/system/dovecot.service.d/override.conf

Add the following lines to this file. This means after Dovecot restarts, it will invoke the dovecot-setfacl service.

[Unit]
Wants = dovecot-setfacl.service

Save and close the file. Then reload systemd.

systemctl daemon-reload

Restart Dovecot.

sudo systemctl restart dovecot

Step 11: Add Domain and Mailboxes in PostfixAdmin

Hint: You can also add domain and mailboxes in the iRedamin admin panel, but I recommend using PostfixAdmin, so all email addresses and aliases can be managed in one place.

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.

debian postfixadmin add domain

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

debian postfixadmin Create a new 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.
thunderbird-mail-client-configuration

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

Set Up Cron Job

Edit root user’s crontab file.

sudo crontab -e

Add the following line in this file to allow the www-data user to read certificate files.

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

Save and close the file.

Wrapping Up

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: 8 Average: 5]

6 Responses to “How to Install PostfixAdmin on an Existing iRedmail Server (Ubuntu)

  • William B
    2 years ago

    Brilliant as usual just minor issue users created in Iredadmin can log into both client and SOGO but users added to postfix admin can only use client software. SOGO fails

  • Alexander
    2 years ago

    Hi Xiao,
    i have problems creating the admin account on the PostfixAdmin setup page after entering the setup password again.

    i followed this tutorial until end of section “Step 10: Configure Dovecot to Use PostgreSQL Database”.

    https://postfixadmin./setup.php shows still errors like in the image attached.

    Do you have an idea what could be wrong?

    Regards, Alexander

  • Alexander
    2 years ago

    I managed to solve all problems with:

    sudo apt-get install php-pgsql
    sudo apt-get install php-sqlite3
    sudo apt-get install php-imap
    sudo systemctl reload nginx

    And then reload https://postfixadmin./setup.php

  • Is it possilbe to set up postfix with iRedMail in one mysql instance? Can you please explain how to do it?

  • cantIIT
    1 year ago

    What is the meaning with Password Expires under the domain section? It’s set up to 365 days by default.
    I want to say mine is almost reaching 365 days since creation. Any idea on what happens? Also, can I disable password expiration by setting it up to 0 days?

    The email server is in production. Kinda scared of touching anything and bringing it down.

  • Hi
    Can you create setup with mysql ?

Leave a Comment

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

The maximum upload file size: 2 MB. You can upload: image. Links to YouTube, Facebook, Twitter and other services inserted in the comment text will be automatically embedded. Drop file here