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:

[email protected]:/tmp# hostname
[email protected]:/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

To prevent the error 'Error in accept: Too many open files' we will set higher open file limits for MariaDB now.

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 -p /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 mysql restart

Now check that networking is enabled. Run

netstat -tap | grep mysql

The output should look like this:

[email protected]:/home/administrator# netstat -tap | grep mysql
tcp6 0 0 [::]:mysql [::]:* LISTEN 17776/mysqld
[email protected]:/home/administrator#

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 libdbd-mysql-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

139 Comment(s)

Add comment


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

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

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


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

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


By: 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:

By: 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:

By: HelLViS69 at: 2017-06-29 20:47:41

Hi,I just installed a fresh Debian 9, but the new server doesn't send/receive emails.

I checked in the logs and the problem is amavis:giu 29 22:29:18 web amavis[21846]: Starting amavisd: ERROR: MISSING REQUIRED ADDITIONAL MODULES:giu 29 22:29:18 web amavis[21846]:   DBD::mysqlgiu 29 22:29:18 web amavis[21846]: (failed).

I checked apt repo and they are ok, the only package referring to DBD and mysql is libaprutil1-dbd-mysql which isn't installed

Anyone have a clue?

By: HelLViS69 at: 2017-07-06 11:31:52

Hi, I installed libdbd-mysql-perl and amavis is up and running.. I didn't try to send/receive mails yet

By: HelLViS69 at: 2017-07-07 20:04:15

Hi, I finally managed to send/receive mails. The first problem, as in the previous mail, was libdbd-mysql-perl missing. (email receiving)

Then I have a SASL login error, fixed installing libsasl2-modules.

The last error was sending mail with this error:status=deferred (connect to[]:10026: Connection refused)

The problem here was in /etc/postfix/ content_filter = amavis:[]:10024 while in /etc/postfix/ there was /^/ FILTER amavis:[]:10026. Asap I changed the port to 10024, postfix started to send mails

By: tucuta at: 2017-07-01 06:07:32

This tutorial does not work. He already tried 3 times, he followed the steps well and there are two applications that do not ask for password.When I create a user and when I sync does not work. The message is: The following changes are not yet populated to all servers:


By: till at: 2017-07-01 06:57:08

The tutorial is working fine. Just had a user who reported to me yesterday that everything worked out of the box and I installed it myself by simple copy/paste of all commands 2 days ago as well without any issues. Your problem is an issue with your server and not the tutorial, when the base system is broken or not a clean fresh install, then the setup will fail. E.g. when services are already installed, then they will not ask for a password. And non-executing ISPConfig jobs can mean that you or the person that made the base install disabled the linux cron daemon. Please post in the forum here at howtoforge to get help with your server installation.

By: Linuxer at: 2017-07-01 17:26:34

Thank you for the new perfect server guide. Works great.

By: brody at: 2017-07-03 05:17:19

lstsencrypt does not enable under Sites -> Web domain

By: till at: 2017-07-03 09:03:08

This means that let's encrypt was not able to verify your domain. See let's encrypt FAQ post in the forum: and post in the Forum if you need further help on configuring your Domain for Let's encrypt.

By: Fab at: 2017-07-05 12:14:03

In order to get amavisd starting you need to install this package:


By: till at: 2017-07-05 12:21:27

I do not have to install this separately on my servers. I'll check that.

By: treki at: 2017-07-07 21:58:20

Configuring phpmyadmin:

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using     ?    ? password: YES) . Your options are:                                       ?    ?  * abort - Causes the operation to fail; you will need to downgrade,     ?    ?    reinstall, reconfigure this package, or otherwise manually intervene  ?    ?    to continue using it. This will usually also impact your ability to   ?    ?    install other packages until the installation failure is resolved.    ?    ?  * retry - Prompts once more with all the configuration questions        ?    ?    (including ones you may have missed due to the debconf priority       ?    ?    setting) and makes another attempt at performing the operation.       ?    ?  * retry (skip questions) - Immediately attempts the operation again,    ?    ?    skipping all questions. This is normally useful only if you have      ?    ?    solved the underlying problem since the time the error occurred.      ?    ?  * ignore - Continues the operation ignoring dbconfig-common errors.     ?    ?    This will usually leave this package without a functional database.   ?    ?                                                                          ?    ? Next step for database installation:                                     ?    ?                                                                          ?    ?                          abort                                           ?    ?                          retry                                           ?    ?                          retry (skip questions)                          ?    ?                          ignore


What i must do?

By: till at: 2017-07-10 09:01:19

The error means that you entered a wrong MySQL root password when requested by apt.

By: treki at: 2017-07-07 22:29:11

The same problem  in the RoudCube install!

By: treki at: 2017-07-07 23:14:33

ISPconfig installation:

PHP Parse error:  syntax error, unexpected 'if' (T_IF), expecting function (T_FUNCTION) in /usr/local/ispconfig/server/plugins-available/ on line 1189

The mysql-password problems are solved.

By: till at: 2017-07-10 08:54:08

Download ISPConfig again and install it.

By: Er1ck at: 2017-07-09 12:39:45

Till, congratulations for the tutorial! It didn't work for me on the first try but I believe in it. For many years, I've set up the systems by hand by the shell and now I want a new life with Ispconfig. :) I want to install it on multiple servers in the cloud and that's why I have a huge hope that it works well. I use Sendmail and Exim4, Postfix will be the first time.

Some servers are in the Google Cloud, which is very restrictive in many things. For email, I'm using Sendgrid with them. My question is if your tutorial and Ispconfig can work fine on a Google Cloud virtual machine using Sendgrip to send emails? The other servers are in Rackspace, Amazon WS and Digital Ocean. Are there any special recommendations for using the tutorial and Ispconfig in these hosting companies?

On special servers some Ispconfig features will be disabled.


Thank you so much!

By: till at: 2017-07-10 09:05:30

This setup works fine on cloud services as well. You can configure e.g. sendgrid as outgoing SMTP under System > Server config in ISPConfig. Btw. In case that you recieved that syntax error that the user posted abvoe when using the ISPConfig dev version from git, then just download ISPConfig dev again (or use the stable version which did not had that problem) as the problem has been resolved in the dev code.

By: Jose at: 2017-07-12 22:59:09

Hello, gives the following error, from inside of Ispconfig:

Is a new installation of a debian 9 in a vps, I tried 3 times installing the manual from the begining alwais with the same error, and doing the manual exactly.

Thank you.

postfix/smtpd[1664]: fatal: no SASL authentication mechanismspostfix/smtpd[1753]: fatal: no SASL authentication mechanisms

By: till at: 2017-07-13 06:48:26

There is no issue in the tutorial itself, mail on the resulting setup works flawlessly as you can see e.g. in the downloadable VM. Most likely, you made a mistake while editing the postfix config or you missed to install a package. Please post in the forum to get help with your configuration problem.

By: Zergling at: 2017-07-15 22:43:17

How to set quota when I have virtual machine running on LXC?And my /etc/fstab looks like this:# UNCONFIGURED FSTAB FOR BASE SYSTEM

By: till at: 2017-07-17 08:18:44

LXC does not has any real quota support. But there are some workarounds to get quota in LXC like this:

But you will probably see a performance decrease.

By: Solstice at: 2017-07-17 21:36:55

There is a issue with the Maria DB for Debian 9 and the echo "update mysql.user set plugin = 'mysql_native_password' where user='root';" | mysql -u root.

If you do the set plugin portion one will end up with a ERROR 1524 (HY000): Plugin  x is not loaded.

From research it seems to have to deal with Maria DB 10x or Mysql 5.7x as it has changed the tables for user passwords.

Please update this, as it gets frustrating during other install portions.


By: till at: 2017-07-18 10:39:16

Thank you for your report. I just tested the installation again on a fresh Debian 9 and there are no errors in the MySQL setup as shown in the tutorial. MySQL login with password works flawlessly and MySQL restarts without errors (neither on screen nor in the log file). Maybe you missed editing the debian.cnf file or you did not restart MySQL.

By: Ed at: 2017-07-27 16:15:33

Hi, Apache 2 won't start in section 10 - do you really mean httpoxy, or do you mean httproxy?

By: till at: 2017-07-27 16:26:24

Apache starts absolutely fine with that config here and yes, the name is 'httpoxy'. Don't you know what httpoxy is? Read here:

When apache does not start with that config, then you might have missed enabling the headers module in apache which is done in the a2enmod command above or you made a typo in one of the commands. In any case, you find the reason for the error that occurs on your server in the apache error.log file.

By: Ed at: 2017-07-27 16:27:46

Please ignore my just sent error report - there was a character missing from my /etc/apache2/conf-available/httpoxy.conf file which I corrected and which is now allowing apache2 to restart - a problem with vim and the mouse!

By: Quentin at: 2017-08-01 11:28:50



# Automatically generated for Debian scripts. DO NOT TOUCH![client]host = localhostuser = rootpassword = howtoforgesocket = /var/run/mysqld/mysqld.sock[mysql_upgrade]host = localhostuser = rootpassword = howtoforgesocket = /var/run/mysqld/mysqld.sockbasedir = /usr


am i supposed to replace howto forge by my root password ? is it safe to let in clear a password?

By: till at: 2017-08-01 11:47:18

Yes, you have to replace it and yes, it's safe as the file can be read by the root user only and the password has to be set in cleartext there.

By: Quentin at: 2017-08-01 12:29:40

Thanks for the answer !

By: Nico at: 2017-08-04 00:37:27

I`ve received an 404-Error, when I`ve tried to acces phpMyAdmin.


Include /etc/phpmyadmin/apache.conf

at the bottom of /etc/apache2/apache2.conf solved my problem.

Rest works great! Thank you very much for this howto.

By: till at: 2017-08-04 07:10:37

When you select the apache installation option during PHPMyAdmin installation as shown in the tutorial, then adding this include manually is not needed.

By: Stefano at: 2018-05-11 17:24:07

For me too. ISPConfig or the tutorial doesn't add the PHPMyAdmin conf file [/etc/roundcube/apache.conf] in /etc/apache2/conf-available/

In the old debian7 with ISPConfig the installer put in /etc/apache2/conf.d/ the phpmyadmin.conf -> ../../phpmyadmin/apache.conf

Solve it with:

ln -s /etc/phpmyadmin/apache.conf /etc/apache2/conf-available/phpmyadmin.confcd /etc/apache2/conf-enabledln -s ../conf-available/phpmyadmin.conf phpmyadmin.confservice apache2 reload


By: till at: 2018-05-11 19:19:44

There is neither an issue in ISPConfig nor in the tutorial. The problem you describe happens when you do not select to configure apache when the phpMyAdmin apt installer asks for it. Selecting means to navigate to the option and then select it with the space bar of your keyboard. If you fail to activate an option in apt with the spacebar and just highlight it, then apt will not enable the option. To verify that your step is not required, I just installed a test server again by foilowing the above tutorial to the letter, the result is that phpmyadmin is enabled and working:


[email protected]:~# ls -la /etc/apache2/conf-enabled/php*

lrwxrwxrwx 1 root root 33 May 11 21:08 /etc/apache2/conf-enabled/phpmyadmin.conf -> ../conf-available/phpmyadmin.conf


But, in case someone did not follow the tutorial and missed enabling phpmyadmin, then your commands are the correct ones to do this manually afterwards.

By: ed at: 2017-08-07 06:04:03

Hi,  In step 12.1 shoud we also a2enconf php7.0-fpm like the terminal return tells us to, or is that a mistake?

By: till at: 2017-08-07 08:56:31

You should not run a2enconf php7.0-fpm.

By: ed at: 2017-08-07 18:42:54

I have the same question - in step 10 I am installing mariadb, yet I was not asked for a mysql root password! and I  am reinstalling because I followed this tutorial perfectly 2 days ago, and have not been able to send or receive mail with this production install, even though I did get it workign on a test vps - the only difference being that the test vps has exim4 installed, and this one does not. and the error is a failure to communicate with smpt - given in roundcube when I try to send mail.

By: Luke at: 2017-08-31 00:07:54

Everything worked great, until it wouldn't let me upload website content via SFTP (user: admin), and I ran chmod 777 on the whole /var/www directory

# chmod -R 777 /var/www


Webserver still runs, but the ISPConfig GUI is broken (500 / Internal Server Error)


Tried to patch up with this, but no dice.....

    # sudo find /var -type d -exec chmod 775 '{}' \;

    # sudo find /var -type f -exec chmod 664 '{}' \;


Any ideas how to fix? I already tried to reinstall ISPConfig with php -q update.php

By: till at: 2017-08-31 07:49:00

A chmod 777 must destroy the whole installation as all files and folders have special permissions, so never do that. You can upload files by SFTP with an SSH user that you created for this website in ISPConfig (or by FTPS when you created an FTP user). The user "admin" which does not belong to the ISPConfig install is probably just a normal Linux user without special permissions, so he can not upload files to websites. Only users of the site and the root user can do that.


What you can try is that you enable the "update permissions on update" option under system > server config > web in ISPConfig and then run Tools > Resync in ISPConfig to resync the websites. If this won't work, then you probably have to delete all sites in ISPConfig and recreate them or reinstall the system.

By: Adam at: 2017-09-10 03:07:14

I am a little confused by this...what am i actually supposed to input into hostname?

Are your ip addresses here internal/local ones or external/public ones? (this is really confusing)

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.


For a google cloud compute instance the following is automatically added by google when the instance is deployed (the disk image already has an O/S too).

Do i delete what google has automatically added and replace it with your etc? (on google cloud locahost is 127... is it not? What is 192.168 for? That is not an external/public ip address?)       localhost

::1             localhost ip6-localhost ip6-loopback

ff02::1         ip6-allnodes

ff02::2         ip6-allrouters server1.c.goannawebsites-1.internal server1  # Added by Google  # Added by Google

By: Adam at: 2017-09-10 08:33:45

is this jailkit directory the right one? Doesnt this install it into the tmp directory?


cd /tmpwget xvfz jailkit-2.19.tar.gzcd jailkit-2.19echo 5 > debian/compat./debian/rules binary

By: till at: 2017-09-10 09:18:07

Yes, that's the correct directory and no, this will not install jailkit in /tmp.

By: Markus at: 2017-09-14 13:46:33

It is not the perfect Server... HowTo...You write about installing letsencrypt, but it is not used in your howto. Only installing is not enough, that does not work

By: till at: 2017-09-15 08:33:13

I guess you are a first-time ISPConfig user so you can't know that the tutorial is complete and the LE certs are created by ISPConfig when you add a site. So there is nothing missing, the tutorial is complete, there are no further steps needed beside installing the LE package as shown in the tutorial. LE is used by ISPConfig and the SSL certs are created by ISPConfig. I'll add a note in the tutorial so that no other first-time users think that something is missing.

By: Eric at: 2017-09-14 15:38:16

Hi, and thank you for this tutorial.

I had an error in the RKHunter log : Invalid WEB_CMD configuration option: Relative pathname: "/bin/false"

I googled it and found a solution, which was to edit the /etc/rkhunter.conf file and change some values :



WEB_CMD="/bin/false" --> WEB_CMD=""

Does these seems fine to you ? Or should I revert these and correct that error another way ?

Thanks for your help

By: esezako at: 2017-09-21 07:26:25


For when a howto Multiserver Setup With Dedicated Web, Email, DNS & MySQL Database Servers On Debian 9?

Thanks in advance!

By: quaz22 at: 2017-09-25 10:08:14


I had to install yet dialog and libwww-perl

I have Debian 8.9

The ispconfig shows me: Invalid WEB_CMD configuration option: Relative pathname: "/bin/false"

Nothing helps


By: till at: 2017-09-25 10:12:56

This tutorial is for Debian 9.x only, it will not work when you have Debian 8.x. The tutorial for Debian 8 is here:


You should always use the tutorial that matches the major version of your installed OS.

By: Michael at: 2017-09-27 05:09:56

Seem to have forgotten to link phpmyadmin apache conf to sites-enabled

By: till at: 2017-09-27 06:25:43

This link is created automatically when you install PHPMyAdmin by selecting apache in the apt installer. If the link is missing on your system, then you have not chosen the right option during install (or you did not activate it in the dialog with the space bar).

By: Michael at: 2017-10-06 02:17:04

Oh! I see what happened. It LOOKED like I had apache selected when configuring, but I didn't have anything selected. I had to hit *space*!

By: Michael at: 2017-09-27 05:44:22

may need to add this too (i needed it for getting certbot to work on command line)


apt-get install python-certbot-apache

By: till at: 2017-09-27 06:28:51

This package is not required and more important it will hurt the setup. It tries to modify the vhosts created by ispconfig in a way that the system will fail later (it duplicates some apache directives which have t be unique server-wide so apache will fail when you restart it). LE certs for websites get generated from within ISPConfig.

By: Michael at: 2017-10-06 02:27:40

Okay... So then how do we get the cert for the main server?

By: till at: 2017-10-06 07:26:23

By: Michael at: 2017-10-06 13:17:47

Thank you! I will look into that. :)

By: Alan Johnston at: 2017-10-02 02:09:36

i must of done this tutorial 8 times in one night getting to the end and not being able to log in, everytime i tried to log in it would not load, it done my head in i went from (obvs not the example part but i have used it as an example) it would not let me log in but now i have managed to log in after trying (diff ip again for security) so if you cant login thorugh the FQDN then try the ip

By: Manel Neto at: 2017-10-04 17:36:57

How do I install another version of php

By: Kévin at: 2017-10-20 12:39:50

Hi and thanks for the tutorial !

When I put this : echo "update mysql.user set plugin = 'mysql_native_password' where user='root';" | mysql -u root

I got this message : ERROR 1698 (28000): Access denied for user 'root'@'localhost'

Do you have any ideas ?



By: till at: 2017-10-20 13:37:24

Seems as if your MySQL server has a root password already. use this command in that case:


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

By: Kévin at: 2017-10-20 14:04:31

Thanks for your quick answer ! 

Sadly, I have this message : ERROR 1698 (28000): Access denied for user 'root'@'localhost'


By: till at: 2017-10-20 14:09:07

Then you either did not add the -p switch at the end of the command as I suggested or you enter a wrong password.

By: Kévin at: 2017-10-20 14:15:26

I added the -p, I tried with sudo, I still got the same error...How to solve this problem ?

By: SamTzu at: 2018-04-09 17:12:01

If you can't login to your mysql database as root you need to reset it's root password. Instructions are here...

By: brody at: 2017-10-24 10:13:34

I get an error in RKHunter Log "Invalid WEB_CMD configuration option: Relative pathname: "/bin/false"

By: till at: 2017-11-04 06:56:58

That's not an issue in the tutorial, it is in the Debian RKHuntre package, see here:

By: John Rand at: 2017-11-08 17:01:21

I'm trying to add ISPConfig on a Debian 9  on Google Compute Engine.  When I added a host and hostname as described, and rebooted, and then check through hostname and hostname -f, it shows the Google hostname, not what I added.  Could this be why I'm getting the Access denied for user 'root'@'localhost' when I run echo "update mysql.user set plugin = 'mysql_native_password' where user='root';" | mysql -u root -p

Obviously a newbie here.  Any suggestions would be appreciated.

By: till at: 2017-11-09 09:23:52

That's not related. When google does not let you set the hostnname, then you can leave the hostname as it is. Maybe you have not set a MySQL root password yet, in that case remove the -p at the end of the command.

By: André at: 2017-11-19 09:37:52

I can't get Pro-FTP to work properly. I just want to allow FTPS. SFTP I have totally deleted because it would have to run over PAM. But with FTPS it cannot load the directory list.

By: cocovina at: 2018-01-04 11:42:29

It looks like firewall problem. Check the high ports - should be opened (or some range corresponding with client setup)

By: Fabrice at: 2017-11-20 21:22:57

Thank you very much

By: Jesse Norell at: 2017-11-22 19:27:33

I upgraded a system from jessie to stretch and edited /etc/mysql/mariadb.conf.d/50-server.cnf (which did exist) to set sql-mode="NO_ENGINE_SUBSTITUTION" however I found that config file was not being read at all; I ended up making the addition to /etc/mysql/conf.d/mariadb.cnf and it worked fine.

By: George at: 2017-11-23 08:26:39

Every time.... in roundcube...



 An error occurred while installing the database:                                                                                                      ?  ?                                                                                                                                                       ?  ? ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2 "No such file or directory") . Your options   ?  ? are:                                                                                                                                                  ?  ?  * abort - Causes the operation to fail; you will need to downgrade,                                                                                  ?  ?    reinstall, reconfigure this package, or otherwise manually intervene                                                                               ?  ?    to continue using it. This will usually also impact your ability to                                                                                ?  ?    install other packages until the installation failure is resolved.                                                                                 ?  ?  * retry - Prompts once more with all the configuration questions                                                                                     ?  ?    (including ones you may have missed due to the debconf priority                                                                                    ?  ?    setting) and makes another attempt at performing the operation.                                                                                    ?  ?  * retry (skip questions) - Immediately attempts the operation again,                                                                                 ?  ?    skipping all questions. This is normally useful only if you have                                                                                   ?  ?    solved the underlying problem since the time the error occurred.                                                                                   ?  ?  * ignore - Continues the operation ignoring dbconfig-common errors.                                                                                  ?  ?    This will usually leave this package without a functional database.                                                                                ?  ?                                                                                                                                                       ?  ? Next step for database installation:                                                                                                                  ?  ?                                                                                                                                                       ?  ?                                                                abort                                                                                  ?  ?                                                                retry                                                                                  ?  ?                                                                retry (skip questions)                                                                 ?  ?                                                                ignore                                                                                 ?  ?                                                                                                                                                       ?  ?                                                                                                                                                       ?  ?                                                                        <Ok>          

By: Fahad Ahammed at: 2017-11-25 04:38:35

Thank You.

By: James Steerforth at: 2017-11-26 08:01:09

A small suggestion - you should rename this as  "The Perfect Guide to a Perfect Server". I proceeded through all the steps without a hitch, a rare occurence when following these type of instructions. Thanks for such a detailed and useful guide.

By: Fabrice at: 2017-11-29 23:37:21


Thank you very much for this tuto.

I followed step by step, I've created a new client with ISPConfig 3.1, a new site and a new ftp account, but I can't connect with FileZilla, with SSH port 21.

Do you have an idea ?



By: till at: 2017-11-30 07:50:07

Most likely you use a wrong FTP mode. ensure that you use FTPS (which is FTP) and not SFTP (which is SSH). If you need further help, please post in the Forum here at howtoforge.

By: David Evans at: 2017-11-30 22:57:37

After finishing this I was unable to log into ISPConfig. I had the site took too long to respond error so I rebooted the server and then was unable to login as root anymore?  

By: till at: 2017-12-01 08:25:15

Then you probably made a mistale during setup. This tutorial does not alter or configure root login nor sshd.

By: Armand at: 2017-12-03 19:03:16

Very nice tutorial, thank you.

I have just a small important problem: I cannot access to phpmyadmin. On myserveraddress:8080/phpmyadmin I'm getting the warning

The requested URL /phpmyadmin was not found on this server.

I'm lost

By: Sijmen at: 2017-12-14 19:57:59

[email protected]:~# 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

Reading package lists... Done

Building dependency tree

Reading state information... Done

E: Unable to locate package dovecot-sieve dovecot-lmtpd sudo

what am i missing i have edited the soucelist

By: Sijmen at: 2017-12-25 18:37:27

The above error was i did not run apt-get update

but got a other error 

[email protected]:~# systemctl daemon-reload

[email protected]:~# service mysql restart

Warning: mysql.service changed on disk. Run 'systemctl daemon-reload' to reload units.

[email protected]:~#


By: Anthony B at: 2017-12-29 14:57:52

Morning, i have the système error 

[email protected]:~# systemctl daemon-reload

[email protected]:~# service mysql restart

Warning: mysql.service changed on disk. Run 'systemctl daemon-reload' to reload units.

[email protected]:~#

By: Anthony B at: 2018-01-02 10:10:34

Hi, i don't know why but now this cmld works fine :) 

By: Anthony B at: 2018-01-04 06:54:43

I have re-install my server and i have the same server. 

For me, i have need to change my cmdl. I remplace systemctl daemon-reload to systemctl --system daemon-reload


Best regards

By: Martin at: 2018-01-18 12:43:28

Any ideas on this?


host:~# systemctl --system daemon-reload

host:~# systemctl daemon-reload

host:~# service mysql restart

Warning: mysql.service changed on disk. Run 'systemctl daemon-reload' to reload units.



By: Sudrien at: 2018-03-18 01:33:50

I also recieved the

Warning: mariadb.service changed on disk. Run 'systemctl daemon-reload' to reload units.

...and running the command had no effect.


Instead of /etc/systemd/system/mysql.service.d/limits.conf

I added & editied /etc/systemd/system/mariadb.service.d/limits.conf

and systemctl daemon-reload took effect

By: jean francois at: 2018-01-02 22:52:40

hello and thank you,

Is it possible to install phpmyadmin with your tutorial ?

By: till at: 2018-01-03 07:18:17

PHPMyadmin is installed as part of this tutorial.

By: Mat at: 2018-01-03 23:09:09

Dear Till,

thanks for this great tutorial!

I will test it soon on a virtual machine at my server - please two questions


does everything also work with latest php 7.2 stable too?

if not, what would be the max. php 7.x release working with your tutorial?


at the debian update, does this update to latest 9.3 stable or is there anything additional to do? (I have only a 9.0 hoster image available) 

or is there any conflict maybe with your tutorial? (With 9.3)


Thanks in advance & kind regards,


By: stratege1401 at: 2018-01-14 03:03:31

First of all, i must say this is a very nice tutoriel.

Very clear, with almost no error, but with a few strange things:

----- For letsencrypt to work do as follow ------

nano /etc/apt/sources.list #add

deb stretch-backports main


apt-get update

ALWAYS go to and use drop down menu to match your server type. You will get the LATEST certbot with the LATEST vulnerability fix !!!

apt-get install python-certbot-apache -t stretch-backports  #wich is the latest certbot for Apache Debian 9.x script

use command line: ( this will fix the actual letsencrypt TLS-SNI vulnerability report, new certbot with fix is due soon, test release work so far ))

certbot --authenticator webroot --installer apache --rsa-key-size 4096 ( in order to have a A+ rate on SSLabscheck )

----- pureFTPD with LETSENCRYPT and not a dummy certificate -----

cat /etc/letsencrypt/live/servername/privkey.pem /etc/letsencrypt/live/servername/fullchain.pem > /etc/ssl/private/pure-ftpd.pem

In order to avoid an DH_params errors with pureFTPD restart 

openssl dhparam -out /etc/ssl/private/pure-ftpd-dhparams.pem 4096

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

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



nano /etc/apache2/sites-available


# SSL Configuration

  SSLEngine On

  SSLProtocol All -SSLv3

  SSLCertificateFile /etc/letsencrypt/live/servername/fullchain.pem  <-- letsencrypt of course

  SSLCertificateKeyFile  /etc/letsencrypt/live/servername/privkey.pem <-- letsencrypt of course


#SSLCertificateFile /usr/local/ispconfig/interface/ssl/ispserver.crt  <-- bad mojo :!

#SSLCertificateKeyFile /usr/local/ispconfig/interface/ssl/ispserver.key  <-- bad mojo :!

#SSLCACertificateFile /usr/local/ispconfig/interface/ssl/ispserver.bundle  <-- bad mojo :!


Have fun and keep up the good work !!!

By: Dominic at: 2018-01-15 23:39:28

Afterwards 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):Admin and Admin don't work :(

By: till at: 2018-01-16 11:28:01

Username and password are case sensitive, so 'admin' and 'Admin' are different users and passwords. Beside that, the ISPConfig installer requested you to enter a password or to accept the default one, which was shown by the installer. and that's the password that you have to enter, this can be different from 'admin'. If you don't remember the password that you have set, then reset it as described here:

By: Thomas at: 2018-01-17 07:45:26

Jailkit can no longer be reached via http, only https, so the new link is:

By: till at: 2018-01-17 09:06:11

Jailkit download works fine without issues here.

By: Dominic at: 2018-01-20 19:50:00

If you have problem with first login to 3.1 verision you need to restart your password:

By: Mike at: 2018-01-23 18:00:00

This tutorial needs to be updated because HHVM is now supporting Debian 9 Stretch.

By: gamal at: 2018-02-01 02:36:57


could you please help me

[email protected]:~# luarocks install lpcInstalling make: command not foundError: Build error: Failed building

By: Julien Julien at: 2018-03-03 19:20:58

I think you should do this apt-get install make

before the step where you install Metronome

By: Golibshoh at: 2018-02-24 07:15:37

ISPConfig was installed with an error:

not all services started, a timeout error, then manually I wanted to restart Apache but it did not work. The server now hangs and the ISPConfig page does not open.

By: Golibshoh at: 2018-02-24 07:19:08

PS: The error was in Amavis.

By: Golibshoh at: 2018-02-24 07:22:47

amavis.service: Start operation timed out. Terminating.

Failed to start LSB: Starts amavisd-new mailfilter.

amavis.service: Unit entered failed state.

amavis.service: Failed with result 'timeout'.

By: till at: 2018-02-24 09:41:57

Amavis fails when the hostname of your server is not configured correcty. That' the most common issue with amavis. Ensure that you configured the hostname on your server correctly before you install the server.

By: MikeC at: 2018-02-24 08:59:51

Nice! Thanks for the great tutorial! I did have to add 8080 to /etc/apache2/ports.conf to get ispconfig to answer.

By: Raham at: 2018-03-12 02:09:24

I  have installed the server based on this tutorial on newly created server. But when I run the ISPConfig install.php I got an error says: "This software cannot be installed on a server wich runs ISPConfig 2.x."

I doubled checked, there is nothing installed from ISPConfig2 or any other version on the server.


I wonder if you have any suggestions?

By: Till at: 2018-03-12 13:09:09

Probably you have a folder /root/ispconfig. Rename that folder.

By: cocovina at: 2018-03-12 08:04:45

"To prevent the error 'Error in accept: Too many open files' we will set higher open file limits for MariaDB now."Is there any correlation with OS ulimit value for "Open files" which is 1024 by default. Should be this ulimit -n increased also?

Thx for explanation.

By: Kai at: 2018-03-15 19:21:10

Is there a chance to update this guide? HHVM offers up-to-date repos since ever™, so integrating might be considered an idea

By: Saul at: 2018-03-18 13:25:18

The perfect server would use PowerDNS instead of BIND.

Just saying.

By: Brian DuBridge at: 2018-03-20 20:44:02

Awesome tutorial! It's making it possible for me to set up an email server, accelerate knowledge, and save a bunch of money, all at the same time!


By: Brian DuBridge at: 2018-03-20 21:48:05

Awesome tutorial! It's making it possible for me to set up an email server, accelerate knowledge, and save a bunch of money, all at the same time!

 mysql seems to be listening on port (I assume) 1964 on my DigitalOcean debian 9 server. Will this be an issue?   [email protected]:~# netstat -tap | grep mysqltcp6       0      0 [::]:mysql              [::]:*                  LISTEN      1964/[email protected]:~#  

By: Marko at: 2018-03-22 00:21:03

I followed the same guide, let me know if this line has caused trouble for you later in instalation?

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

in my case, digital ocean droplet

By: Federico Jaramillo at: 2018-03-26 21:47:55

La creacion de certificados Letsencrypt no funciona automaticamente.

Me funciono con esta guia.


By: till at: 2018-03-27 07:44:33

LE certificates can be created automatically by simply enabling the lets encrypt checkbox of the website in ISPConfig. The article link you posted is outdated and was made for ISPConfig version before LE was integrated into ISPConfig. The article mentions that btw.

By: SamTzu at: 2018-04-09 17:16:48

There is more power on this one page than in thousand other pages combined.Congrats...-Sam

By: Stefano at: 2018-05-12 18:55:09

Hello! Thanks for this very complete guide.


In past time I've installed ISPConfig on a Debian 7 and now on a new server with Debian 9. Thanks.


The only difference in the new Debian 9 is the disponibility of the four PHP versions: 5.6, 7.0, 7.1 and 7.2


Inconcepible, the new Debian 9 refuse to activate sites. I have try to create a new reseller too.


The one thing I have understand is that the folder /var/www/clients doesn't exist, I have also try to create "clients/client2" manually, then do the "chown root:client2 /var/www/clients/client2" but the system tell me doesn't knowledge client2 as a group...


Something strange. Reinstall all?

By: ZenMiser at: 2018-05-25 11:02:21

Hi, I followed the tutorial word for word on a linode. I am stuck at step 10:phpMyAdmin, and mcrypt. I get this error;

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

I checked my password as Till suggested;

From: till at: 2017-11-17 08:59:07Reply  The MySQL root password that you have set in the file /etc/mysql/debian.cnf seems to be wrong. It did not work. Any other suggestions?

By: Andreas Borowczak at: 2018-07-09 15:02:39

What`s wrong ? I have do it step by Step

Jul 9 14:54:50 bodi-minimal postfix/smtpd[27088]: warning: unknown[]: SASL LOGIN authentication failed: UGFzc3dvcmQ6

By: till at: 2018-07-09 15:30:37

There is nothing wrong with the guide. The message just means that you use a wrong username or password. The email username is the full email address. If you need further help, please post in the forum.

By: brody at: 2018-07-21 02:57:53

correct way to install python

apt-get build-dep libapache2-mod-python libapache2-mod-wsgi

By: Thorsten at: 2018-08-10 08:19:07

I get every time the dpkg error pure-ftp-mysql... Somebody got a tip for me?

By: till at: 2018-08-10 09:00:20

Not easy to help you without knowing which exact error you get. But you might want to compare the /etc/apt/sources.list file on your server with the one shown in this tutorial.

By: brody at: 2018-08-11 23:45:40

XMPP server does not work.. which tutitrial do we follow?


By: Vladimir Antonini at: 2018-08-21 16:23:41

The installation of ISPConfig on Raspbian 0S, of the Raspberry Pi 3, an ARM operating system, follows the same steps as the Debian 9 (Stretch) tutorial with Apache, BIND, Dovecot, PureFTPD and ISPConfig 3.1 (this tutorial) just by skipping the Quotas configuration step in fstab that it should not be done, because it will not work.

By: tux at: 2018-09-09 17:11:12


Following your tutorial, after ispconfig installation, I've got this error when trying to reach :

In apache error log,

[Sun Sep 09 19:05:49.221188 2018] [fcgid:warn] [pid 31184] (104)Connection reset by peer: [client] mod_fcgid: error reading data from FastCGI server[Sun Sep 09 19:05:49.221427 2018] [core:error] [pid 31184] [client] End of script output before headers: index.phpIn firefox I've got an internal server error 500

Thank you for your help


By: Panagiotis at: 2018-09-14 10:26:31

Just following your guide now.  In Step 17, there's a typo.  It should be:

rm -rf jailkit_2.19*

and not 

rm -rf jailkit-2.19*

Thanks for the great effort, and amazing guides!



By: pat76 at: 2018-09-18 17:52:00

good tutorial, but i have an issue with postfix. i just start getting emaisl that seem to come from my server itself. when i tried from (server = my hostname, Recipient email and Sender email = a valid email address hostes on this ispconfig installtion) i'm able to send this email without the need of any authentication. that weird, right ? shouldn't the line in force every email sender to be authenticated ? smtpd_sender_restrictions = check_sender_access regexp:/etc/postfix/ , permit_mynetworks, permit_sasl_authenticated, check_sender_access mysql:/etc/postfix/, check_sender_access regexp:/etc/postfix/ doen anyone have the same issue or a, that blocks the emails sent without authentification ( shoudl't work in a well configured server, right ?)

By: till at: 2018-09-18 18:45:38

The setup of your server is fine, you just made a mistake in your test. To test if s server is an open relay, you have to specify a recipient address that is not on the server (e.g. a gamil address). What you tested is not if someone can send through your server, you just tested if your server is configured correctly to receive emails for the local email address that you used as recipient. If you need additional help, please post in the forum

By: r_s at: 2018-10-23 09:39:27

The questions in step 8 are slightly different:


Enter current password for root (enter for none):

Set root password? [Y/n]


It does not ask 'Change the root password?'.


By: pinguinito at: 2018-10-25 19:00:05



is not working for my first login in ISPconfig

By: till at: 2018-10-31 15:33:53

The ISPConfig installer shows you the random password that was generated during install.

By: Nick at: 2018-10-31 15:13:24

 Hi till

I have a problem with Amavis. It ALWAYS crashes and leaves a bunch of emails in the mailq. When I say always I do mean it. This is the 4th server I have set up based on your excellent posts and every few hours I need to restart Amavis to unlock my mail queue.

By: till at: 2018-10-31 15:33:12

I've never had that issue on any server yet, maybe not enough RAM or something similar. Please make a post in the ispconfig forum here at howtoforge so we can help you to find out where the issue in your system is.

By: Warrior at: 2018-11-14 22:52:42

Hello, thank you. amazing tutoriali need help in step finish. I install ispconfig in my server, my file apache log write my hostname: address.localdomain: 8080, where can I rewrite the hostname?.my address: 8080

By: Bioshi at: 2018-11-15 10:45:19

Hello, I have a problem with roundcube, a priori I did not answer the question on the database, suddenly the access to the webmail is translated by a blank page, I can not find the solution to either revive the instalation or manually change the configuration. Can you help me ?