Perfect server: Debian 9 (stretch) V1.0

botond published 2019. 01. 21., H - 17: 40 time

The 1. page content


In this tutorial we will build the perfect server Debian 9 (Stretch). I will label this server with the 1.0 version number as it will add many more later, so I can easily refer to this installation with the version numbers. By the way, the server has already been created Debian 8 (Jessie), which can be viewed here.

The description of the Howtoforge's recipe based on it.

The server contains many components, so it takes longer to build. If you need a simpler server setup, I recommend using Debian 9 (Stretch) LAMP Server preparation.

Update: 2020-01-02:
A newer version of the server is ready: Perfect server: Debian 10 (Buster) V1.0


Installation requires the base system on which we build the server. Of this installer description can be found here, which also contains important settings.

Update Debian packages

As with all major installation work, we will now start by updating the packages. However, you need to configure your luggage storage properly before upgrading packages. If we hadn't done it at the end of the base system installation, then we are definitely replacing the expansion of luggage storage!

But if we're done with it, let's update it APT package manager database and packages:

apt-get update
apt-get upgrade

Configure / verify network and host name

Setting up a network and host name is also very important, so if you have previously installed a base system and are unsure, check the based on previous guidance.

The hostname of this server is:


And the full server name is:

hostname -f

So in this installer, I will go through these hostname settings. We use our own server name for installation.

Set the default shell

Debian 9 defaults to Dash shell, which is not appropriate for this installation, we need to migrate to Bashto:

dpkg-reconfigure dash

Set the default shell

Here, select not option. The system will then switch to symbolic links to Bash. This is important for later ISPConfig control panel installation, because it would not start without it.

System clock synchronization

The system clock should be synchronized with NTP protocol to keep accurate time on the server:

apt-get install ntp

Installing Postfix, Dovecot, MySQL, rkhunter, and Binutils

Install the components mentioned in the title in one apt-get command:

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

In Debian 9 a MySQL instead, MariaDB is in the distribution repository, so we will install this. Because of its high compatibility, it can completely replace MySQL.

However, if you still want to install MySQL, you can replace it later, in a different description.

Set Postfix

To run this command, the installer will start, and a few questions about the SMTP server (postfix) configuration will appear:

Debian 9 (Stretch) - Perfect Server Installation - Postfix General Configuration

If you are installing the server for live use, select "Internet Site" here.

When installing a home test environment, you can also select "Local only", but in this case, you can also select "Internet Site" because, for example, a relay host can send mail from your home computer to an external server.

Debian 9 (Stretch) Installing a Perfect Server - Postfix Configuration - Setting a Domain Name

Here, if you have set the host name correctly, it will be offered by the system FQDN laugh. Or, set yourself right domain name, from which we send out emails.

Then open the /etc/postfix/ file

nano /etc/postfix/

and make the TLS / SSL settings to look exactly like this part of the configuration file:

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

Save and then restart the postfix:

service postfix restart

Configuring MySQL / MariaDB

Let's secure our database configuration by disabling the test database and the anonymous user and their associated privileges:


It is also part of MariaDB's MySQL compatibility that the "mysql" names are retained in the commands, packages and configuration names, so everything can be configured as with MySQL.

Here are a few more questions to run:


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

Here you need to enter the root password for the database. Since no password has been set in the recent installation, press enter.

You will then be asked if you want to change your root password:

OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

You already have a root password set, so you can safely answer 'n'.

Change the root password? [Y/n]

Press "Y" and enter the new password and repeat. This sets the MariaDB root password.

He then describes that MariaDB has an anonymous user installed by default, which allows anyone to log in without a separate user account. It is intended for test use only and is recommended for removal under sharp use.

Here's how to answer the question accordingly:

Remove anonymous users? [Y/n]

Be sure to select "Y" when in use.

You will then be prompted to disable the root user remote access:

Disallow root login remotely? [Y/n]

Select "Y" here unless you need remote root access.

Remote access means, for example, trying to log in as a root client on a remote machine or directly connecting to a database running on the server as a root from a remote machine.
A phpMyAdmin logging is not remote logging because it runs on the server and is therefore a local connection wherever we use it. So if you disable remote root access with the "Y" option, you will still be able to log in as root as well on the phpMyAdmin interface.

You will then be asked to delete the "test" database, which is also created for test purposes and can be accessed by any user:

Remove test database and access to it? [Y/n]

Be sure to delete "Y" for live use.

 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n]

This will delete the body database and its associated permissions. You will then be asked to reload the privileges. Here, press "Y".

Above, we have disabled remote access for the root user. However, we now allow you to be able to connect to databases from other hosts by default, not just from localhost (except of course with root). To do this, open the /etc/mysql/mariadb.conf.d/50-server.cnf file:

nano /etc/mysql/mariadb.conf.d/50-server.cnf

Comment on the line beginning with "bind-address" and insert the line starting with "sql-mode" below to look like this section:

# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address           =


Let's save it.

Configure the root user defaults fileso that you do not have to type in the root password again at the command prompt.

nano /etc/mysql/debian.cnf

Enter the root password in both places (if the password contains special characters, include the apostrophe):

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

Let's save it.

Use the following command to change the MariaDB root user password authentication mode to native so that PHPMyAdmin can connect as root later (I split it into two lines, but this is a command):

echo "update mysql.user set plugin = 'mysql_native_password' where user='root';" | \
    mysql --defaults-file=/etc/mysql/debian.cnf

We no longer need to type the root password for the database, thanks to our defaults file. (It was the other way around in the original description, but it makes more sense to configure the defaults file first and use it immediately. So I swapped the two parts)

Then, increase the maximum number of files that MariaDB can open. Open the /etc/security/limits.conf file:

nano /etc/security/limits.conf

and add the following two lines to the end:

mysql soft nofile 65535
mysql hard nofile 65535

Create a new directory (/etc/systemd/system/mysql.service.d/):

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

Create a new file in the directory:

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

And let's put the following two lines:


Let's save it.

Restart Services

Update the systemdand restart MariaDB:

systemctl daemon-reload
service mysql restart

At the second command he throws a warning:

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

The first time I installed, I didn't know what to think of this message, so I started searching. In the Howtoforge forum, I found two questions about this, namely one here, and and another here. In both topics, the same message was asked, and in each case the original description was chosen by the author to ignore this message.

To confirm this, I have previously installed the same server on my desktop, written the same thing, but it works fine without any errors.

You can also check if the MySQL / MariaDB daemon is running:

netstat -nap | grep mysql

And the output must be something similar when properly operating:

tcp6       0      0 :::3306                 :::*                    LISTEN      13648/mysqld        
unix  2      [ ACC ]     STREAM     LISTENING     69347    13648/mysqld         /var/run/mysqld/mysqld.sock

And to keep you asleep, you can still search for running services:

systemctl | grep mariadb

And you have to give it something like this:

mariadb.service                   loaded active running   MariaDB 10.1.37 database server

So good from all angles. At first, of course, I was worried, so I was looking for these.

A next page continues with installing Amavisd, SpamAssassin, and ClamAV antivirus and SPAM filtering programs ...


This description consists of several pages: