Apache HTTP Server, stands as one of the most widely used and trusted web server software globally. Born in the mid-1990s, Apache has since dominated the digital landscape, powering a significant portion of websites worldwide. Renowned for its stability, flexibility, and extensibility, Apache is an open-source solution that offers a robust platform for hosting dynamic web content. Its modular architecture allows for seamless integration with various programming languages and technologies, making it a versatile choice for developers and administrators alike. With its strong security features and continuous updates, Apache remains a cornerstone of the internet, enabling the smooth delivery of web content to users across the globe.
The Apache installation process on Linux is the famous apt install:
apt-get install apache2
Apache configuration files are located in /etc/apache2.
ports.conf
Specifies the ports Apache listens on for incoming connections. For example, we can add Listen 8080
. After restarting the service, we will also be able to access port 8080 in the browser.
sites-available
Holds configuration files for individual websites or virtual hosts. These files define settings like domain names and access rules. Whenever we want to expose a website we must add it to this directory. Let’s create a simple demonstration file:
<VirtualHost *:80>
# Domain to which the site will respond
ServerName www.example.local# The path of the website itself
DocumentRoot /var/www/html
# Log verbosity level
LogLevel info
# Path to logs
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# It is recommended to separate log files when you have many sites:
# ErrorLog ${APACHE_LOG_DIR}/example_error.log
# CustomLog ${APACHE_LOG_DIR}/example_access.log
</VirtualHost>
Just creating the file in sites-available is not enough. We have to create a symbolic link inside sites-enabled pointing to the file.
sites-enabled
To do this, we pass the path of the example.conf file to the ln command, within the sites-enabled
directory.
cd /etc/apache2/sites-enabledsudo ln -s /etc/apache2/sites-available/example.conf
# or
a2ensite example.conf
Disabling Verbose Error Messages
When we cause an error, typing a path that does not exist, we can see the banner containing the versions of the Apache service. This is a problem because it signals to attackers which exploit to look for. So we don’t want this banner, we’re going to make life a little more difficult for hackers: to do this, we need to edit the file /etc/apache2/conf-available/security.conf
Right from the start in the file, we have the ServerTokens
option, set to the value OS
, which sends verbose information in the response header to the client. The ideal is to define it as Prod
:
Another important setting is to leave the AllowTrace
option set to Off
. The TRACE method in HTTP allows a client to retrieve the headers that are sent with the request as they are received by the server. While TRACE can be useful for debugging and diagnostics purposes, it also presents a security risk, primarily due to Cross-Site Tracing (XST) attacks.
If your website has sensitive directories such as the infamous .git
, it is a matter of good sense to deny access to them. We can do this through the RedirectMatch
option:
If we wanted, we could also define a CSP, but as that’s not the focus of this article, that’s for next time!
Keep in mind that just like in the case of sites-enabled
, we need to have a symbolic link in conf-enabled
.
In addition to removing verbose error messages and implementing other settings, it is a good security practice to change the default Apache user (www-data), creating a non-privileged user.
sudo useradd -s /usr/sbin/nologin -d /var/www/html --system ap-usergroupadd --system ap-group
cat /etc/group | grep "ap-group"
usermod -g <Group ID> ap-user
Then we set this user in the /etc/apache2/envvars file to run Apache processes.
And finally, we define the new user as the “owner” of the /var/www/html
directory:
sudo chown ap-user:ap-group /var/www/html
The /etc/apache2/mods-available/dir.conf
file defines the “default” files, which Apache will look for within the /var/www/html
folder.
cat /etc/apache2/mods-available/dir.conf
We need to define a file with one of these names (or add a new name in the configuration file) inside /var/www/html:
cd /var/www/htmlmv index.html index.html.lock
mv index.nginx-debian.html index.nginx-debian.html.lock
echo "<?php phpinfo() ?>" >> index.php
# If PHP isn't already installed, you can install with the following command:
#
sudo apt-get install php8.2 -y
systemctl restart apache2
phpinfo()
is a PHP function that outputs information about the PHP configuration of a server, including installed modules, environment variables, and current settings.
After reloading the page in the browser, we can see that the phpinfo()
function has been executed.
Disable Directory Listing
Directory listing refers to the automatic display of the contents of a directory when no default index file (like index.html or index.php) is present. This allows users to see a list of files and subdirectories within a directory when accessing it via a web browser. To disable this flaw, we need to edit the /etc/apache2/apache2.conf file:
Just remove the Indexes
option, between Options
and FollowSymLinks
.
Ok, if we try to access a website that doesn’t have the index (or the default file), it will return the 403 Forbidden
status.
What if we want to add more than one website but take advantage of the same server? Well, it’s possible. To do this, we just add more sites, following the same steps as before. But how will the server know which site to serve?
For this, there is the Apache rewrite
module, which is already installed by default. We can enable it with the following command:
a2enmod rewrite
And then, after creating and adding new sites, creating our own user and our own directory, and defining it in the site settings, we will use the concept of virtual host.
Vhosts
Virtual hosts, or vhosts, are configurations on web servers that allow hosting multiple websites or web applications on a single server. Each vhost has its own domain name and settings, enabling efficient management of multiple sites on one server.
To configure a virtual host, we need to edit the /etc/hosts
file on Linux, or C:\Windows\System32\drivers\etc\hosts
on Windows (Requires administrative permission to be edited). In both cases, the syntax is the same:
# Syntax: <address> <domain>
#
# Examples:
102.54.94.97 rhino.acme.com # source server
38.25.63.10 x.acme.com # x client host
Remembering that it is always necessary to restart the Apache service after any configuration.