The Perfect Server - Ubuntu 20.04 with Apache, PHP, MariaDB, PureFTPD, BIND, Postfix, Dovecot and ISPConfig 3.2

This tutorial shows the installation of an Ubuntu 20.04 (Focal Fossa) web hosting server with Apache 2.4, Postfix, Dovecot, Bind, and PureFTPD to prepare it for the installation of ISPConfig 3.2. The resulting system will provide a Web, Mail, Mailinglist, DNS, and FTP Server.

ISPConfig is a web hosting control panel that allows you to configure the following services through a web browser: Apache or Nginx web server, Postfix mail server, Courier or Dovecot IMAP/POP3 server, MariaDB as MySQL replacement, BIND or MyDNS nameserver, PureFTPd, SpamAssassin, ClamAV, and many more. This setup covers the installation of Apache (instead of Nginx), BIND (instead of MyDNS), and Dovecot (instead of Courier).

1. Preliminary Note

In this tutorial, I use the hostname with the IP address and the gateway  These settings might differ for you, so you have to replace them where appropriate.  Before proceeding further you need to have a basic minimal installation of Ubuntu 20.04 as explained in the tutorial.

The commands in this tutorial have to be run with root permissions. To avoid adding sudo in front of each command, you'll have to become root user by running:

sudo -s

before you proceed.

2. Edit /etc/apt/sources.list and Update your Linux Installation

Edit /etc/apt/sources.list. Comment out or remove the installation CD from the file and make sure that the universe and multiverse repositories are enabled. It should look like this afterwards:

nano /etc/apt/sources.list
# See for how to upgrade to
# newer versions of the distribution.
deb focal main restricted
# deb-src focal main restricted

## Major bug fix updates produced after the final release of the
## distribution.
deb focal-updates main restricted
# deb-src focal-updates main restricted

## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team. Also, please note that software in universe WILL NOT receive any
## review or updates from the Ubuntu security team.
deb focal universe
# deb-src focal universe
deb focal-updates universe
# deb-src focal-updates universe

## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team, and may not be under a free licence. Please satisfy yourself as to
## your rights to use the software. Also, please note that software in
## multiverse WILL NOT receive any review or updates from the Ubuntu
## security team.
deb focal multiverse
# deb-src focal multiverse
deb focal-updates multiverse
# deb-src focal-updates multiverse

## N.B. software from this repository may not have been tested as
## extensively as that contained in the main release, although it includes
## newer versions of some applications which may provide useful features.
## Also, please note that software in backports WILL NOT receive any review
## or updates from the Ubuntu security team.
deb focal-backports main restricted universe multiverse
# deb-src focal-backports main restricted universe multiverse

## Uncomment the following two lines to add software from Canonical's
## 'partner' repository.
## This software is not part of Ubuntu, but is offered by Canonical and the
## respective vendors as a service to Ubuntu users.
# deb focal partner
# deb-src focal partner

deb focal-security main restricted
# deb-src focal-security main restricted
deb focal-security universe
# deb-src focal-security universe
deb focal-security multiverse
# deb-src focal-security multiverse

Then run

apt-get update

to update the apt package database and

apt-get upgrade

to install the latest updates (if there are any). If you see that a new kernel gets installed as part of the updates, you should reboot the system afterwards:


3. Change the Default Shell

/bin/sh is a symlink to /bin/dash, however we need /bin/bash, not /bin/dash. Therefore, we do this:

dpkg-reconfigure dash

Use dash as the default system shell (/bin/sh)? <-- No

If you don't do this, the ISPConfig installation will fail.

4. Disable AppArmor

AppArmor is a security extension (similar to SELinux) that should provide extended security. In my opinion, you don't need it to configure a secure system, and it usually causes more problems than advantages (think of it after you have done a week of troubleshooting because some service wasn't working as expected, and then you find out that everything was ok, only AppArmor was causing the problem). Therefore, I disable it (this is a must if you want to install ISPConfig later on).

We can disable it like this:

service apparmor stop
update-rc.d -f apparmor remove
apt-get remove apparmor apparmor-utils

5. Synchronize the System Clock

It is a good idea to synchronize the system clock with an NTP (network time protocol) server over the Internet when you run a physical server. In case you run a virtual server then you should skip this step. Just run

apt-get -y install ntp

and your system time will always be in sync.

6. Install Postfix, Dovecot, MariaDB, rkhunter, and binutils

For installing postfix, we need to ensure that sendmail is not installed and running. To stop and remove sendmail run this command:

service sendmail stop; update-rc.d -f sendmail remove

The error message:

Failed to stop sendmail.service: Unit sendmail.service not loaded.

Is ok, it just means that sendmail was not installed, so there was nothing to be removed.

Now we can install Postfix, Dovecot, MariaDB (as MySQL replacement), rkhunter, and binutils with a single command:

apt-get -y install postfix postfix-mysql postfix-doc mariadb-client mariadb-server openssl getmail4 rkhunter binutils dovecot-imapd dovecot-pop3d dovecot-mysql dovecot-sieve sudo patch

You will be asked the following questions:

General type of mail configuration: <-- Internet Site
System mail name: <--

It is important that you use a subdomain as "system mail name" like or and not a domain that you want to use as email domain (e.g. yourdomain.tld) later.

Next, open the TLS/SSL and submission ports in Postfix:

nano /etc/postfix/

Uncomment the submission and smtps sections as follows - add the line -o smtpd_client_restrictions=permit_sasl_authenticated,reject to both sections and leave everything thereafter commented:

submission inet n       -       y       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
-o smtpd_tls_auth_only=yes -o smtpd_client_restrictions=permit_sasl_authenticated,reject # -o smtpd_reject_unlisted_recipient=no # -o smtpd_client_restrictions=$mua_client_restrictions # -o smtpd_helo_restrictions=$mua_helo_restrictions # -o smtpd_sender_restrictions=$mua_sender_restrictions # -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject # -o milter_macro_daemon_name=ORIGINATING smtps inet n - y - - smtpd -o syslog_name=postfix/smtps -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes -o smtpd_client_restrictions=permit_sasl_authenticated,reject # -o smtpd_reject_unlisted_recipient=no # -o smtpd_client_restrictions=$mua_client_restrictions # -o smtpd_helo_restrictions=$mua_helo_restrictions # -o smtpd_sender_restrictions=$mua_sender_restrictions # -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject # -o milter_macro_daemon_name=ORIGINATING [...]

NOTE: The whitespaces in front of the "-o .... " lines are important!

Restart Postfix afterward:

service postfix restart

We want MySQL to listen on all interfaces, not just localhost. Therefore, we edit /etc/mysql/mariadb.conf.d/50-server.cnf and comment out the line bind-address =

nano /etc/mysql/mariadb.conf.d/50-server.cnf
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address           =


Now we set a root password in MariaDB. Run:


You will be asked these questions:

Enter current password for root (enter for none): <-- press enter
Set root password? [Y/n] <-- y
New password: <-- Enter the new MariaDB root password here
Re-enter new password: <-- Repeat the password
Remove anonymous users? [Y/n] <-- y
Disallow root login remotely? [Y/n] <-- y
Reload privilege tables now? [Y/n] <-- y

Set the password authentication method in MariaDB to native so we can use PHPMyAdmin later to connect as root user:

echo "update mysql.user set plugin = 'mysql_native_password' where user='root';" | mysql -u root

Edit the file /etc/mysql/debian.cnf and set the MYSQL / MariaDB root password there twice in the rows that start with password.

nano /etc/mysql/debian.cnf

The MySQL root password that needs to be added is shown in red. In this example, the password is "howtoforge". Replace the word "howtoforge" with the password that you have set for the MySQL root user with the mysql_secure_installation command.

# Automatically generated for Debian scripts. DO NOT TOUCH!
host = localhost
user = root
password = howtoforge
socket = /var/run/mysqld/mysqld.sock
host = localhost
user = root
password = howtoforge
socket = /var/run/mysqld/mysqld.sock
basedir = /usr

Open the file /etc/security/limits.conf with an editor:

nano /etc/security/limits.conf

and add these lines at the end of the file.

mysql soft nofile 65535
mysql hard nofile 65535

Next, create a new directory /etc/systemd/system/mysql.service.d/ with the mkdir command.

mkdir /etc/systemd/system/mysql.service.d/

and add a new file inside:

nano /etc/systemd/system/mysql.service.d/limits.conf

paste the following lines into that file:


Save the file and close the nano editor.

Then we reload systemd and restart MariaDB:

systemctl daemon-reload
service mariadb restart

Now check that networking is enabled. Run

netstat -tap | grep mysql

The output should look like this:

[email protected]:~# netstat -tap | grep mysql
tcp6       0      0 [::]:mysql              [::]:*                  LISTEN      51836/mysqld
[email protected]:~#

7. Install Amavisd-new, SpamAssassin, and Clamav

To install amavisd-new, SpamAssassin, and ClamAV, we run

apt-get -y install amavisd-new spamassassin clamav clamav-daemon unzip bzip2 arj nomarch lzop cabextract apt-listchanges libnet-ldap-perl libauthen-sasl-perl clamav-docs daemon libio-string-perl libio-socket-ssl-perl libnet-ident-perl zip libnet-dns-perl postgrey

The ISPConfig 3 setup uses amavisd which loads the SpamAssassin filter library internally, so we can stop SpamAssassin to free up some RAM:

service spamassassin stop
update-rc.d -f spamassassin remove

To start ClamAV use:

service clamav-daemon start

The following error can be ignored on the first run of freshclam.

ERROR: /var/log/clamav/freshclam.log is locked by another process
ERROR: Problem with internal logger (UpdateLogFile = /var/log/clamav/freshclam.log).

8. Install Apache, PHP, phpMyAdmin, FCGI, SuExec, Pear

Apache 2.4, PHP 7.4, phpMyAdmin, FCGI, suExec, and Pear can be installed as follows:

apt-get -y install apache2 apache2-doc apache2-utils libapache2-mod-php php7.4 php7.4-common php7.4-gd php7.4-mysql php7.4-imap phpmyadmin php7.4-cli php7.4-cgi libapache2-mod-fcgid apache2-suexec-pristine php-pear libruby libapache2-mod-python php7.4-curl php7.4-intl php7.4-pspell php7.4-sqlite3 php7.4-tidy php7.4-xmlrpc php7.4-xsl memcached php-memcache php-imagick php7.4-zip php7.4-mbstring php-soap php7.4-soap php7.4-opcache php-apcu php7.4-fpm libapache2-reload-perl

You will see the following question:

Web server to reconfigure automatically: <-- apache2

Enable PHPMyAdmin in Apache2

Configure database for phpmyadmin with dbconfig-common? <-- Yes
DBConfig Common

MySQL application password for phpmyadmin: <-- Press enter

MySQL application password

Then run the following command to enable the Apache modules suexec, rewrite, ssl, actions, and include (plus dav, dav_fs, and auth_digest if you want to use WebDAV):

a2enmod suexec rewrite ssl actions include cgi alias proxy_fcgi
a2enmod dav_fs dav auth_digest headers

To ensure that the server cannot be attacked through the HTTPOXY vulnerability, I will disable the HTTP_PROXY header in apache globally. Create a new httpoxy.conf file with nano:

nano /etc/apache2/conf-available/httpoxy.conf

Paste this content into the file:

<IfModule mod_headers.c>
    RequestHeader unset Proxy early

Enable the config file by running:

a2enconf httpoxy

Restart Apache afterward:

service apache2 restart

If you want to host Ruby files with the extension .rb on your websites created through ISPConfig, you must comment out the line application/x-ruby rb in /etc/mime.types:

nano /etc/mime.types
#application/x-ruby                             rb

(This is needed only for .rb files; Ruby files with the extension .rbx work out of the box.)

Restart Apache afterwards:

service apache2 restart

9. Install Let's Encrypt

ISPConfig 3.2 has built-in support for the free SSL Certificate Authority Let's encrypt. The Let's Encrypt function allows you to create free SSL Certificates for your website in ISPConfig.

Now we will add support for Let's encrypt.

apt-get install certbot

10. Install Mailman

ISPConfig allows you to manage (create/modify/delete) Mailman mailing lists. If you want to make use of this feature, install Mailman as follows:

apt-get -y install mailman

Select at least one language, e.g.:

Languages to support: <-- en (English)
Missing site list <-- Ok

The error 'Job for mailman.service failed because the control process exited with error code.' can be ignored for now.

Before we can start Mailman, a first mailing list called mailman must be created:

newlist mailman

[email protected]:~# newlist mailman
Enter the email of the person running the list:
 <-- admin email address, e.g. [email protected]
Initial mailman password: <-- admin password for the mailman list
To finish creating your mailing list, you must edit your /etc/aliases (or
equivalent) file by adding the following lines, and possibly running the
`newaliases' program:

## mailman mailing list
mailman:              "|/var/lib/mailman/mail/mailman post mailman"
mailman-admin:        "|/var/lib/mailman/mail/mailman admin mailman"
mailman-bounces:      "|/var/lib/mailman/mail/mailman bounces mailman"
mailman-confirm:      "|/var/lib/mailman/mail/mailman confirm mailman"
mailman-join:         "|/var/lib/mailman/mail/mailman join mailman"
mailman-leave:        "|/var/lib/mailman/mail/mailman leave mailman"
mailman-owner:        "|/var/lib/mailman/mail/mailman owner mailman"
mailman-request:      "|/var/lib/mailman/mail/mailman request mailman"
mailman-subscribe:    "|/var/lib/mailman/mail/mailman subscribe mailman"
mailman-unsubscribe:  "|/var/lib/mailman/mail/mailman unsubscribe mailman"

Hit enter to notify mailman owner...
 <-- ENTER

[email protected]:~#

Open /etc/aliases afterwards...

nano /etc/aliases

... and add the following lines:

## mailman mailing list
mailman:              "|/var/lib/mailman/mail/mailman post mailman"
mailman-admin:        "|/var/lib/mailman/mail/mailman admin mailman"
mailman-bounces:      "|/var/lib/mailman/mail/mailman bounces mailman"
mailman-confirm:      "|/var/lib/mailman/mail/mailman confirm mailman"
mailman-join:         "|/var/lib/mailman/mail/mailman join mailman"
mailman-leave:        "|/var/lib/mailman/mail/mailman leave mailman"
mailman-owner:        "|/var/lib/mailman/mail/mailman owner mailman"
mailman-request:      "|/var/lib/mailman/mail/mailman request mailman"
mailman-subscribe:    "|/var/lib/mailman/mail/mailman subscribe mailman"
mailman-unsubscribe:  "|/var/lib/mailman/mail/mailman unsubscribe mailman"



afterward and restart Postfix:

service postfix restart

Finally, we must enable the Mailman Apache configuration:

ln -s /etc/mailman/apache.conf /etc/apache2/conf-available/mailman.conf

This defines the alias /cgi-bin/mailman/ for all Apache vhosts, which means you can access the Mailman admin interface for a list at http://<vhost>/cgi-bin/mailman/admin/<listname>, and the web page for users of a mailing list can be found at http://<vhost>/cgi-bin/mailman/listinfo/<listname>.

Under http://<vhost>/pipermail you can find the mailing list archives.

Activate the configuration with:

a2enconf mailman

Restart Apache afterward:

service apache2 restart

Then start the Mailman daemon:

service mailman start

11. Install PureFTPd and Quota

PureFTPd and quota can be installed with the following command:

apt-get -y install pure-ftpd-common pure-ftpd-mysql quota quotatool

Edit the file /etc/default/pure-ftpd-common...

nano /etc/default/pure-ftpd-common

... and make sure that the start mode is set to standalone and set VIRTUALCHROOT=true:


Now we configure PureFTPd to allow FTP and TLS sessions. FTP is a very insecure protocol because all passwords and all data are transferred in clear text. By using TLS, the whole communication can be encrypted, thus making FTP much more secure.

If you want to allow FTP and TLS sessions, run

echo 1 > /etc/pure-ftpd/conf/TLS

In order to use TLS, we must create an SSL certificate. I create it in /etc/ssl/private/, therefore I create that directory first:

mkdir -p /etc/ssl/private/

Afterwards, we can generate the SSL certificate as follows:

openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout /etc/ssl/private/pure-ftpd.pem -out /etc/ssl/private/pure-ftpd.pem

Country Name (2 letter code) [AU]: <-- Enter your Country Name (e.g., "DE").
State or Province Name (full name) [Some-State]:
<-- Enter your State or Province Name.
Locality Name (eg, city) []:
<-- Enter your City.
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
<-- Enter your Organization Name (e.g., the name of your company).
Organizational Unit Name (eg, section) []:
<-- Enter your Organizational Unit Name (e.g. "IT Department").
Common Name (eg, YOUR name) []:
<-- Enter the Fully Qualified Domain Name of the system (e.g. "").
Email Address []:
<-- Enter your Email Address.

Change the permissions of the SSL certificate:

chmod 600 /etc/ssl/private/pure-ftpd.pem

Then restart PureFTPd:

service pure-ftpd-mysql restart

Edit /etc/fstab. Mine looks like this (I added ,usrjquota=quota.user,,jqfmt=vfsv0 to the partition with the mount point /):

nano /etc/fstab
# /etc/fstab: static file system information.
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
# <file system> <mount point> <type> <options> <dump> <pass>
/dev/mapper/server1--vg-root / ext4 errors=remount-ro,usrjquota=quota.user,,jqfmt=vfsv0 0 1
/dev/mapper/server1--vg-swap_1 none swap sw 0 0
/dev/fd0 /media/floppy0 auto rw,user,noauto,exec,utf8 0 0

To enable quota, run these commands:

mount -o remount /
quotacheck -avugm
quotaon -avug

 Which will show the following output:

[email protected]:/tmp# quotacheck -avugm
quotacheck: Scanning /dev/mapper/server1--vg-root [/] done
quotacheck: Cannot stat old user quota file //quota.user: No such file or directory. Usage will not be subtracted.
quotacheck: Cannot stat old group quota file // No such file or directory. Usage will not be subtracted.
quotacheck: Cannot stat old user quota file //quota.user: No such file or directory. Usage will not be subtracted.
quotacheck: Cannot stat old group quota file // No such file or directory. Usage will not be subtracted.
quotacheck: Checked 13602 directories and 96597 files
quotacheck: Old file not found.
quotacheck: Old file not found.
[email protected]:/tmp# quotaon -avug
/dev/mapper/server1--vg-root [/]: group quotas turned on
/dev/mapper/server1--vg-root [/]: user quotas turned on

12. Install BIND DNS Server

BIND can be installed as follows:

apt-get -y install bind9 dnsutils haveged

Enable and start the haveged Daemon:

systemctl enable haveged
systemctl start haveged

13. Install Vlogger, Webalizer, AWStats and GoAccess

Vlogger, Webalizer, and AWStats can be installed as follows:

apt-get -y install vlogger webalizer awstats geoip-database libclass-dbi-mysql-perl

Installing the latest GoAccess version directly from GoAccess repository:

echo "deb $(lsb_release -cs) main" | sudo tee -a /etc/apt/sources.list.d/goaccess.list
wget -O - | sudo apt-key --keyring /etc/apt/trusted.gpg.d/goaccess.gpg add -
sudo apt-get update
sudo apt-get install goaccess

Open /etc/cron.d/awstats afterwards...

nano /etc/cron.d/awstats

... and comment out everything in that file:


#*/10 * * * * www-data [ -x /usr/share/awstats/tools/ ] && /usr/share/awstats/tools/

# Generate static reports:
#10 03 * * * www-data [ -x /usr/share/awstats/tools/ ] && /usr/share/awstats/tools/

14. Install Jailkit

Jailkit is used to jailed shell users and cronjobs in ISPConfig. Install jailkit with apt:

apt-get -y install jailkit

15. Install fail2ban and UFW

This is optional but recommended because the ISPConfig monitor tries to show the log:

apt-get -y install fail2ban

To make fail2ban monitor PureFTPd and Dovecot, create the file /etc/fail2ban/jail.local:

nano /etc/fail2ban/jail.local
enabled  = true
port     = ftp
filter   = pure-ftpd
logpath  = /var/log/syslog
maxretry = 3

enabled = true
filter = dovecot
action = iptables-multiport[name=dovecot-pop3imap, port="pop3,pop3s,imap,imaps", protocol=tcp]
logpath = /var/log/mail.log
maxretry = 5

enabled  = true
port     = smtp
filter   = postfix
logpath  = /var/log/mail.log
maxretry = 3

Restart fail2ban afterwards:

service fail2ban restart

To install the UFW firewall, run this apt command:

apt-get install ufw

16. Install Roundcube Webmail

To install Roundcube Webmail, run:

apt-get -y install roundcube roundcube-core roundcube-mysql roundcube-plugins roundcube-plugins-extra javascript-common libjs-jquery-mousewheel php-net-sieve tinymce

The installer might ask the following questions:

Configure database for roundcube with dbconfig-common? <-- Yes
MySQL application password for roundcube: <-- Press enter

Don't worry if you do not get these questions and a warning about the ucf script, that's ok.

The ucf warning that you will get on the shell can be ignored, it has no negative impact on the installation.

Then edit the RoundCube apache configuration file.

nano /etc/apache2/conf-enabled/roundcube.conf

and remove the # in front of the Alias line, then add the second Alias line for /webmail and add the line "AddType application/x-httpd-php .php" right after the "<Directory /var/lib/roundcube>" line:

# Those aliases do not work properly with several hosts on your apache server
# Uncomment them to use it or adapt them to your configuration
Alias /roundcube /var/lib/roundcube
Alias /webmail /var/lib/roundcube [...] <Directory /var/lib/roundcube> AddType application/x-httpd-php .php [...]

And restart apache

service apache2 restart

Then edit the RoundCube configuration file:

nano /etc/roundcube/

and change the default host to localhost:

$config['default_host'] = 'localhost';

and the SMTP server to:

$config['smtp_server'] = 'localhost';


$config['smtp_port']  = 25;

This prevents that Roundcube will show server name input field in the login form.

17. Install ISPConfig 3.2

We will use the ISPConfig 3.2 stable build here.

cd /tmp 
wget -O ispconfig.tar.gz
tar xfz ispconfig.tar.gz
cd ispconfig3*/install/

The next step is to run

php -q install.php

This will start the ISPConfig 3 installer. The installer will configure all services like Postfix, Dovecot, etc. for you.

# php -q install.php

_____ ___________ _____ __ _ ____
|_ _/ ___| ___ \ / __ \ / _(_) /__ \
| | \ `--.| |_/ / | / \/ ___ _ __ | |_ _ __ _ _/ /
| | `--. \ __/ | | / _ \| '_ \| _| |/ _` | |_ |
_| |_/\__/ / | | \__/\ (_) | | | | | | | (_| | ___\ \
\___/\____/\_| \____/\___/|_| |_|_| |_|\__, | \____/
__/ |

>> Initial configuration
Operating System: Ubuntu 20.04.1 LTS (Focal Fossa)
Following will be a few questions for primary configuration so be careful.
Default values are in [brackets] and can be accepted with <ENTER>.
Tap in "quit" (without the quotes) to stop the installer.

Select language (en,de) [en]: <-- Hit Enter
Installation mode (standard,expert) [standard]: <-- Hit Enter
Full qualified hostname (FQDN) of the server, eg server1.domain.tld []: <-- Hit Enter
MySQL server hostname [localhost]: <-- Hit Enter
MySQL server port [3306]: <-- Hit Enter
MySQL root username [root]: <-- Hit Enter
MySQL root password []: <-- Enter your MySQL root password
MySQL database to create [dbispconfig]: <-- Hit Enter
MySQL charset [utf8]: <-- Hit Enter
Configuring Postgrey
Configuring Postfix
Generating a 4096 bit RSA private key
writing new private key to 'smtpd.key'
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [AU]: <-- Enter 2 letter country code
State or Province Name (full name) [Some-State]: <-- Enter the name of the  state
Locality Name (eg, city) []: <-- Enter your city
Organization Name (eg, company) [Internet Widgits Pty Ltd]: <-- Enter company name or press enter
Organizational Unit Name (eg, section) []: <-- Hit Enter
Common Name (e.g. server FQDN or YOUR name) []: <-- Enter the server hostname, in my case:
Email Address []: <-- Hit Enter
Configuring Mailman
Configuring Dovecot
Configuring Spamassassin
Configuring Amavisd
Configuring Getmail
Configuring BIND
Configuring Jailkit
Configuring Pureftpd
Configuring Apache
Configuring vlogger
Configuring Metronome XMPP Server
writing new private key to 'localhost.key'
Country Name (2 letter code) [AU]: <-- Enter 2 letter country code
Locality Name (eg, city) []: <-- Enter your city
Organization Name (eg, company) [Internet Widgits Pty Ltd]: <-- Enter company name or press enter
Organizational Unit Name (eg, section) []: <-- Hit Enter
Common Name (e.g. server FQDN or YOUR name) []: <-- Enter the server hostname, in my case:
Email Address []: <-- Hit Enter
Configuring Ubuntu Firewall
Configuring Fail2ban
[INFO] service OpenVZ not detected
Configuring Apps vhost
Installing ISPConfig
ISPConfig Port [8080]:
Admin password [admin]:
Do you want a secure (SSL) connection to the ISPConfig web interface (y,n) [y]: <-- Hit Enter
Generating RSA private key, 4096 bit long modulus
e is 65537 (0x10001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [AU]: <-- Enter 2 letter country code
State or Province Name (full name) [Some-State]: <-- Enter the name of the  state
Locality Name (eg, city) []: <-- Enter your city
Organization Name (eg, company) [Internet Widgits Pty Ltd]: <-- Enter company name or press enter
Organizational Unit Name (eg, section) []: <-- Hit Enter
Common Name (e.g. server FQDN or YOUR name) []: <-- Enter the server hostname, in my case:
Email Address []: <-- Hit Enter
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: <-- Hit Enter
An optional company name []: <-- Hit Enter
writing RSA key

Symlink ISPConfig LE SSL certs to postfix? (y,n) [y]:  <-- Hit Enter
Symlink ISPConfig LE SSL certs to pureftpd? Creating dhparam file takes some times. (y,n) [y]:  <-- Hit Enter
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time

Configuring DBServer
Installing ISPConfig crontab
no crontab for root
no crontab for getmail
Detect IP addresses
Restarting services ...
Installation completed.

The installer automatically configures all underlying services, so there is no manual configuration needed.

Afterward you can access ISPConfig 3 under http(s):// or http(s):// (HTTP or HTTPS depends on what you chose during installation). Log in with the username admin and the password admin (you should change the default password after your first login):

ISPConfig Login on Ubuntu 18.04 LTS

ISPConfig 3.2 dashboard

The system is now ready to be used.

18. Virtual machine image download of this tutorial

This tutorial is available as ready to use virtual machine image in ovf/ova format that is compatible with VMWare and Virtualbox. The virtual machine image uses the following login details:

SSH / Shell Login

Username: administrator
Password: howtoforge

This user has sudo rights.

ISPConfig Login

Username: admin
Password: howtoforge

MySQL Login

Username: root
Password: howtoforge

The IP of the VM is, it can be changed in the file /etc/netplan/01-netcfg.yaml. Please change all the above passwords to secure the virtual machine.

19. Links

Share this page:

Suggested articles

126 Comment(s)

Add comment


By: ustoopia

Allright!! I already have a freshly installed server waiting for exactly this moment! Thanks!

By: ustoopia

Perhaps an idea for you to include somewhere in the setup guide that we need to perform the command : "apt install patch" before starting the ispconfig installer. I received an error message after entering the command " php -q install.php" that said "The patch command is missing. Install patch command and start installation again." After searching the forum here I found the solution so now the installer was able to start succesfully.

By: Sahin


Can be done in Ubuntu 20

Installed Nginx, MySQL and bind completely

By: till

A separate installation of the patch command was not required on my systems. But I can add it.

By: Hammers Thor

Outstanding, and I mean OUTSTANDING tutorial. I have posted to GAB and Brighteon. Social (sorry, don't do facebook or twitter).

Thank you!

By: Tom

OMG this is such great tutorial. I can tell already I'm going to learn a ton just by going through the motions of setting it up. Thanks for such detailed work. 

By: Tom

Am I missing something? It says there's a link to download the image, but for the life of me I can't find any download link for that.

By: till

The download link is in the menu on the right side of the page, near the top. Right below the big red download Icon.

By: Zoltan Kiss

Hi! The download does not work.

By: till

Try the download again, it works fine now.

By: jakobdam

Wow - this is an EXTREMELY well made tutorial! Thanks a lot for the time and professionalism put into this - it made able to do something I thought was much, much harder - and indeed, it would've been (for me) if not for this tutorial.


Just a few sidenotes if any future visitors should encounter the same issues as me:


1) quota setup: My fstab file didn't look remotely like yours:

/dev/mapper/server1--vg-root / ext4 errors=remount-ro,usrjquota=quota.user,,jqfmt=vfsv0

Instead, mine was mapped with UUIDs. It now says:

UUID=62a4ff85-72b8-4b49-9aaa-e66f919b4b8d / ext4 usrjquota=quota.user,,jqfmt=vfsv0 0 0


2) In my case, ispconfig3 worked fine but I couldn't log in with admin/admin. So I entered mariadb and changed the password for the admin user:

Log on to the mariadb as root, enter password when prompted:

mysql -u root -p

Then enter the ispconfig db:


use dbispconfig;

Now update admin with the password admin:

UPDATE sys_user SET passwort = md5('admin') WHERE username = 'admin';

And write "quit" to exit, and now the login admin/admin works.

By: jakobdam

Additional to my earlier comment; phpmyadmin didn't work for me. This was the solution in my case:

ln -s /etc/phpmyadmin/apache.conf/etc/apache2/conf-available/phpmyadmin.conf

a2enconf phpmyadmin

service apache2 restart

By: till

@jakobdam The Reason that you were not able to access phpmyadmin is that you missed to enable it during installation. See screenshots in chapter 8, you must navigate to the apache config option using tab key and enable the apache option by using the space key on your keyboard, so that the * shows up in the option field. If you miss that, then phpmyadmin will not work and you'll have to enable it later manually.


Regarding ispconfig password, the password is what you see in the installer, it is not admin, unless you enter the word admin.


The fstab file is different depending on your base setup, so it's normal that it does not look exactly as in the guide. But there are unlimited possible alterations, so only one is shown in the guide.

By: aadursun

where are the downloads, can't find links??

By: till

This has been answered in the comments already, here again: The download link is in the menu on the right side of the page, near the top. Right below the big red download Icon.

By: Bob White

I've been getting a lot of spam lately where the body of the message is base64 encoded. Once the body is decoded, it contains URLs that contain a server (e.g., What I would like to do is discard any message containing the text "hubspotfree".

I can add it to Postfix's "body_checks" file, but that requires putting it in three times because it's base4 encoded. I tried editing the Spamassassin config files in /etc/spamassassin, but that doesn't seem to have any effect - I expect because it's using amavis, not SA. I tried entering into ISPConfig - with /hubspotfree/ as the text to match and DISCARD as the action.  Still didn't catch a test message.

How is this supposed to work? Where do I put the stuff I want filtered or flagged as spam?



By: till

@Bob: Please post support questions in the ISPConfig forum here at howtoforge.

By: Kart Mitchel

Everything is excellent in the manual. some details like .. quota settings were not of major importance as well Errors were encountered while processing:


E: Sub-process / usr / bin / dpkg returned an error code (1)

fix it by removing # $ myhostname = "abc.def.ghi";

# Qualified Domain Name (FQDN) and remove the # at the beginning of the line.


#$ myhostname = "abc.def.ghi";

everything worked as expected ... thanks


By: till

@Kart Michael: There is no need to edit that file, if amavis fails with this error, then it means that you did not configure the server hostname properly. As a wrong server hostname setup will give you more errors later when you start using the system, I highly recommend that you undo the change you made in the amavisd config file and instead fox your /etc/hostname file and server hostname, so that the command 'hostname -f' returns the correct FQDN hostname.

By: Maik Kramer

Great tutorial. Everything is working fine, but I stuck for many days now with the mailserver. I made the installiation on Alibaba Cloud in Hong Kong and I can not send emails (250 authenification fail) and I do not recieve emails; permanent error (SMTP error from remote mail server after RCPT TO:<[email protected]>:  550 5.1.1 <[email protected]>: Recipient address rejected:  User unknown in local recipient table). It is the first time I have to set up a mailserver, an I thought it was done with this tutorial, but I see now thats not. May be someone can give me some links, topics or help what I still have to do, to get the mailserver working based on this tutorial. I read many other tutorial now and even one for Alibaba Cloud (How to Setup Email Server on Ubuntu 16.04 Alibaba ECS), but they all go different ways, from what I saw in this tutorial. thank you in advance

By: till

@Maik: The mail server is completely set up when you finished this guide, you just have to add your domain and mailboxes in ISPConfig. It is good that you asked for help instead of following another guide as mixing guides is a guarantee that you will mess up your setup. Please post your problem in the ISPConfig forum here at howtoforge if you need further help.

By: Maik Kramer

@Till: Thank you! Can it be possible, that I have a mix up with the IP addresses? I got 2 IP addresses from Alibaba Cloud: one they call internet IP and the other privat IP. Now I saw, that in ISPConfig under Server Config the used IP address is the privat IP and also under Sites/WebDomain it showed only the privat IP, which I used then, to save that site. Now, after I added in the DNS the Internet IP I can change under Sites/Webdomain to the internet IP, with the effect, that, if I go through the webbrowser to my site, it do not show the client side, but instead the index site under /var/www/html/. My question is, do the installation have to use the internet IP address or the privat IP address. One other thing I would like to ask you, because it is irritating for me. I have DNS Settings for the Domain in Alibaba Cloud under manage DNS and I have DNS Settings in ISPConfig. Do I have to make the same DNS settings in both, or only some in Alibaba DNS and the rest in ISPConfig. I hope the questions are not to basic or worse. I just need to know, where I have to look/search and I will get it working, but in the moment I am realy in the dark. Thank you, Maik

By: till

@Maik: Please use the forum to ask for help. the comments section is not a good place to discuss individual setup questions. Thanks!

By: Goedendag

Hi, I get the "SMTP Error (250): Authentication failed." when trying to send a mail via roundcube. Any ideas on how to fix this?

By: till

@Goedendag: Please use the forum to ask for help. the comments section is not a good place to discuss individual setup questions. Thanks!

By: Ghostshell3301

It would be nice to add the correct username and password for the OVA root:howtoforge is not working !!!

By: till

@Ghostshell3301: The correct username and password is mentioned in the tutorial already. The username is 'administrator' and the password is 'howtoforge'. As you might know, you can not login as root user on Ubuntu systems, you always use the username of a user with sudo privileges, in this case, the user 'administrator' to log in, then run 'sudo -s' to become root.

By: Ghostshell3301

@Till sorry I'm a (not) the RTFM dude ... So I used the pdf file with the download link :$ One must follow orders :) For only once I did read the RTFM and I'm awarded with this :p Problem solved (BTW I'm using the Perfect server from version Debian 6 until now with great pleasure and love the docs) KUDOS !

By: agustintommasi

Hello, is there any way to put APS Installer in ISPConfig 3.2? 

By: till, the source of APS packages, has been discontinued in 2019. And an application installer that has no recent packages to be installed anymore makes not much sense. That's why the APS installer is hidden in the menu, the code is still there in 3.2, but it makes not much sense to activate it.

By: Mark Rhyne

Hi, I get the "SMTP Error (250): Authentication failed." when trying to send a mail via roundcube. Any ideas on how to fix this?

If you ran the update script this becomes an issue. In the Roundcube config file change the port back to 25 not 587 then it works again.

Maybe its fixed now, maybe my advise is bad but it worked for me.

By: Newland Futures

Been using these tutorials for 15+ years.  A very long time.  Thank you again for the great work and easy installation.  Use this for a runbook and out the large number of servers I have installed using these tutorials only once or twice have I had issues.

I was able to download the nightly build, but the tar.gz file was corrupted and several files did not extract properly.  So I simply git cloned the repository and switched the branch to the 3.2b3 branch and off to the races.  Thanks!

By: decentris

Hi Till,

I have to add to the praises of my predecessors. The new tutorial is again top, as we are used to from you and your team. I just have one question: When configuring the "postfix" - file, I stumbled upon a line "#  -o smtpd_tls_auth_only=yes" in the option-settings of

submission inet n - y - - smtpd

which is not displayed in the respective config example above. Is it save to keep this commented out or could it be a security improvement to activate "smtpd_tls_aut_only"?Thanks for your valued input.Best,Johannes

By: till

Hello Johannes, it might indeed be better to activate that line to prevent users from sending AUTH details on submission port without TLS at all. There are (hopefully) no mail clients anymore today which have a problem with that setting. I'll update the tutorial and add that line.

By: aplusdesigners

I LOVE this tutorial. It has been a few years since I setup my own server and this is just what the doctor ordered. One question though. My ISP blocks port 25 for mail sending, so how do we specify a port in the setup to send the mail? Thanks a bunch for such a well documented process.

By: till

@aplusdesigners: You cans et the relay host in ISPConfig under System > server config. Append the port like this to the relay server name:




where 123 is the port.

By: Indar

Hi Till,

Nice tutorial, but I got a problem with step-7 (install amavisd-new, SpamAssassin, and ClamAV). After executing the command (apt-get -y install amavisd-new spamassassin ...), I got error messages:

Setting up amavisd-new (1:2.11.0-6.1ubuntu1) ...Creating/updating amavis user account...Job for amavis.service failed because the control process exited with error code.See "systemctl status amavis.service" and "journalctl -xe" for details....Oct 14 11:06:03 pakcarik systemd[1]: Failed to start LSB: Starts amavisd-new mailfilter.dpkg: error processing package amavisd-new (--configure):  installed amavisd-new package post-installation script subprocess returned error exit status 1 ...

Errors were encountered while processing:    amavisd-new E: Sub-process /usr/bin/dpkg returned an error code (1)

I just ignored those errors, and continue the steps. When I tried to run the ClamAV by executing: freshclam 

then I got there errors:

ERROR: /var/log/clamav/freshclam.log is locked by another processERROR: Problem with internal logger (UpdateLogFile = /var/log/clamav/freshclam.log).ERROR: initialize: libfreshclam init failed.ERROR: Initialization error!

Did I miss something? I followed your tutorial carefully after a fresh install of Ubuntu 20.04 server. My server has an Intel i9-9900K with 64GB DDR4 and 2TB SSD. Any suggestion? Many thanks!

By: phanky5

Roundcube doesn't appear to be properly configured out of the box. IMAP and SMTP hosts are both configured as localhost. This causes issues with authentication. Localhost should be replaced with the fully qualified domain name of your email server in /etc/roundcube/ $config['default_host'] = 'tls://'; $config['smtp_server'] = 'tls://'; @till maybe you want to add this to the tutorial. I see a few people already ran into the same issue.

By: leonardo.saracini

In section 7 before freshclam better do a

systemctl stop clamav-freshclam.service

By: TonyG

Trivial typo:

"The MySQL root password that needs to be added is shown in read"

should be red.

By: Mark

Hi Till, three questions: (1) I've just installed Ubunu 20.10 and noticed it has some location changes, for example Grub is not located at /etc/defaults/grub as in 20.04. Would this ISPConfig installation be possible on 20.10, do you know?

(2) Is the virtual image compatible with KVM?

(3) How would either installation allow for update/upgrade of the various components?

By: Sigh

In order to log into MariaDB to secure it, we'll need the current

password for the root user.  If you've just installed MariaDB, and

you haven't set the root password yet, the password will be blank,

so you should just press enter here.


Enter current password for root (enter for none):

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)


Enter current password for root (enter for none):


Tried both no password and the root user's password on three different cloud containers, all gave the same results. 

By: Jaume

I'm trying to change the apache tls restriction to make only tls 1.2 and 1.3 available, but I can't understand why I can't change. I put in the Apache directives of the site (options tab) the lines: SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 -TLSv1.2 SSLHonorCipherOrder off SSLSessionTickets off trying to change the lines... and the test always tells me that tls1.0 and 1.1 is enabled...what can I do? regards!

By: till

Apache does not support it to set TLS levels by vhost, it will always use the lowest setting from any vhost in all other vhosts. This means you have to change all vhosts and the global TLS settings from Ubuntu.

By: Tom

This tutorial not only saved me a TON of time trying to figure it all out on my own, but I understand so much more. This was such a great way to learn so many different web/server based technologies. Thank you SO MUCH for creating such master pieces. I can't tell you how excited I've been to have this up and running. I don't think i could have done it without this writeup.

By: Jaume

Hi Till, thanks to question regarding tls settings... what is the correct way to change all these settings? editing vhots manually? 

By: francoisPE

I don't know why, I don't have last line in my /etc/mysql/debian.cnf (basedir) # Automatically generated for Debian scripts. DO NOT TOUCH! [client] host = localhost user = root password = howtoforge socket = /var/run/mysqld/mysqld.sock [mysql_upgrade] host = localhost user = root password = howtoforge socket = /var/run/mysqld/mysqld.sock basedir = /usr ------ May be that is why I have a mistake in file " proxy:mysql:\/etc\/postfix/mysql-virtual...dbname " 2 wrong \ : I removed and it works...

By: Ken C.

Thank you for a job well done. Best installation yet for ISPConfig with all server applications on my VPS; so far working without a hitch.

By: Henrique Moraes


Its very beautifull.

Thanks a lot!

By: kazuki

thank you. waiting for nginx perfect server

By: Tom


Installation went well, I can recieve emails but I can not send, did i miss something?


By: Pablo

I'm sure you need to uncomment a line in /etc/postfix/

By: francoisPE

In below packages list, there is "apache lib for python" : libapache2-mod-python.

apt-get -y install apache2 apache2-doc apache2-utils libapache2-mod-php php7.4 php7.4-common php7.4-gd php7.4-mysql php7.4-imap phpmyadmin php7.4-cli php7.4-cgi libapache2-mod-fcgid apache2-suexec-pristine php-pear libruby libapache2-mod-python php7.4-curl php7.4-intl php7.4-pspell php7.4-sqlite3 php7.4-tidy php7.4-xmlrpc php7.4-xsl memcached php-memcache php-imagick php7.4-zip php7.4-mbstring php-soap php7.4-soap php7.4-opcache php-apcu php7.4-fpm libapache2-reload-perl


This lib is quite old. It was replaced by libapache2-mod-wsgi first. And now, by libapache2-mod-wsgi-py3 for python3.

I suggest to modify that line of tuto in order to avoid people setting python 2.7.17 instread of python 3.8...


By: till

@francoisPE: The libs are required to be installed in the way that is described in the guide, so do not alter the commands if you like to get a working setup. The changes you suggested will result in a non-functional system as mod-wsgi is not a direct replacement and also not supported by ISPConfig at all.

By: francoisPE

@Till, libapache2-mod-python is incompatible with python3... it automatically load python2.7 and make it 'default'. When having libapache2-mod-python, it is impossible to have libapache2-mod-wsgi-py3. Python3 is incompatible with most of the modern web site using python... For me, this is a matter of concern.

I don't know if you are able to move ispconfig to libapache2-mod-wsgi-py3. It would be really great!

By: ofer

Pelase add


without fixing the host name amavis want start


By: till

@ofer: there is no change in that file needed on correctly installed systems and you should not change that file, so the first step is undo your change and then fix your system hostname. If you had to change that file to start amavis, then you have not configured the hostname of your system correctly before you started to install ISPConfig. Go back to Ubuntu basic server install guide, the link is at the beginning of this tutorial, and fix your hostname. The command 'hostname -f' must return the correct fully qualified hostname like '' when you configured the system correctly.

By: Treaver Hoerig

I have actually reinstalled the entire Ubuntu Server OS over 50 times following this guide to the letter and I still get SMTP Error 250 when accessing roundcube, I can't get LetsEncrypt to work across ISPConfig/Mail/Web without the "Untrusted Certificate Error" and I have literally followed this guide as well as a number of other guides; including hours of research and still am unable to actually get this server working perfectly. In an attempt to try to fix these issues, I research, get apache errors, have never gotten rid of the SMTP Error 250 as of yet, and always end up breaking something. Could someone here please explain to me what I am doing wrong. 

By: till

@Treaver: Please use the forum here at howtoforge to post the details of your issue.

By: Tom

When I check my MySQL config using the netstat/grep command, my listen port is 44086 and not the one listed in the tutorial. Is this a random port or should mine match exactly? 

By: Arthena

Many thanks for an inspiring run through. As a novice I had everything up and running. Is there at tutorial for fetting your web name houster to point to the server? I am unsure of what to set up on custom DNS records with my web name issuer.


Many thanks

By: Manisch

I'm sorry, but Step 8 (Install Apache, PHP, phpMyAdmin, FCGI, SuExec, Pear) just won't work over here.At the point where you write "MySQL application password for phpmyadmin: <-- Press enter", it always gives me an error because the login failed...Yes, I actually selected the apache2 option before by pressing the space bar. 

By: romain

Thanks a lot, I followed everything and except updating the ispconfig version (which is not beta anymore) everything worked perfectly without any change from what you explain :)

By: Balu

The entry in /etc/roundcube/ must still be made $ config ['smtp_server'] = 'localhost'; against this $ config ['smtp_server'] = 'tls: //% n'; be replaced. Otherwise you cannot send any emails.

By: Spaetzle

Hi I wondered why rspamd is not used in this tutorial. Isn't this better than amavisd and spamassiassin? Or are there some known problems with Ubuntu 20.04. Regards Bernd

By: Francisco Gomez

In the webmail configuration (roundcube) the possibility that the user himself changes the password of his account does not appear

By: francoisPE

set up plugin for that

By: Masters of Media

Hello Till, there is a small change in the dialog when securing MySQL. After the question "Disallow root login remotely? [Y/n]" there is a new dialog:

   By default, MariaDB comes with a database named 'test' that anyone can   access. This is also intended only for testing, and should be removed   before moving into a production environment.   Remove test database and access to it? [Y/n] y

By: Masters of Media

I would like to suggest to include an extra check on each occasion of a service being restarted, by doing a 'service xxxx status' immediately following the restart. In one or 2 occasions, following this tutorial, I came across a situation where a service would not restart or only restarted with warnings, which later on in the setup caused problems.

By: Masters of Media

I have issues when trying to enable quotas on vps's from a number of provicers. I get the following:[email protected]:/# quotaon -avug quotaon: using // on /dev/vda1 [/]: No such process quotaon: Quota format not supported in kernel.quotaon: using //quota.user on /dev/vda1 [/]: No such processquotaon: Quota format not supported in kernel.What could be going wrong here?

By: Masters of Media

On some servers, I get messages like this during the various installs: The following package was automatically installed and is no longer required:  xxxxxxxxxxUse 'apt autoremove' to remove it. Perhaps it would be a good idea to conclude the setting up of the server with a new section between 16 and 17 to autoremove anything no longer needed on the server?

By: Masters of Media

I would suggest to change the use of the nightly build in this article, to be replaced with the stable build of ISPConfig instead.

What an amazing tutorial. Thanks so much!

By: cydo

I am getting error after doing 

Install ISPConfig 3.2


 Unable to connect to the specified MySQL server Access denied for user 'root'@'localhost' (using password: YES)


What to do ...Please suggest me.

By: ridwan

hello Till, My installation process was interrupted because of the internet network disconnection

 at step

17. Install ISPConfig 3.2 --> Common Name (e.g. server FQDN or YOUR name) []: <-- Enter the server hostname, in my case:


I reconnected the server and repeated the steps

[email protected]:~# cd /[email protected]:/tmp# cd ispconfig3*/install/[email protected]:/tmp/ispconfig3-nightly/install# php -q install.php


Now i get the error like this :

ERROR: Stopped: Database already contains some tables.

How To Solve it ?


By: Eickelpasch

I have installed the virtual machine from this tutorial.

I could login as administrator.

When i started http(s):// to reach ispconfig nothig happens.

By: till

Depending on your local network, you might have to adjust the network configuration so that the IP matches the subnet. And until you configured your own server hostname, better use just the IP address to access the VM.

By: Jens

After using this tutorial, I get daily rkhunter emails with the following warnings:


Warning: The command '/usr/bin/lwp-request' has been replaced by a script: /usr/bin/lwp-request: Perl script text executable Warning: The following suspicious (large) shared memory segments have been found: Process: /usr/sbin/apache2 PID: 1436448 Owner: root Size: 1.2MB (configured size allowed: 1.0MB)


I guess we need to configure an exception rule for apache and lwp-request. How do I do this?

By: Jakub

Thanks for great tutorial! I am wondering where is the right my.cnf file for mysql tuning? Seems like when i try update any of file in etc/mysql nothing happen and phpmyadmin showing all time same values for variables. Thanks!

By: Michael FIscher

roundcube 1.4.3+dfsg.1-1In /etc/roundcube/ I have to set: $config['smtp_server'] = 'tls://%n'; otherwise I cannot send from roundcube. corresponding error message in /var/log/roundcube/errors.log:[01-Feb-2021 19:14:22 +0000]: <6mbeqtlv> PHP Error: SMTP server does not support authentication (POST /webmail/?_task=mail&_unlock=loading1612206862537&_framed=1&_action=send)[01-Feb-2021 19:14:22 +0000]: <6mbeqtlv> SMTP Error: Authentication failure: SMTP server does not support authentication (Code: ) in /usr/share/roundcube/program/lib/Roundcube/rcube.php on line 1702 (POST /webmail/?_task=mail&_unlock=loading1612206862537&_framed=1&_action=send)

By: Fanis Tsiros

Just a small tip for mariaDB instalation:

Editing file /etc/mysql/debian.cnf with a password gives me the following error when i start or restart the database server:

xxxxx: Looking for 'mysqlcheck' as: /usr/bin/mysqlcheck

xxxxx: Version check failed. Got the following error when calling the 'mysql' command line client

xxxxx: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

xxxxx: FATAL ERROR: Upgrade failed

Seems that my password has special characters. I ecnlosed my password in /etc/mysql/debian.cnf with single quotes like:

password = 'howtoforge'

Now version check does not fail.

By: nhybgtvfr

any ETA on the perfect server tutorial v2 you wanted to write?


Thanz for this tutorial. Great Work!

By: pranjal

i can not accesss login panel i went throgh installation. my server ip is

any help?

By: till

Please post your issue in the ISPConfig support forum:

By: Artie

I noticed unanswered question about Rspamd (By: Spaetzle at: 2020-12-28 18:25:44)So I want to ask the same and hope to get answer: Could you please provide the Tutorial with Rspamd ? I see you posotion Rspamd positively  ( and would like to install it on Ubuntu 20.04 initially if possibly. Hope to get reply soon...Thanks a lot for your efforts ! ISPConfig is definitely very effective Panel !

By: Fred

Thanks for a really good and easy to follow guide, everything was installed and is running except in my case for the Mailman web interface.  When accessing the link https://<server>/cgi-bin/mailman/listinfo/<mailing_list_name> I get a 404 error.  How should I go about troubleshooting that issue?

By: Brian P.

Why is it, we have to call example in the server name and in the ssl setup, and not only ??I get ssl certificate error after installing ispconfig, and no errors on the way. But when i enter the ispconfig admin site, i get the not trusted certificate, and in chrome i sometimes can not enter the site at all.

By: till

Because the server hostname is never your main domain name, as you would not be able to host a website on that domain and not receive any emails if you would use mydomain.tld instead of server1.mydomain.tld for the server hostname. Please post in the forum if you need further help with your DNS setup and SSL.

By: Brian P.

Thank you for answer.I was just wondering :) I wll post if i get error again, trying a new clean setup now.

By: Brian P.

Hi again.Its the same, i am locked out of the site, unless i go incognito mode, and accept that the certificate is unsafe, i tryed many times now, this one last time, i used the full automated ispconfig setup, just for try that :(Any have any idea how i can make my site secure ?

By: till

Please post in the forum if you need further help.

By: Aaron Stevens

Thank you so much. I followed this tutorial and it worked brilliantly :-) 


By: David

Hey I followed this and I have been running it for 6 months amazingly! Do you have plans on making it a docker image or is there a way to convert mine to a docker image? I want this containerized and then PiHole containerized and a Plex server all containerized on the same box.

By: mpyusko

Is there a reason you don't use php-fpm?  It offers much faster page-loads/rendering than the apache mod.

By: till

ISPConfig uses PHP-FPM and PHP-FPM is the default mode. You can choose the PHP mode in ISPConfig.

By: Chris_UK

Not sure about your configuration but my ESXI host uses DHCP for VM IP Assignment.

If you find the static IP does not match your configurations you have a couple of options. Either set it to dhcp, or change the ip address. I chose dhcp and this is whats needed to make it work.

Find your the name of your NIC ensXXX:ip -c link

sudo nano /etc/netplan/00-installer-config.yaml

change ens33 to match your NIC

change dhcp4 and dhcp6 to true

remove all lines after.Once you have saved the file (ctrl + x or ctrl + o) Reboot your VM, you should now get a DHCP assigned IP Address, login to your router and perform the steps required to make the ip address static. I won't go into that side of things, I use a cisco router so it may not be of use here.


By: Loggy

After upgrading to 20.04 from 16.04 via 18.04, roundcube required php-net-idna2 to be installed with apt install.  Then more 'fun' configuring roundcube but that's a different story!

By: vmevada102

After installing the ISP config, Login page displayed, But after login, blank page displayed in the system, Only ISP config logo, Search and Admin button displayed Ubuntu version 20.04, Php 7.4

By: Daniel Black

Please don't recommend updating mysql.user. It isn't possible in MariaDB-10.4 or later as that is a SQL view. It also has no effect without FLUSH TABLES. ALTER USER is that standard way to change a user's authentication so use that over any direct manipulation of MariaDB system tables.mysql_secure_installation has already set the password. So this actually isn't needed.

By: Brandon Stivers

First of all, MariaDB-10.4 and above isn't even installed with apt install mariadb-* by default on Ubuntu 20.04. MariaDB-10.3 is. You'd have to manually add the MariaDB repository to get above 10.3 right now. And that's not in the tutorial. So guess what's still needed and relevant? Maybe don't go above and beyond what a tutorial says (like activating 3rd-party repos), then complain the tutorial is wrong. Because it's not. People like you are why virtual environments exist in the development world. How many times have you said stuff doesn't work on your machine, while everyone else says it does? FOLLOW DIRECTIONS. 

By: Michael Falzon

Nice and work 2 install and kick ass it worked each time ( come from qmail )

By: Freeman

I have seen on other installations that ISPConfig manages XMPP but I can't see an XMPP server installaed in this tutorial or did I miss something.

By: till

XMPP support in ISPConfig has been removed as recent metronome versions are not compatible with the XMPP implementation in ISPConfig anymore and XMPP in ISPConfig was so rarely used, that a complete re-implementation is not planned at the moment.

By: Johny

Excellent and thorough instructions. Suggestion: to add a point #20 to have reverse proxy to port 8080 using nginx so the url would be clean (without :port to admin and clients).  

By: ProphetLamb

Some linux kerrnels do no support quota. This is due to a bug. Adding then to the virtual packages solves this.

To do so install virrtial pagages

apt-get install linux-image-extra-virtual

then register the quota modules

vim /etc/modules # add these quota_v1quota_v2


By: MSilliman

I have follwed this tuorial and have an up and workign system, however I'm having SSL issues. I have installed let's encrypt and I'm able to create new let's encrypt certifcates for websites, but my coresponding email, ftp, and other services are not using the Let's Encrypt SSL cert. The email and ftp services are using the SSL Cert asigned to the ISPConfig control pannel, which is a self signed cert.

By: till

The mail service shall use the system-wide SSL cert for the hostname, so that's fine. But that#s normally a let's encrypt cert as well unless your hostname was unreachable at install time. Take care that your server hostname is correctly configured in DNS. Then run: --force


and let the updater create a new SSL cert for ISPConfig and the other services. Also, take care that you use the right server name in your email client, the right one is the hostname of the server and not one of your hosted domains.

By: roberto

Hi folks

unfortunatelly this installs no perfect server. Till Ubuntu 16.04 LTS it worked fine. After the installing  ESM for Ubuntu 16.04 LTS the System was destroyed. Other tries with Ubuntu 18.04 LTS and Debian 11 and with Ubuntu 20.04 LTS failed to install the "perfect server"

By: till

The above guide works perfectly fine on Ubuntu 20.04, simply copy & paste the commands result in a working system, I'll test it regularly, no changes or updates are needed. You might want to make a post in the ISPConfig forum with the error messages you got so we can help you to find out where you did not follow the guide or where your base system has deficits that cause the overall system to fail later. Following this guide requires that you follow it to the letter, leaving things out or modifying commands will break it. Another possibility is that you use a unclean base system or there are other issues with your base system like unsuitable virtualization or not enough resources. At least you can rule out now that there are any issues with the guide.

By: malaperdas

Don't know when this was posted, but today, 25th of May 2022, this guide after following it 3 times, it doesn't work completely. I need only emails, no website hosting or any other services. I can create accounts, mailboxes, and log in into the accounts but can't send or receive. 

By: Declan Barry

Hi Folks.

To save a bit of time whilst experimenting, I cheated and downloaded the VM. I set it up to my IP Range and all seemed to work great so I decided to update the system. Whilst updating it it gets as far as unpacking the 00-maria DB - and just hangs there at 26%.

I restarted the VM and went through the upgrade again. Had to manually run sudo dpkg --configure -a to correct a dpkg issue. It seems to have upgraded okay now but my query is in relation to why the mariadb upgrade failed. its currently at 10.3.34.

I'm going to go down through the actual tutorial but was just curious as to why the mariadb upgrade appears to fail.



By: Moonlit

why it doesn't work on email. i have completed everything without any issue but the mail is not sending or receiving! the error is connection to refused. i have also tried with or without AMAVIS which can cause this error. tried every solution that is posted on how to forge but nothing works! tried different providers like Hetzner and Vultr, nothing works!!

By: till

The above guide works perfectly fine at Hetzner and other providers, I've installed a system at Hetzner a few days ago successfully. The most likely reason for your issue is that the hostname was not configured correctly before installing the system, amavis requires it that the command: "hostname -f" returns the fully qualified hostname while the command "hostname" returns the short hostname. Post in the ISPConfig support forum if you need further help

Or you replace Amavis with Rspamd:

Or you use the latest and recommended setup for Ubuntu and install from scratch which uses Rspamd too:

By: MKTwo

Hi,everything is done, but no mails are going out or in with roundcube.

The mail.log shows the following:

Jul 23 21:38:52 vps amavis[188478]: (188478-02) (!)connect to* failed, attempt #1: Can't connect to socket* using module IO::Socket::IP: Connection refused


 vps amavis[188477]: (188477-03) (!)Nl3eWAaM5MpA FWD from <t -> <>,  451 4.5.0 From MTA() during fwd-connect (All attempts (1) failed connecting to smtp:*): id=188477-03

By: till

The most common reason for Amavis failing to start is a misconfiguration of the hostname. Please post your issue in the ISPConfig forum if you need further help:

Or you replace Amavis with Rspamd:

Or you use the latest and recommended setup for Ubuntu and install from scratch which uses Rspamd too:

By: bvbrakel

Dear Till Brehm, my nane is Ben van Brakel, 79 years young and still active with computers, I'm fighting with them since 1963 (NASA IBM systens) with a lot of pleasure and fun. I want give you my deepest respect for what you did with your tutorial, it is splendid and o so complete, Thanks for that.

I use it already a long time from on my first UBUNTU release 10.04 I believe, but now I'm running in a big problem with ubuntu 20.04, I cannot get email working, I installed for my on security your tutorial at the last pont 3 times and I got 3 times the same failure wen I try to receive mails, the problem is "amavis" I tried all I know but cannot get it goin. Hereby 3 lines dfrom my maillog:  Maybe you can give me a hint, or tell me where I could find a solution. Thank in advance.


Aug 1 11:19:43 vbserver1 amavis[533827]: (533827-14) (!)connect to* failed, attempt #1: Can't connect to socket* using module IO::Socket::IP: Connection refused Aug 1 11:19:43 vbserver1 amavis[533827]: (533827-14) (!)Pnkul5auYlt6 FWD from <[email protected]> -> <[email protected]>, 451 4.5.0 From MTA() during fwd-connect (All attempts (1) failed connecting to smtp:*): id=533827-14 Aug 1 11:19:43 vbserver1 amavis[533827]: (533827-14) Blocked MTA-BLOCKED {TempFailedOpenRelay}, [] [] <[email protected]> ->port: 10024 and 10026 are active iin IP4 and IP6.


By: till

Hello Ben, please make a new thread for your issue in our support forum so we can help you to find out why amavis is not working on your server. You can find the support forum here:

By: Hawk

I am planning to use this setup with Ubuntu 22.04 and additional with dotnet core on a Virtual Server.

What would you recommend for cpu and ram for such a system? 

By: Guillermo

 Thank you guys a lot for this tutorials, they`re lifesavers. An update is in order since certbot is not available anymore as described here and have to be installed diferently. 

Thanks again for your work!

By: Sanuich

The emails are received but not appeared not in roundcube not in app clients

postfix/smtps/smtpd[210685]: warning: connect to Milter service inet:localhost:11332: Connection refused

 postfix/trivial-rewrite[210698]: warning: do not list domain in BOTH mydestination and virtual_mailbox_domains



not all new files appears in /var/mail for every new mailbox i create with IspConfig

By: till

You set up a wrong hostname before installing ISPConfig. You must use a subdomain as hostname (as the tutorial above advises) like and not a domain that you ant to use for email (like To fix that, set a correct hostname in the files /etc/hosts, /etc/hostanme and /etc/postfix/ by changing the domain (like to a subdomain (like and reboot your server.

By: Sanuich

I must apologize. Everything works with this tutorial. I could reach email SPAMless rate 10/101. Very important to use a subdomain as it was explained here. If you want to use as an email domain create for installing ISPconfig. will not work from emails!!!!2. Change System -> Server Config -> Mail -> Content Filtrer to  Rspamd also remove Amavis


That's all Everything works

By: Fisa

I have successfully installed Roundcube and ISPConfig in AWS EC2, i have one domain in godaddy, i cannot able to send the mail from, how to add DNS Records in Godaddy 

By: Phantom

Hi. I followed this guide to the letter and everything works, except roundcube.

I get ERR_SSL_PROTOCOL_ERROR when I try to access from a browser.

I get the same error for

Any ideas where should I start looking to solve this ?

By: till

Please post in the support forum to get help with your setup: