Build Your Own Personal Web Site Hosting Server

Build A Debian 11 Hosting Server Using Apache, BIND, Dovecot, MariaDb, PureFTPD and ISPConfig

Build a Debian 11 Web Site Hosting Server Using Apache, BIND, Dovecot, MariaDb, PureFTPD and ISPConfig Featuring PHPMyAdmin and RoundCube Web Applications with Multiple PHP Versions

Tutorial 3 Best if viewed by Tablet or Computer
  • Written By:
    Edward Kimmel
  • Published On:
    November 13th, 2022
    9:00 PM
  • Last Updated:
    December 9th, 2022
    9:00 PM

A Tutorial To Build A Debian 11 Web Site Hosting Server Using Apache, BIND, Dovecot, MariaDb, PureFTPD and ISPConfig - Page: 3

By: Edward Kimmel

Build A LAMP HTTP Server

2.01 Overview

  LAMP is an open source Web development platform that uses Linux (Debian 11) as the operating system, Apache as the Web server, MySQL (or MariaDb) as the relational database management system and PHP as the object-oriented scripting language. Let’s get Apache 2, MariaDb, and PHP 7.4 installed.

2.02 Install MariaDb Server

  MariaDB is an open-source database management system (DBMS), commonly used as an alternative for the MySQL portion of the popular LAMP (Linux, Apache, MySQL, PHP/Python/Perl) stack. It’s intended to be a drop-in replacement for MySQL and Debian now only ships with MariaDB packages. Install MariaDb with this command:

apt-get -y install dbconfig-common mariadb-client mariadb-server

2.03 Secure MariaDb Server

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


  Answer the questions as follows:

root@server:~# mysql_secure_installation


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
haven't set the root password yet, you should just press enter here.

Enter current password for root (enter for none):
OK, successfully used password, moving on...

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

You already have your root account protected, so you can safely answer 'n'.

Switch to unix_socket authentication [Y/n] y  <-- Hit Enter
Enabled successfully!
Reloading privilege tables..
 ... Success!

You already have your root account protected, so you can safely answer 'n'.

Change the root password? [Y/n] y  <-- Hit Enter
New password: MDbcfg4Me2@ccessU  <-- Hit Enter
Re-enter new password: MDbcfg4Me2@ccessU  <-- Hit Enter
Password updated successfully!
Reloading privilege tables..
 ... Success!

By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y  <-- Hit Enter
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] y  <-- Hit Enter
 ... Success!

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  <-- Hit Enter
 - 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] y  <-- Hit Enter
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

  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 = by adding a # in front of it.

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

  Comment out the bind-address = using a ‘#‘, the file should look like this:

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

  Close and Save the file.

2.04 Configure MariaDb Server

  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

  add these lines at the end of the file.

# End of file

# Prevents the error ‘Error in accept: Too many open files’ from occuring
mysql soft nofile 65535
mysql hard nofile 65535

  Close and save the file.

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

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

  Then add a new file inside:

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

  paste the following lines into that file:


  Save and close the file.

  Then we reload systemd and restart MariaDB:

systemctl daemon-reload

systemctl restart mariadb

  Now check that networking is enabled. Run

netstat -tap | grep mysql

  The output should look like this:

root@server:~# netstat -tap | grep mysql
tcp6 0 0 [::]:mysql [::]:* LISTEN 28599/mariadbd

2.05 Install Apache HTTP Server And PHP

  The Apache HTTP Server is free and open-source cross-platform web server software, released under the terms of Apache License 2.0. Apache is developed and maintained by an open community of developers under the auspices of the Apache Software Foundation. Originally based on the NCSA HTTPd server, development of Apache began in early 1995. Apache played a key role in the initial growth of the World Wide Web, and has remained popular since.

  PHP is an HTML-embedded scripting language. Much of its syntax is borrowed from C, Java and Perl with a couple of unique PHP-specific features thrown in. The goal of the language is to allow web developers to write dynamically generated pages quickly.

  The suEXEC feature provides users of the Apache HTTP Server the ability to run CGI and SSI programs under user IDs different from the user ID of the calling web server. Normally, when a CGI or SSI program executes, it runs as the same user who is running the web server.

  cgi-fcgi is a CGI/1.1 program that communicates with an already-running FastCGI application in order to respond to an HTTP request. cgi-fcgi is also capable of starting a FastCGI application.

  The FastCGI Process Manager (FPM) is an alternative to the FastCGI configuration with multiple enhancements. This is useful for high load websites. This tutorial will help you with the installation and configuration of PHP-FPM with Apache on your Debian 11 (Bullseye) Linux system.

  mcrypt is a crypting program, intended to be replacement for the old unix crypt(1). But it can do a lot more, since with its libmcrypt library it can encrypt and decrypt with the following algorithms: BLOWFISH, TWOFISH, DES, TripleDES, 3-WAY, SAFER-sk64, SAFER-sk128, SAFER+, OKI97, GOST, RC2, RC6, MARS, IDEA, RIJNDAEL-128, RIJNDAEL-192, SERPENT, RIJNDAEL-256, CAST-128 (known as CAST5), CAST-256, ARCFOUR, ENIGMA, PANAMA, XTEA and WAKE.

  The PHP Extension and Application Repository, or “PEAR”, is a repository of reusable PHP code which you can add to your website to easily enable certain functions such as SMTP Mail.

  ImageMagick is a free and open source, feature-rich, text-based, and cross-platform image manipulation tool used to create, edit, compose or convert bitmap images. It runs on Linux, Windows, Mac Os X, iOS, Android OS, and many other operating systems.

  Memcached is a free and open-source high-performance in-memory key-value data store. It is generally used to speed up applications by caching various objects from the results of API and database calls.

  Apache2, PHP, FCGI, suExec, Pear, mod_fcgid, PHP-FPM, imagemagick, memcached and mcrypt can be
installed as follows:

apt-get -y install apache2 apache2-utils apache2-doc libapache2-mod-php php7.4 php7.4-common php7.4-gd php7.4-mysql php7.4-imap php7.4-cli php7.4-cgi libapache2-mod-fcgid php-fpm htop apache2-suexec-pristine php-pear mcrypt imagemagick 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 php-memcache php-imagick php7.4-zip php7.4-mbstring memcached libapache2-mod-passenger php7.4-soap php7.4-fpm php7.4-opcache php-apcu libapache2-reload-perl php-memcache php-imagick memcached php-apcu

2.06 Enable PHP 7.4 FPM As Default

  You will see this notice after the program installation completes. I enabled PHP 7.4 FPM before continuing the processes.

NOTICE: Not enabling PHP 7.4 FPM by default.
NOTICE: To enable PHP 7.4 FPM in Apache2 do:
NOTICE: a2enmod proxy_fcgi setenvif
NOTICE: a2enconf php7.4-fpm
NOTICE: You are seeing this message because you have apache2 package installed.

  Enable PHP 7.4 FPM as default using these commands:

a2enmod proxy_fcgi setenvif

a2enconf php7.4-fpm

2.07 Configure Apache HTTP Server

  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 dav_fs dav auth_digest cgi headers actions proxy_fcgi alias

Now we need to restart Apache2 web server using this command:

systemctl restart apache2

  You will now configure Apache to pass all requests for files with the .php extension to the PHP wrapper through FastCGI.

  Configure PHP-FPM to use UNIX sockets instead of TCP. In this command, you will use grep to determine if the sockets are already being used. This command will search your php-fpm installation’s default pool configuration file for the setting:

grep -E '^\s*listen\s*=\s*[a-zA-Z/]+' /etc/php/7.4/fpm/pool.d/www.conf

  You should see the example output.

listen = /run/php/php7.4-fpm.sock

  If you see the above output, skip to ‘Check for configuration errors’, otherwise continue to the next step to manually configure your UNIX steps.

  If no output is returned, you will need to edit your PHP pool configuration file by adding a listen setting with the address on which to accept FastCGI requests. Add the line in the example file.

nano /etc/php/7.4/fpm/pool.d/www.conf

  add this line:

listen = /run/php/php7.4-fpm.sock
listen = /var/run/php/php7.4-fpm.sock

  If the listen = is not already uncommented, do so now.
  If the listen.allowed_clients = is not already uncommented, do so now.

listen.allowed_clients =
listen =

  Close and Save the file.

  Restart the php-fpm daemon for these changes to take effect.

systemctl restart php7.4-fpm

  Update your default Apache configuration file with the following basic settings for mod_fcgid. You may consider changing these settings based on your own needs.

nano /etc/apache2/apache2.conf
# Basic settings for mod_fcgid
AddHandler fcgid-script .fcgi .php .fpl
FcgidConnectTimeout 20
FcgidMaxRequestLen 268435456
FcgidMaxProcessesPerClass 10
FcgidIOTimeout 300

  Close and Save the file.

  Check for configuration errors. [Skip to Here]

apache2ctl configtest

  You should see this output:

root@server:~# apache2ctl configtest
Syntax OK

  Edit your FastCGI module’s configuration file to add the settings in the example file. Some of the example settings may already be included in your configuration. Add the missing settings.

nano /etc/apache2/mods-available/fcgid.conf
<IfModule mod_fcgid.c>
  FcgidConnectTimeout 20
  AddType application/x-httpd-php .php
  AddHandler application/x-httpd-php .php
  Alias /php7-fcgi /usr/lib/cgi-bin/php7-fcgi

  <IfModule mod_mime.c>
    AddHandler fcgid-script .fcgi

  Close and Save the file.

  Check for configuration errors.

apache2ctl configtest

  You should see this output:

root@server:~# apache2ctl configtest
Syntax OK

  If you received Syntax OK for both configuration checks, restart the Apache service:

systemctl restart apache2

2.08 Confirm Apache HTTP Server Online

  Check if PHP is working by creating and accessing a page with phpinfo() displayed. The following command will create a new file info.php in /var/www/html/info.php.

echo "<?php phpinfo(); ?>" > /var/www/html/info.php

  Then use a browser and check http://localhost/info.php or http://192/168/0/150/info.php and you should see a PHP version output.

Figure 3-5

2.09 Secure Apache HTTP Server

  To ensure that the server cannot be attacked through the HTTPOXY vulnerability, we will disable the HTTP_PROXY header in apache globally by adding the configuration file /etc/apache2/conf-available/httpoxy.conf.

Note: The vulnerability is named httpoxy (without ‘r’) and therefore the file where we add the config to prevent it is named httpoxy.conf and not httproxy.conf, so there is no ‘r’ missing in the filename.

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

  Paste the following content to the file:

<IfModule mod_headers.c>
     RequestHeader unset Proxy early

  Then Close and Save the file.

  Enable the module by running a2enconf httpoxy and then restart apache2:

a2enconf httpoxy

systemctl restart apache2

2.10 Install PhpMyAdmin

  PhpMyAdmin is an open-source web-based application that offers a web interface to directly manage and access MySQL or MariaDB databases from anywhere/remotely using a web browser. The user can use the web graphical user interface provided by it to interact with databases without having extensive knowledge of the commands. Hence, even a newbie with some knowledge of computers can manage database tables for querying data and manipulating individual parameters.

  Create folders for PHPMyadmin:

mkdir /usr/share/phpmyadmin

mkdir /etc/phpmyadmin

mkdir -p /var/lib/phpmyadmin/tmp

chown -R www-data:www-data /var/lib/phpmyadmin

touch /etc/phpmyadmin/htpasswd.setup

2.11 Download Latest Version Of phpMyAdmin

  Go to the /tmp directory and download the PHPMyAdmin sources:

cd /tmp


  Unpack the downloaded archive file and move the files to the /usr/share/phpmyadmin folder and clean up the /tmp directory.

tar xfz phpMyAdmin-5.2.0-all-languages.tar.gz

mv phpMyAdmin-5.2.0-all-languages/* /usr/share/phpmyadmin/

rm phpMyAdmin-5.2.0-all-languages.tar.gz

rm -rf phpMyAdmin-5.2.0-all-languages

2.12 Configure phpMyAdmin

  Create a new config file for PHPMyaAdmin based on the provided sample file:

cp /usr/share/phpmyadmin/ /usr/share/phpmyadmin/

  Open the config file with nano editor:

nano /usr/share/phpmyadmin/

  Set a secure password (blowfish secret) which must be 32 chars long:

* This is needed for cookie based authentication to encrypt password in
* cookie. Needs to be 32 chars long.
$cfg['blowfish_secret'] = ‘BlowFishSecret2KeepItSecret4MeNot4You’; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */

  Then add a line to set the directory which PHPMyAdmin shall use to store temporary files:

 * PHPMyAdmin shall use to store temporary files
$cfg['TempDir'] = '/var/lib/phpmyadmin/tmp';

  Now set the phpmyadmin user details in the configuration file:

  Scroll down until you see the lines below and edit them with the following information. Then uncomment the complete section by removing the ‘//’ that is in front of each line. Make it look like this:

[…] /* User used to manipulate with storage */ $cfg['Servers'][$i]['controlhost'] = 'localhost'; $cfg['Servers'][$i]['controlport'] = ''; $cfg['Servers'][$i]['controluser'] = 'pmauser'; $cfg['Servers'][$i]['controlpass'] = 'PMAcfg4Me2@ccessU'; /* Storage database and tables */ $cfg['Servers'][$i]['pmadb'] = 'phpmyadmin'; $cfg['Servers'][$i]['bookmarktable'] = 'pma__bookmark'; $cfg['Servers'][$i]['relation'] = 'pma__relation'; $cfg['Servers'][$i]['table_info'] = 'pma__table_info'; $cfg['Servers'][$i]['table_coords'] = 'pma__table_coords'; $cfg['Servers'][$i]['pdf_pages'] = 'pma__pdf_pages'; $cfg['Servers'][$i]['column_info'] = 'pma__column_info'; $cfg['Servers'][$i]['history'] = 'pma__history'; $cfg['Servers'][$i]['table_uiprefs'] = 'pma__table_uiprefs'; $cfg['Servers'][$i]['tracking'] = 'pma__tracking'; $cfg['Servers'][$i]['userconfig'] = 'pma__userconfig'; $cfg['Servers'][$i]['recent'] = 'pma__recent'; $cfg['Servers'][$i]['favorite'] = 'pma__favorite'; $cfg['Servers'][$i]['users'] = 'pma__users'; $cfg['Servers'][$i]['usergroups'] = 'pma__usergroups'; $cfg['Servers'][$i]['navigationhiding'] = 'pma__navigationhiding'; $cfg['Servers'][$i]['savedsearches'] = 'pma__savedsearches'; $cfg['Servers'][$i]['central_columns'] = 'pma__central_columns'; $cfg['Servers'][$i]['designer_settings'] = 'pma__designer_settings'; $cfg['Servers'][$i]['export_templates'] = 'pma__export_templates'; […]

  Save and close the file.

  Next, we create the Apache configuration file for PHPMyAdmin by opening a new file in nano editor:

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

  Paste the following config into the file and save it.

[…] # phpMyAdmin default Apache configuration Alias /phpmyadmin /usr/share/phpmyadmin <Directory /usr/share/phpmyadmin> Options FollowSymLinks DirectoryIndex index.php <IfModule mod_php7.c> AddType application/x-httpd-php .php php_flag magic_quotes_gpc Off php_flag track_vars On php_flag register_globals Off php_value include_path . </IfModule> </Directory> # Authorize for setup <Directory /usr/share/phpmyadmin/setup> <IfModule mod_authn_file.c> AuthType Basic AuthName "phpMyAdmin Setup" AuthUserFile /etc/phpmyadmin/htpasswd.setup </IfModule> Require valid-user </Directory> # Disallow web access to directories that don't need it <Directory /usr/share/phpmyadmin/libraries> Order Deny,Allow Deny from All </Directory> <Directory /usr/share/phpmyadmin/setup/lib> Order Deny,Allow Deny from All </Directory> […]

  Then Close and Save the file.

  Activate the configuration and restart Apache.

a2enconf phpmyadmin

systemctl restart apache2

  In the next step, we will configure the phpMyadmin configuration store (database).

2.13 Create MySQL Database For phpMyAdmin

  Log into MariaDB as root user:

mysql -u root -p

  Enter the MariaDB root password on request.

  In the MariaDB shell, create a new database for PHPMyAdmin:

MariaDB [(none)]> CREATE DATABASE phpmyadmin;

  Then create a new user:

MariaDB [(none)]> CREATE USER 'pmauser'@'localhost' IDENTIFIED BY 'PMAcfg4Me2@ccessU';

  Replace the password PMAcfg4Me2@ccessU with a secure password of your choice in the commands above and below, use the same password both times. Then grant the user access to this database and reload database permissions.

MariaDB [(none)]> GRANT ALL PRIVILEGES ON phpmyadmin.* TO ‘pmauser’@’localhost’ IDENTIFIED BY ‘PMAcfg4Me2@ccessU’ WITH GRANT OPTION;

  Refresh the database and exit MariaDb:


MariaDB [(none)]> EXIT;

  Finally, load the SQL tables into the database:

mysql -u root -p phpmyadmin < /usr/share/phpmyadmin/sql/create_tables.sql

  Then use a browser and check http://localhost/phpmyadmin or and you should see the phpMyAdmin log in screen.

Figure 3.6

  Your Debian 11 LAMP HTTP server is installed and configured. phpMyAdmin was installed to give you access to the MariaDb MySQL server. PHP 7.4 was installed as default. Now we need to build the Dovecot Mail Server next.