LAMP - Apache

Set up Apache

This manual page is based on Apache 2.4.46.

According to our example from the installation guide, we want to set up a LAMP test server for developers that is directly connected to the workstation PC via LAN. Beyond that, for security reasons, there should be no connection for the server to a local network or even to the Internet.
The only exception is that the server will be connected to the Internet temporarily and exclusively for system and software updates via a second network interface.

Apache in the file system

Debian has fully integrated the Apache files into the file system according to their function:

It is important to distinguish between the variables ServerRoot and DocumentRoot.

ServerRoot is the configuration directory, i.e. /etc/apache2/.
DocumentRoot contains the web page data, so /var/www/html/.

Connection to the server

The connection between the test server and the PC is placed in the IPv4 network segment 192.168.3.xxx, while the PC’s Internet connection is outside this network segment. The data used are:

server
IP: 192.168.3.1/24
name: server1.org
alias: www.server1.org

PC
IP: 192.168.3.10/24
name: pc1

We make a backup copy of the */etc/hosts* file on the server and on the PC and add the necessary lines to both.

Next, in NetworkManager, we enter the data for the server in the fields outlined in red. The method is changed from “Automatic (DHCP)” to “Manual” and in the address fields we enter the values mentioned at the beginning.

Server - Data entry in NetworkManager

Additionally, in the tab “General”, the option “Automatically connect with priority” should be activated.
Accordingly, we set the appropriate settings on the PC for the used LAN interface.

On the PC, we test the connection in the console with

$ ping -c3 www.server1.org

and, if successful, we immediately check the function of Apache by entering http://www.server1.org/index.html in the address line of the web browser.

The Apache welcome page with “It works!” should appear.

Apache configuration

The configuration files and directories are located in the ServerRoot directory /etc/apache2/.
The central configuration file is apache2.conf. It is usually not edited because many configurations are in separate files. Activation and deactivation is done via sym links. This has the advantage that a number of different configurations are available and only the required ones are included.

The configuration files are text files, which are created or edited with an editor and root permissions. The name of the file may be arbitrary, but the file extension must be “.conf”. The valid directives that may be used in the configuration files are described in detail in the Apache documentation.

The files are located in the directories

/etc/apache2/conf-available,
/etc/apache2/mods-available, and
/etc/apache2/sites-available.

Your activation links can be found in

/etc/apache2/conf-enable,
/etc/apache2/mods-enable, and
/etc/apache2/sites-enable.

To enable or disable a “.conf” file, we use a2enconf and a2disconf. This creates or removes the activation links. The command

a2enconf NAME_OF_FILE.conf 

activates the configuration. Deactivation is done accordingly with:

a2disconf NAME_OF_FILE.conf 

We proceed in the same way for modules and virtual hosts with the commands a2enmod, a2ensite and a2dismod, a2dissite.

The Apache web server reads the changed configuration with the command

systemctl reload apache2.service

Now we return to our LAMP test server for developers and adjust the configuration to the server data.

  1. /etc/apache2/apache2.conf file

    It is one of the few exceptions for editing the apache2.conf. We add the following line at the beginning of the “Global configuration” section:

    ServerName 192.168.3.1

    This tells the Apache web server the IP address where the development project should be reachable and suppresses redirections to IP 127.0.1.1 with error messages.

  2. New sites file

    With the text editor of our choice, we create the file
    /etc/apache2/sites-available/server1.conf, e.g.

    mcedit /etc/apache2/sites-available/server1.conf

    Then we insert the following content, save the file, and exit the editor.

    <VirtualHost *:80>
    ServerName server1.org
    ServerAlias www.server1.org
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error_server1.log
    CustomLog ${APACHE_LOG_DIR}/access_server1.log combined
    </VirtualHost>

    Then we change the configuration to the new VirtualHost and announce the changes to the Apache web server:

# a2ensite server1.conf 
   Enabling site server1.
[...]

# a2dissite 000-default.conf 
   Site 000-default disabled.
[...]

systemctl reload apache2.service

Users and permissions

The Apache web server runs with the USER.GROUP www-data.www-data" and DocumentRoot belongs to “root.root” immediately after installation.
To give users write permissions to the files contained in DocumentRoot, a new group should be created specifically for this purpose. It does not make sense to use the existing group www-data because Apache runs with the rights of this group.
We name the new group work.

With CMS

If a content management system (software for collaborative editing of website content) is added, we prepare DocumentRoot accordingly:

  1. Create the group and assign it to the user.

    groupadd work
    adduser USERNAME work
    chgrp work /var/www/html

To activate the new permissions you have to log out and log in again, or use the newgrp command as user.

$ newgrp work
  1. Set SGID bit for DocumentRoot
    so that all added directories and files inherit the group work.

    chmod g+s /var/www/html
  2. Adjust owner and file permissions
    so that unauthorized people don’t get access and the Apache web server runs properly.
    Let’s look at the current permissions:

    # ls -la /var/www/html
    total 24
    drwxr-sr-x 2 root work 4096 Jan 9 19:32 .
                 (DocumentRoot with SGID bit)
    drwxr-xr-x 3 root root 4096 Jan 9, 19:04 ...
                 (The parent directory /var/www)
    -rw-r--r-- 1 root work 10701 9 Jan 19:04 index.html
    -rw-r--r-- 1 root work 20 Jan 9, 19:32 info.php

    For DocumentRoot we change the owner to “www-data”, give write permission to the group, and revoke read permission from everyone else as well (all recursively).

    chown -R www-data /var/www/html
    chmod -R g+w /var/www/html
    chmod -R o-r /var/www/html

    We check the result again.

    # ls -la /var/www/html
    total 24
    dr-xrws--x 2 www-data work 4096 Jan 9 19:32 .
    drwxr-xr-x 3 root root 4096 Jan 9 19:04 ...
    -rw-rw---- 1 www-data work 10701 9 Jan 19:04 index.html
    -rw-rw---- 1 www-data work 20 9 Jan 19:32 info.php

    Now only members of the group work have write permission in DocumentRoot. Apache web server can read and write the files, all others are denied access.

  3. Disadvantages of these settings

    When creating new directories and files below DocumentRoot, the owner is the respective user and not www-data. This prevents the Apache web server from reading the files.
    The solution is a Systemd Path Unit, which monitors changes below DocumentRoot and adjusts the owner and file permissions. (See the example in the Systemd-Path manual page.)

Without CMS

For static websites, a content management system is often not necessary and only constitutes another security risk and increased maintenance effort. In addition to the settings made before, the write permission to DocumentRoot can be revoked from the Apache web server to strengthen security because in case an attacker finds a hole in Apache, this will not give him write permission to DocumentRoot.

chmod -R u-w /var/www/html

Security - Apache Standard

Important safeguards are already included in the file /etc/apache2/apache2.conf by default.

The following three directives prevent access to the root file system and then release the two directories used by the Apache web server, “/usr/share” and “/var/www”.

<Directory />
    Options FollowSymLinks
    AllowOverride None
    Require all denied
</directory>

<Directory /usr/share>
    AllowOverride None
    Require all granted
</directory>

<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</directory>

The options “FollowSymLinks” and “Indexes” constitute a security risk and should be changed unless absolutely necessary. See below.

The following directive disables the display of the files .htaccess and .htpasswd.

<FilesMatch "^\.ht">
    Require all denied
</FilesMatch>

Security - other configurations

Use HTTPS

Without HTTPS no website project can be launched today.
How to obtain a certificate is described, for example, in detail and in an easy-to-understand manner on the website wpbeginner.

First we create the necessary folders inside DocumentRoot:

cd /etc/apache2/
/etc/apache2/# mkdir ssl ssl/certs ssl/private

In these we put the certificate file server1.org.crt and the private key server1.org.key.

Then we secure the directories against unauthorized access.

/etc/apache2/# chown -R root.root ssl
/etc/apache2/# chmod -R o-rwx ssl
/etc/apache2/# chmod -R g-rwx ssl
/etc/apache2/# chmod u-w ssl/certs/server1.org.crt
/etc/apache2/# chmod u-w ssl/private/server1.org.key

Finally, we use the ls command to check:

/etc/apache2/# ls -la ssl
   total 20
   drwx------ 5 root root 4096 Jan 25 18:17 .
   drwxr-xr-x 9 root root 4096 Jan 25 18:43 ...
   drwx------ 2 root root 4096 Jan 25 18:16 certs
   drwx------ 2 root root 4096 Jan 25 18:16 private

/etc/apache2/# ls -l ssl/certs
   -r-------- 1 root root 1216 25 Jan 15:27 server1.org.crt

Security Tips

Integration in Apache2

The ssl module is activated in Apache by default. It is enough to edit the file /etc/apache2/sites-available/server1.conf.

The extended server1.conf then has the following content:

<VirtualHost *:80>
    ServerName server1.org
    ServerAlias www.server1.org
    Redirect / https://server1.org/
</VirtualHost>

<VirtualHost *:443>
    ServerName server1.org
    ServerAlias www.server1.org
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error_server1.log
    CustomLog ${APACHE_LOG_DIR}/access_server1.log combined

    SSLEngine on
    SSLProtocol all -SSLv2 -SSLv3
    SSLCertificateFile /etc/apache2/ssl/certs/server1.org.crt
    SSLCertificateKeyFile /etc/apache2/ssl/private/server1.org.key

    <Directory "/var/www/html">
        Order deny,allow
        Deny from all
        Allow from 192.168.3.10
        Allow from 192.168.3.1
    </directory>

    <FilesMatch "\.(cgi|shtml|phtml|php)$">
        SSLOptions +StdEnvVars
    </FilesMatch>

    <Directory /usr/lib/cgi-bin>
        SSLOptions +StdEnvVars
    </Directory>
</VirtualHost>

In case our finished project is to be located at a hoster without access to ServerRoot (this is the rule), we can add a rewrite statement to the .htaccess file in DocumentRoot or create the file with the rewrite statement.

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

Sources Apache

apache.org - Documentation
apache.org - Configuration files
apache.org - SSL Howto
Let’s Encrypt - A nonprofit Certificate Authority

Last edited: 2022/04/03