The Perfect Server - Debian 9 (Stretch) with Apache, BIND, Dovecot, PureFTPD and ISPConfig 3.1

This tutorial shows how to prepare a Debian 9 server (with Apache2, BIND, Dovecot) for the installation of ISPConfig 3.1, and how to install ISPConfig. The web hosting control panel ISPConfig 3 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, MySQL, BIND or MyDNS nameserver, PureFTPd, SpamAssassin, ClamAV, and many more. This setup covers Apache (instead of nginx), BIND, and Dovecot.

1 Preliminary Note

In this tutorial, I will 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 minimal installation of Debian 9. This might be a Debian minimal image from your Hosting provider or you use the Minimal Debian Server tutorial to setup the base system.

2 Install the SSH server (Optional)

If you did not install the OpenSSH server during the system installation, you can do it now:

apt-get install ssh openssh-server

From now on you can use an SSH client such as PuTTY and connect from your workstation to your Debian 9 server and follow the remaining steps from this tutorial.

3 Install a shell text editor (Optional)

We will use nano text editor in this tutorial. Some users prefer the classic vi editor, therefore we will install both editors here. The default vi program has some strange behavior on Debian and Ubuntu; to fix this, we install vim-nox:

apt-get install nano vim-nox

If vi is your favorite editor, then replace nano with vi in the following commands to edit files.

4 Configure the Hostname

The hostname of your server should be a subdomain like "". Do not use a domain name without subdomain part like "" as hostname as this will cause problems later with your mail setup. First, you should check the hostname in /etc/hosts and change it when necessary. The line should be: "IP Address - space - full hostname incl. domain - space - subdomain part". For our hostname, the file shall look like this:

nano /etc/hosts       localhost.localdomain   localhost     server1

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Then edit the /etc/hostname file:

nano /etc/hostname

It shall contain only the subdomain part, in our case:


Finally, reboot the server to apply the change:


Log in again and check if the hostname is correct now with these commands:

hostname -f

The output shall be like this:

root@server1:/tmp# hostname
root@server1:/tmp# hostname -f


5 Update Your Debian Installation

First, make sure that your /etc/apt/sources.list contains the stretch/updates repository (this makes sure you always get the newest security updates), and that the contrib and non-free repositories are enabled as some required packages are not in the main repository.

nano /etc/apt/sources.list

deb stretch main contrib non-free
deb-src stretch main contrib non-free

deb stretch/updates main contrib non-free
deb-src stretch/updates main contrib non-free


apt-get update

To update the apt package database

apt-get upgrade

and to install the latest updates (if there are any).


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


7 Synchronize the System Clock

It is a good idea to synchronize the system clock with an NTP (network time protocol) server over the Internet. Simply run

apt-get install ntp

and your system time will always be in sync.


8 Install Postfix, Dovecot, MySQL, rkhunter, and Binutils

We can install Postfix, Dovecot, MySQL, rkhunter, and Binutils with a single command:

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

When you prefer MySQL over MariaDB, replace the packages "mariadb-client mariadb-server" in the above command with "mysql-client mysql-server".

You will be asked the following questions:

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

To secure the MariaDB / MySQL installation and to disable the test database, run this command:


Answer the questions as follows:

Change the root password? [Y/n] <-- y
New password: <-- Enter a new MySQL root password
Re-enter new password: <-- Repeat the MySQL root password
Remove anonymous users? [Y/n] <-- y
Disallow root login remotely? [Y/n] <-- y
Remove test database and access to it? [Y/n] <-- y
Reload privilege tables now? [Y/n] <-- y

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

nano /etc/postfix/

Uncomment the submission and smtps sections as follows and add lines where necessary so that this section of the file looks exactly like the one below.

submission inet n - - - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-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=
# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
# -o milter_macro_daemon_name=ORIGINATING
smtps inet n - - - - 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=
# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
# -o milter_macro_daemon_name=ORIGINATING [...]

Restart Postfix afterwards:

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 = and add the line sql-mode="NO_ENGINE_SUBSTITUTION":

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           =



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 read, in this example the password is "howtoforge".

# 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

Then we restart MariaDB:

service mysql restart

Now check that networking is enabled. Run

netstat -tap | grep mysql

The output should look like this:

root@server1:/home/administrator# netstat -tap | grep mysql
tcp6 0 0 [::]:mysql [::]:* LISTEN 17776/mysqld


9 Install Amavisd-new, SpamAssassin, and ClamAV

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

apt-get install amavisd-new spamassassin clamav clamav-daemon zoo 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
systemctl disable spamassassin

9.1 Install Metronome XMPP Server (optional)

This step installs the Metronome XMPP Server which provides a chat server that is compatible with the XMPP protocol. This step is optional, if you do not need a chat server, then you can skip this step. No other ISPConfig functions depend on this software.

Add the Prosody package repository in Debian.

echo "deb stretch main" > /etc/apt/sources.list.d/metronome.list
wget -O - | sudo apt-key add -

Update the package list:

apt-get update

and install the packages with apt.

apt-get install git lua5.1 liblua5.1-0-dev lua-filesystem libidn11-dev libssl-dev lua-zlib lua-expat lua-event lua-bitop lua-socket lua-sec luarocks luarocks

luarocks install lpc

Add a shell user for Metronome.

adduser --no-create-home --disabled-login --gecos 'Metronome' metronome

Download Metronome to the /opt directory and compile it.

cd /opt; git clone metronome
cd ./metronome; ./configure --ostype=debian --prefix=/usr
make install

Metronome has now be installed to /opt/metronome.

Share this page:

Suggested articles

5 Comment(s)

Add comment


From: Luther at: 2017-06-20 20:48:14

as soon as stretch released you updated your guides, thx for keeping up the hard work

From: nedkox at: 2017-06-23 19:23:48


From: marc at: 2017-06-25 10:55:29

The underscore got me confused, it should be "NO_ENGINE_SUBSTITUTION"   . Hope it helps. 


From: Oscar at: 2017-06-26 04:11:56

I have a problem with IspConfig:

With initial configuration i create a user and a site y say this:

The following changes are not yet populated to all servers:

From: till at: 2017-06-26 07:47:10

Writing changes to disk takes about 1 Minute. If the changes have not been written after some time, then please make a post in the forum to get help with your installation issue. Instruction on how to find out what is failing in your install can be found at the end of this post: