Got any questions?
We do our best to respond within 2 business hours (GMT)
Written by: Aptive
Our team provide a guide on Apache security hardening and configuration. We provided this guide to help with practical configuration steps to help mitigate vulnerabilities and strengthen the Apache web servers default configuration.
Apache HTTP Server is one of the most widely used web server applications globally, powering a significant portion of websites and web applications. Due to its popularity, Apache is often a target for cyberattacks, making securing it a crucial aspect of maintaining a robust and reliable web environment.
This guide aims to provide practical, step-by-step instructions for hardening the Apache web server. By securing Apache, we reduce the surface area for potential attacks, protect sensitive data, and ensure the overall integrity of the system.
Security hardening involves a series of actions and configurations designed to eliminate or mitigate vulnerabilities. This guide covers key security practices, including the following:
By following these recommendations, administrators can significantly enhance the security posture of their Apache servers, reducing the risk of exploitation and ensuring that the server is resilient to various types of cyber threats.
In the sections that follow, we will walk through each of these areas in detail, offering actionable advice to help you secure your Apache web server effectively.
Regular updates are essential to maintaining the security of any system, including Apache HTTP Server. Vulnerabilities in older versions of Apache could be exploited by attackers, which is why it is crucial to ensure that the server is running the latest stable release. This section provides guidance on how to check the current Apache version and update it using common Linux package managers.
To check the version of Apache that is currently installed and running on your system, use the following command:
apache2 -v
This command will output the Apache version, along with other relevant information such as the build date.
Alternatively, for systems using httpd
(such as CentOS or Red Hat), the command is:
httpd -v
To ensure Apache is up to date, use the package manager for your Linux distribution. Below are the commands for the most common package managers.
For systems that use the apt
package manager, update the package index and upgrade Apache with the following commands:
sudo apt update
sudo apt upgrade apache2
To ensure Apache is fully upgraded, including dependencies, use:
sudo apt full-upgrade apache2
On Red Hat-based systems, which use yum
or dnf
, run the following commands to update Apache:
For yum
:
sudo yum update httpd
For dnf
(for newer versions of Fedora, CentOS, and RHEL):
sudo dnf update httpd
For other Linux distributions, refer to the relevant package manager’s documentation to perform the update. For example, zypper
for openSUSE or pacman
for Arch Linux.
After upgrading Apache, it is essential to restart the service to apply the updates. Use the following command:
sudo systemctl restart apache2
For Red Hat/CentOS systems:
sudo systemctl restart httpd
By keeping Apache up to date, you ensure that the server is protected against known patched vulnerabilities and is running optimally.
Apache’s log files are useful for tracking and analysing web server activity, providing critical insight into potential security incidents. By enabling and properly configuring Apache log files, administrators can monitor traffic patterns, detect malicious activity, and investigate security breaches. There are two primary types of log files in Apache: access logs and error logs.
Monitoring Traffic: Access logs record every request made to the server, including details about the client, requested resources, timestamps, and response status codes. This allows administrators to monitor who is accessing the server, what resources are being requested, and whether any suspicious activity is occurring.
Error Tracking: Error logs capture server-side issues, such as misconfigurations, missing files, or failed authentication attempts. Monitoring these logs helps to identify potential vulnerabilities or errors in the server configuration that could be exploited.
Security Auditing: Log files are invaluable in investigating security incidents. In the event of an attack, logs can provide information about the attack’s origin, its scope, and how it was executed, facilitating a more effective response and resolution.
Apache log files are typically enabled by default, but their configuration can be fine-tuned in the Apache configuration file (httpd.conf
or apache2.conf
depending on your system).
To enable and configure the access log, use the CustomLog
directive. Below is an example of enabling access logging:
CustomLog /var/log/apache2/access.log combined
This directive logs requests to the /var/log/apache2/access.log
file using the combined
log format, which includes details such as the client IP address, request method, and HTTP status code.
The error log can be configured with the ErrorLog
directive. For example:
ErrorLog /var/log/apache2/error.log
This will log server-side errors to /var/log/apache2/error.log
. Additionally, you can adjust the level of detail recorded using the LogLevel
directive, such as:
LogLevel warn
This setting ensures that only warnings and more severe messages are logged.
While local logs are useful, they may be vulnerable to tampering if the attacker gains control of the server. To enhance security, it is recommended to configure Apache to forward logs to an external logging server. This provides several benefits:
Protection from Tampering: Storing logs offsite ensures they cannot be altered or deleted by an attacker who gains access to the local server.
Centralised Monitoring: An external log server centralises logs from multiple servers, making it easier to analyse and correlate security events across an entire network or infrastructure.
Improved Compliance: For organisations that need to comply with regulations (e.g., GDPR, PCI-DSS), external log servers provide an additional layer of security by ensuring logs are retained securely and are not susceptible to internal manipulation.
To send logs to a remote server, you can use the TransferLog
directive with a network location, such as:
CustomLog "|/usr/bin/remote-log-server" combined
Alternatively, Apache supports logging via the syslog service, which can be configured to forward logs to an external syslog server:
ErrorLog syslog:local1
CustomLog syslog:local1
By configuring Apache to send logs to an external logging server, administrators are helping to ensure that logs are protected from local attacks and are available for more in-depth analysis.
Transport Layer Security (TLS) is a cryptographic protocol designed to ensure secure communication over a network. For Apache, configuring TLS is essential for protecting data transmitted between the server and clients, particularly sensitive information such as login credentials, payment details, and personal data.
To enable TLS, Apache requires a valid SSL/TLS certificate and the mod_ssl
module, which is responsible for providing SSL/TLS support. Below is a concise guide to configure TLS for Apache.
Ensure that the mod_ssl
module is enabled. This can be done with the following command on Ubuntu/Debian-based systems:
sudo a2enmod ssl
sudo systemctl restart apache2
For Red Hat/CentOS-based systems, mod_ssl
is often enabled by default. If needed, you can install it using:
sudo yum install mod_ssl
Once the module is enabled, configure Apache to use SSL/TLS by editing the SSL configuration file, typically located at /etc/apache2/sites-available/default-ssl.conf
or /etc/httpd/conf.d/ssl.conf
.
An example configuration for enabling HTTPS on Apache:
<VirtualHost *:443>
ServerAdmin [email protected]
DocumentRoot /var/www/html
ServerName www.example.com
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.key
SSLCertificateChainFile /etc/ssl/certs/example.com-chain.crt
<Directory /var/www/html>
</Directory>
</VirtualHost>
In this configuration:
SSLEngine on
enables SSL/TLS for the server.SSLCertificateFile
specifies the path to your SSL certificate.SSLCertificateKeyFile
points to the private key file.SSLCertificateChainFile
is used for intermediate certificates, if applicable.Ensure that port 443 (the default port for HTTPS) is open on your firewall to allow encrypted traffic.
Let’s Encrypt is a free, automated certificate authority that provides SSL/TLS certificates. It simplifies the process of obtaining and renewing certificates, which is essential for maintaining secure connections.
To use Let’s Encrypt, follow these steps:
Install Certbot: Certbot is a client for Let’s Encrypt that automates the process of obtaining and renewing certificates. To install Certbot on Ubuntu/Debian-based systems:
sudo apt update
sudo apt install certbot python3-certbot-apache
For CentOS/RHEL systems:
sudo yum install certbot python3-certbot-apache
Obtain a TLS Certificate: Once Certbot is installed, run the following command to automatically obtain and configure an SSL/TLS certificate for your domain:
sudo certbot --apache
This command will automatically:
Automating Certificate Renewal: Let’s Encrypt certificates are valid for 90 days. Certbot automatically sets up a cron job to renew the certificate before it expires. To manually test the renewal process, you can run:
sudo certbot renew --dry-run
To ensure a strong TLS configuration, consider implementing the following:
Disabling Weak Protocols and Ciphers: Disable older and vulnerable versions of SSL/TLS (such as SSLv2, SSLv3, and TLS 1.0/1.1) by adding the following to your SSL configuration:
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5
HTTP Strict Transport Security (HSTS): Enforce HTTPS with HSTS by adding the following header to your Apache configuration:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
For more detailed information on configuring SSL/TLS with Apache, refer to the official Apache documentation on SSL:
By enabling and correctly configuring TLS, Apache ensures that sensitive data remains encrypted and secure during transmission.
mod_evasive
is an Apache module designed to mitigate the risk of Denial of Service (DoS) and Distributed Denial of Service (DDoS) attacks by detecting and preventing abusive or excessive request patterns. By limiting the number of requests a single IP can make in a given time period, mod_evasive
helps to ensure that the server remains available and responsive, even under high traffic or attack conditions.
mod_evasive
provides the following benefits:
Mitigation of DoS and DDoS Attacks: The module can detect rapid, repeated requests from a single IP address that may indicate an attempt to overwhelm the server. It can then block or delay these requests, reducing the impact of the attack.
Prevention of Brute Force Attacks: Excessive login attempts or requests to specific URLs can be slowed or blocked, preventing attackers from exploiting vulnerable login forms or authentication mechanisms.
Customizable Request Limiting: Administrators can configure thresholds for requests per second, per minute, and per second for each IP, providing a flexible approach to blocking suspicious behaviour.
To install and configure mod_evasive
, follow the steps below:
Installation: On Ubuntu/Debian systems, install the mod_evasive
package:
sudo apt update
sudo apt install libapache2-mod-evasive
On CentOS/RHEL systems:
sudo yum install mod_evasive
Enabling mod_evasive: Once installed, enable the module by running:
sudo a2enmod evasive
sudo systemctl restart apache2
Configuration: The main configuration file for mod_evasive
is typically located at /etc/apache2/mods-available/evasive.conf
or /etc/httpd/conf.d/mod_evasive.conf
. Here, you can configure the thresholds for requests and the behaviour when a threshold is exceeded.
Example configuration to limit the number of requests:
<IfModule mod_evasive.c>
# Max number of requests per second per IP
DOSHashTableSize 3097
DOSPageCount 2
DOSSiteCount 50
# Time window for counting requests (in seconds)
DOSPageInterval 1
DOSSiteInterval 1
# Block for 30 seconds if the threshold is exceeded
DOSBlockingPeriod 30
# Log directory for denied requests
DOSLogDir "/var/log/apache2/mod_evasive"
</IfModule>
In this configuration:
DOSPageCount
limits the number of requests allowed per page within a specific interval (DOSPageInterval
).DOSSiteCount
limits the total number of requests allowed from a single IP address within a given time frame (DOSSiteInterval
).DOSBlockingPeriod
.Testing and Adjusting Configuration: After configuring mod_evasive
, ensure that Apache is restarted:
sudo systemctl restart apache2
Review the logs in /var/log/apache2/mod_evasive
to monitor blocked requests and adjust the thresholds as needed.
mod_evasive
offers an effective way to protect Apache from DoS and DDoS attacks by limiting the number of requests an IP address can make in a given period. This can significantly reduce the impact of malicious traffic and enhance the overall security and performance of the server.
For further details on configuring mod_evasive
, refer to the official Apache documentation:
To enhance the security and performance of an Apache web server, it is possible to configure various HTTP limits. These limits help to prevent abuse, control resource usage, and protect the server from being overwhelmed by excessive or malicious requests. Apache provides several directives that allow administrators to fine-tune these limits, ensuring a balance between performance and security.
MaxRequestWorkers (formerly `MaxClients)
This directive defines the maximum number of simultaneous requests that Apache can handle. Limiting this number ensures that the server does not run out of resources when facing high traffic or a denial of service attack.
Example configuration:
MaxRequestWorkers 150
This sets the maximum number of simultaneous requests to 150. When the limit is reached, additional requests will be queued or denied.
Timeout
The Timeout
directive specifies the maximum amount of time Apache will wait for certain events, such as receiving a request, sending data, or completing a request. This helps to prevent slow client attacks, where an attacker holds connections open for extended periods, consuming server resources.
Example configuration:
Timeout 60
This sets the timeout to 60 seconds.
KeepAlive
The KeepAlive
directive controls whether Apache will maintain persistent connections with clients. Enabling KeepAlive can improve performance by allowing multiple requests from a client to be sent over a single connection. However, leaving connections open for too long may exhaust server resources.
Example configuration:
KeepAlive On
KeepAliveTimeout 5
MaxKeepAliveRequests 100
In this example:
KeepAlive On
enables persistent connections.KeepAliveTimeout 5
sets the timeout for keeping connections open to 5 seconds.MaxKeepAliveRequests 100
limits the maximum number of requests per connection.LimitRequestBody
The LimitRequestBody
directive allows administrators to restrict the size of incoming request bodies, preventing large payloads that could be used in attacks such as file upload abuse or resource exhaustion.
Example configuration:
<Directory /var/www/uploads>
LimitRequestBody 10485760
</Directory>
This configuration limits the body size of requests to 10 MB (10,485,760 bytes) for the /var/www/uploads
directory.
LimitRequestFields
The LimitRequestFields
directive sets a limit on the number of HTTP request headers allowed in a request. Limiting the number of headers can help to prevent attacks that attempt to exhaust server resources by sending excessively large headers.
Example configuration:
LimitRequestFields 100
This limits the number of headers to 100.
LimitRequestFieldSize
The LimitRequestFieldSize
directive sets the maximum allowed size for any individual HTTP request header. This helps mitigate attacks that attempt to overload the server by sending oversized headers.
Example configuration:
LimitRequestFieldSize 8190
This sets the maximum size for headers to 8 KB (8,190 bytes).
MaxConnectionsPerChild
The MaxConnectionsPerChild
directive defines the number of connections a single child process will handle before it is terminated and replaced with a new process. This helps to reduce memory leaks and improve stability by limiting the number of requests processed by any given child process.
Example configuration:
MaxConnectionsPerChild 1000
This configuration terminates each child process after it has served 1,000 requests.
Configuring HTTP limits in Apache is essential for improving the security and stability of the server. By limiting the number of simultaneous requests, the duration of connections, and the size of incoming data, administrators can significantly reduce the risk of server overload and protect against various types of attacks, such as denial of service (DoS). Careful consideration of these settings will ensure that Apache runs efficiently while maintaining security.
For further details on Apache configuration directives, refer to the official Apache documentation:
One of the key steps in hardening an Apache server is conducting a thorough audit of the modules that are enabled. Apache, by design, is modular, meaning that numerous modules can be enabled or disabled based on the requirements of the server. However, any unnecessary or unused modules that remain enabled increase the server’s attack surface and introduce potential security vulnerabilities.
Minimising the Attack Surface: Each enabled module introduces additional functionality, and with this, new potential vectors for exploitation. Disabling unnecessary modules reduces the number of features available to attackers.
Improved Performance: Disabling unused modules can reduce resource consumption, improving overall performance by eliminating the overhead associated with unnecessary features.
Compliance and Security Best Practices: Many security frameworks and compliance standards recommend disabling unused services and features as a principle of least privilege.
To see which modules are currently enabled in Apache, use the following command on Ubuntu/Debian-based systems:
apache2ctl -M
On CentOS/Red Hat-based systems:
httpd -M
This will list all enabled modules. Review this list to identify modules that are not required for your specific use case.
Once identified, unused or unnecessary modules can be disabled. To disable a module, you can use the a2dismod
command on Ubuntu/Debian-based systems. For example, to disable the mod_status
module:
sudo a2dismod status
sudo systemctl restart apache2
On Red Hat/CentOS systems, you can comment out or remove the LoadModule
directive for the respective module in the Apache configuration files (usually located in /etc/httpd/conf/httpd.conf
or /etc/httpd/conf.d/
).
For example, to disable mod_userdir
, locate the following line in the configuration file and comment it out:
# LoadModule userdir_module modules/mod_userdir.so
After making changes, restart Apache to apply the configuration:
sudo systemctl restart apache2 # Ubuntu/Debian
sudo systemctl restart httpd # CentOS/RHEL
Regularly auditing and disabling unused Apache modules is a good first step in reducing the server’s attack surface and improving its overall security posture. By only enabling the modules necessary for your specific environment, you minimise the potential for vulnerabilities and ensure a more secure configuration.
For further details on managing Apache modules, refer to the official Apache documentation:
Configuring Apache to run under a dedicated, non-privileged user and group is a fundamental security measure that limits the impact of a potential compromise. By default, Apache runs under a specific user and group, typically www-data
(Debian/Ubuntu) or apache
(CentOS/RHEL). Restricting this user’s permissions ensures that, if an attacker exploits a vulnerability, their access remains confined to the Apache process and does not extend to the broader system.
Apache allows administrators to specify the user and group under which the server processes run. This is controlled via the User
and Group
directives in the main configuration file, typically located at:
/etc/apache2/apache2.conf
(Debian/Ubuntu)/etc/httpd/conf/httpd.conf
(CentOS/RHEL)To modify these directives, update the configuration file with a dedicated user and group:
User apache-secure
Group apache-secure
In this example:
apache-secure
is a restricted user created specifically for running the Apache process.apache-secure
ensures that only authorised processes can interact with Apache files.If a non-default user is required, create it using the following commands:
sudo groupadd apache-secure
sudo useradd -r -d /var/www -s /usr/sbin/nologin -g apache-secure apache-secure
The above performs:
apache-secure
.apache-secure
with no login shell (/usr/sbin/nologin
), preventing direct logins./var/www
, restricting unnecessary file system access.After modifying the configuration, restart Apache to apply the changes:
sudo systemctl restart apache2 # Debian/Ubuntu
sudo systemctl restart httpd # CentOS/RHEL
Ensuring that Apache operates under a dedicated, restricted user and group is a critical step in securing the web server. This measure prevents unauthorised privilege escalation and reduces the impact of potential exploits. Regularly auditing user permissions and maintaining the principle of least privilege further enhances security.
For further details on Apache user and group configuration, refer to the official documentation:
Restricting access to sensitive directories is a critical security measure to prevent unauthorised users from viewing or interacting with files that should not be publicly accessible. Apache provides several methods to block access to directories, ensuring that only legitimate requests are processed.
Apache uses the <Directory>
and <Location>
directives to control access. The recommended approach is to explicitly deny access to directories that should never be exposed.
Deny Access to All Users
To block access to a specific directory, such as /var/www/private
, modify the Apache configuration file (typically /etc/apache2/apache2.conf
for Debian-based systems or /etc/httpd/conf/httpd.conf
for CentOS/RHEL):
<Directory "/var/www/private">
Require all denied
</Directory>
This prevents all users from accessing the /var/www/private
directory.
Deny Access to the Root Directory (Global Restriction)
To apply a default-deny policy to all directories except explicitly allowed locations, use:
<Directory />
Require all denied
</Directory>
This blocks access to all directories unless specifically overridden by other <Directory>
directives.
Blocking Access to Sensitive Files
Certain files, such as .htaccess
, .env
, or database configuration files, should never be accessible via a web request. To prevent access, use the <Files>
directive:
<Files ~ "^\.(htaccess|htpasswd|env|git|svn)">
Require all denied
</Files>
This blocks access to hidden files commonly used for configuration or version control.
Blocking Access with .htaccess (Per-Directory Override)
If modifying the main configuration file is not feasible, use an .htaccess
file within a directory to block access:
Order allow,deny
Deny from all
Ensure that .htaccess
usage is enabled in Apache for this method to be effective.
After making configuration changes, restart Apache to apply them:
sudo systemctl restart apache2 # Debian/Ubuntu
sudo systemctl restart httpd # CentOS/RHEL
Blocking access to sensitive directories is a fundamental security control that reduces the risk of information disclosure and unauthorised access. Implementing a restrictive default policy and allowing access only where required strengthens the overall security posture of the Apache web server.
For further details, refer to the official Apache documentation:
By default, Apache may display a directory listing when an index
file (such as index.html
or index.php
) is missing from a directory. This can expose sensitive files, configuration backups, or scripts that attackers could exploit. Disabling directory listings is a fundamental security measure to prevent unauthorised access to such files.
Apache controls directory listings using the Options
directive, specifically the Indexes
option. To disable directory listings, remove or explicitly deny the Indexes
option in the configuration file.
Global Configuration (Recommended)
To disable directory listings server-wide, modify the main Apache configuration file, typically located at:
/etc/apache2/apache2.conf
(Debian/Ubuntu)/etc/httpd/conf/httpd.conf
(CentOS/RHEL)Locate any existing Options
directive and ensure -Indexes
is included:
<Directory /var/www/html>
Options -Indexes
</Directory>
Per-Site Configuration (Virtual Hosts)
If directory listing should only be disabled for a specific site, modify the corresponding virtual host file (usually in /etc/apache2/sites-available/
for Debian-based systems or /etc/httpd/conf.d/
for CentOS/RHEL):
<VirtualHost *:80>
DocumentRoot "/var/www/example.com"
<Directory "/var/www/example.com">
Options -Indexes
</Directory>
</VirtualHost>
Using .htaccess (Per-Directory Override)
If modifying the global configuration is not an option, an .htaccess
file can be used to disable directory listings on a per-directory basis. Create or edit the .htaccess
file in the target directory and add:
Options -Indexes
After modifying the configuration, restart Apache for changes to take effect:
sudo systemctl restart apache2 # Debian/Ubuntu
sudo systemctl restart httpd # CentOS/RHEL
Disabling directory listings is a fundamental security measure that prevents unauthorised users from accessing file structures. Enforcing -Indexes
globally or at a per-site level ensures sensitive files remain hidden, reducing the risk of exploitation.
For further details, refer to the official Apache documentation:
By default, Apache includes server version details in HTTP response headers and error pages. This information, such as the Apache version, operating system, and installed modules, can be leveraged by attackers to identify vulnerabilities and craft targeted exploits. Disabling the “Server” header minimises information leakage, reducing the risk of reconnaissance attacks.
Apache provides two directives to control the exposure of server information:
ServerSignature Off
ServerTokens Prod
Server
response header to only display Apache
, without version details or OS information.To disable the “Server” header, modify the Apache configuration file (typically /etc/apache2/apache2.conf
for Debian-based systems or /etc/httpd/conf/httpd.conf
for CentOS/RHEL) and add the following directives:
ServerSignature Off
ServerTokens Prod
After making these changes, restart Apache to apply the configuration:
sudo systemctl restart apache2 # Debian/Ubuntu
sudo systemctl restart httpd # CentOS/RHEL
To check if the “Server” header is still exposing information, use curl
:
curl -I http://yourdomain.com
The response should now contain a minimal Server: Apache
header without version details.
Disabling Apache’s “Server” header is a straightforward yet effective security measure to reduce information leakage. By configuring ServerSignature Off
and ServerTokens Prod
, administrators can prevent unnecessary exposure of version details, making it more difficult for attackers to conduct reconnaissance.
For further details, refer to the official Apache documentation:
Entity Tags (ETags) are response headers used for web caching and content validation. However, they can inadvertently expose inode numbers and other system metadata, potentially aiding attackers in fingerprinting a server’s file system structure. Disabling ETags enhances security by reducing the risk of information leakage.
Apache allows ETags to be disabled using the FileETag
directive. To prevent ETags from being included in responses, modify the Apache configuration file (typically /etc/apache2/apache2.conf
for Debian-based systems or /etc/httpd/conf/httpd.conf
for CentOS/RHEL) and add:
FileETag None
Alternatively, if using .htaccess
for per-directory control, add the same directive:
<IfModule mod_headers.c>
Header unset ETag
</IfModule>
FileETag None
After modifying the configuration, restart Apache for the changes to take effect:
sudo systemctl restart apache2 # Debian/Ubuntu
sudo systemctl restart httpd # CentOS/RHEL
To confirm that ETags are disabled, inspect the HTTP response headers using curl
:
curl -I http://yourdomain.com
The response should no longer contain an ETag
header.
Disabling ETags in Apache eliminates unnecessary metadata exposure, reducing the risk of fingerprinting attacks. By setting FileETag None
, administrators can improve security while maintaining efficient caching strategies.
For further details, refer to the official Apache documentation:
.htaccess
in ApacheThe .htaccess
file is used to override Apache configurations on a per-directory basis. While it provides flexibility, enabling .htaccess
introduces security risks, as it allows users to modify server behaviour and potentially introduce misconfigurations or vulnerabilities. Disabling .htaccess
improves security and performance by enforcing centralised configuration management.
.htaccess
?.htaccess
files in every directory, reducing processing overhead..htaccess
Apache controls .htaccess
usage via the AllowOverride
directive. To disable .htaccess
, modify the Apache configuration file (typically /etc/apache2/apache2.conf
for Debian-based systems or /etc/httpd/conf/httpd.conf
for CentOS/RHEL) and set:
<Directory "/var/www/html">
AllowOverride None
</Directory>
This ensures that .htaccess
files in the specified directory (and subdirectories) are ignored.
After modifying the configuration, restart Apache to apply the changes:
sudo systemctl restart apache2 # Debian/Ubuntu
sudo systemctl restart httpd # CentOS/RHEL
.htaccess
DirectivesIf .htaccess
is currently in use, transfer necessary rules to the main Apache configuration. For example, if .htaccess
contains:
RewriteEngine On
RewriteRule ^oldpage\.html$ newpage.html [R=301,L]
Move these rules into the appropriate <VirtualHost>
block within the Apache configuration:
<VirtualHost *:80>
DocumentRoot "/var/www/html"
<Directory "/var/www/html">
AllowOverride None
</Directory>
RewriteEngine On
RewriteRule ^oldpage\.html$ newpage.html [R=301,L]
</VirtualHost>
.htaccess
..htaccess
files.Disabling .htaccess
enforces a centralised and secure configuration model, reducing risks associated with user-defined overrides. Migrating necessary .htaccess
rules to the main Apache configuration ensures security and performance improvements.
For further details, refer to the official Apache documentation:
Common Gateway Interface (CGI) and Server-Side Includes (SSI) allow dynamic content execution on an Apache web server. While these features are useful in certain environments, they introduce significant security risks, including remote code execution (RCE) vulnerabilities, unauthorised script execution, and server compromise. Disabling CGI and SSI mitigates these risks by preventing the execution of untrusted scripts.
Apache handles CGI scripts via the mod_cgi
or mod_cgid
modules. To disable CGI execution, ensure these modules are not loaded:
For Debian-based systems (e.g., Ubuntu):
sudo a2dismod cgi
For CentOS/RHEL, comment out or remove the LoadModule
directive in /etc/httpd/conf/httpd.conf
:
#LoadModule cgi_module modules/mod_cgi.so
Additionally, ensure the following directive is set to prevent CGI execution within specific directories:
<Directory "/var/www/html">
Options -ExecCGI
</Directory>
SSI allows the inclusion of server-side scripts within HTML files, which can be exploited for code injection attacks. To disable SSI, remove the Includes
option from Apache’s configuration:
<Directory "/var/www/html">
Options -Includes
</Directory>
Additionally, ensure that mod_include
is disabled:
For Debian-based systems:
sudo a2dismod include
For CentOS/RHEL, comment out or remove the LoadModule
directive in /etc/httpd/conf/httpd.conf
:
#LoadModule include_module modules/mod_include.so
After modifying the configuration, restart Apache to apply the settings:
sudo systemctl restart apache2 # Debian/Ubuntu
sudo systemctl restart httpd # CentOS/RHEL
Unless CGI or SSI is explicitly required, disabling them is a crucial security measure to prevent unauthorised script execution. By restricting these features, administrators can significantly reduce the risk of exploitation and improve the overall security posture of an Apache web server.
For further details, refer to the official Apache documentation:
Security headers provide an additional layer of protection against common web vulnerabilities by instructing browsers on how to handle content, enforce security policies, and mitigate attack vectors. The OWASP Secure Headers Project outlines key HTTP security headers that should be considered with performing security hardening for Apache to strengthen a web applications security posture.
The following headers should be configured within the Apache server to improve security:
Strict-Transport-Security (HSTS)
Enforces HTTPS and prevents downgrade attacks.
Recommended configuration:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Ensure the website supports HTTPS before enabling HSTS.
Content-Security-Policy (CSP)
Restricts allowed sources for scripts, styles, and other resources to prevent XSS attacks.
Example configuration:
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self'"
Adjust the policy to fit specific application needs.
X-Content-Type-Options
Prevents MIME-type sniffing, mitigating content-based attacks.
Recommended setting:
Header always set X-Content-Type-Options "nosniff"
X-Frame-Options
Protects against clickjacking attacks by preventing the site from being embedded in an iframe.
Example configuration:
Header always set X-Frame-Options "SAMEORIGIN"
Alternative values: DENY
(blocks all framing) or ALLOW-FROM uri
(allows specific origins).
Referrer-Policy
Controls how much referrer information is sent to other websites.
Example configuration:
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Permissions-Policy
Restricts browser features (e.g., camera, microphone, geolocation) to prevent misuse.
Example configuration:
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
Security headers can be added within the Apache configuration file (/etc/apache2/apache2.conf
or /etc/httpd/conf/httpd.conf
) or inside a specific virtual host configuration:
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self'"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
</IfModule>
After modifying the configuration, restart Apache to apply the settings:
sudo systemctl restart apache2 # Debian/Ubuntu
sudo systemctl restart httpd # CentOS/RHEL
Use curl
or online tools such as Mozilla Observatory to verify that the security headers are correctly applied:
curl -I https://yourdomain.com
Implementing security hardening measures is essential, but regular external security testing is required to validate their effectiveness. Web app pen tests simulate real-world attack scenarios to identify misconfigurations, vulnerabilities, and potential entry points that may be overlooked. Additionally, automated website vulnerability scanning can provide continuous monitoring and vulnerability scanning to detect emerging threats. Combining both manual and automated testing ensures a robust security posture, helping organisations address weaknesses before they can be exploited.
Enabling these security headers in Apache strengthens the server against common web threats, including XSS, clickjacking, and data leakage. Proper implementation ensures compliance with security best practices while enhancing user protection.
For further details, refer to:
Document changelog.