Skip to main content

Apache configuration

Configuring Apache properly is essential for website security. Generally, pre-packaged webserver software (e.g. Bitnami instances) are not designed to have every security measure enabled, as some measures need to be carefully decided by the server administrator to prevent e.g. blocking access to legitimate pages.

There are several important things to be aware of when configuring Apache on your webservers.

httpd.conf and .htaccess files

Apache can be configured from two main files: the primary httpd.conf file in the apache/conf directory, and individual .htaccess files in specific directories where you want to override the httpd.conf file.

Avoid using .htaccess files

For both security and performance reasons, htaccess files should be avoided. Outside of shared hosting situations, it's generally a sign of bad website design when .htaccess files are used, as they are often used to deny access to folders containing credentials or private data that should not be in the server's DocumentRoot in the first place. Even when a particular folder has to be in the document root, denying access to it from the httpd.conf is less error prone, as it doesn't rely on a htaccess file being present in the given folder.

The use of htaccess files also makes Apache slower, as it has to check all of the individual directories for .htaccess files when serving a page to check if there are any rules it needs to override. 

The AllowOverride directive

Within <Directory> tags, that specify how Apache serves documents within a given directory, this directive decides if any htaccess file within the DocumentRoot can override the main httpd.conf file. The settings are All (any .htaccess file can override the main settings) or None (disable .htaccess files altogether).

Options (Indexes, FollowSymLinks)

The Options Directive is mostly used to specify Indexes and occasionally FollowSymLinks.

Options Indexes means that when a user browses to a directory in your website, rather than a specific page, a directory of the folder contents is shown to the user. This is usually not desirable behaviour; using Options -Indexes prevents this, returning a 403 Forbidden error to the user instead.

Files and FilesMatch directives

The <Files> and <FilesMatch> directives let you specify what should occur for specific files or files that match a regular expression. They are commonly used to deny access to particular files or types of files.

Files Directive

Usually used to control access to one particular file. Example:

# Deny access to the ".gitignore" file in the DocumentRoot.
<Files ".gitignore">
    Require all denied
</Files>
FilesMatch directive

Used to control access to groups of files, or files of a particular type or with other attributes you can test for. Example:

# Deny access to any file that ends with .zip, .rar, etc.
<FilesMatch "\.(zip|rar|log|pem|crt|key)$">
    Require all denied
</FilesMatch>

# Deny access to any file whose name ends in error_log, or access_log, etc.
<FilesMatch "(error_log|access_log|apache_error_log|apache_access_logs)$">
    Require all denied
</FilesMatch>

HTTP Headers

Permissions Policy

The permissions policy header restricts which aspects of a user's browser your website has access to. The point is that you can deny access to anything you don't intend to use, so that code bugs or malicious attacks cannot make use of those features. Example:

# Prevents your site from accessing these aspects of a user's browser/computer.
Header always set Permissions-Policy "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()"

Content Security Policy

The content security policy determines what content is allowed to be loaded on your webpages, in the context of external sources like other websites. Example:

# Set the Content-Security-Policy header. This is a critical defence
# against XSS attacks.
Header always set Content-Security-Policy "default-src 'self' localhost:* *.desertedchateau.com *.stripe.com *.cloudflare.com; style-src *.desertedchateau.com localhost:* 'unsafe-inline'; connect-src ws: *.desertedchateau.com *.stripe.com; img-src localhost:* *.desertedchateau.com *.stripe.com *.cloudflare.com data:;"

This allows you to control which external resources (e.g. scripts loaded from other websites) are allowed to run. If a particular content source (e.g. connect-src) is not specified, the policy uses the default-src to determine if the content is allowed. Be aware that an incorrectly configured CSP can cause some elements on your website not to work, e.g. if it comes from a host or protocol not explicitly identified in your CSP.

Strict-Transport-Security

This header enforces the use of HTTPS instead of insecure HTTP connections (and is the preferred and more secure method, versus using the mod_rewrite engine to rewrite HTTP urls to HTTPS ones). Example:

Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"

The max age tells the user's browser to cache this instruction for two years, includeSubDomains applies the header to all subdomains of your website. More information is here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security 

X-Frame-Options

This header determines if external websites may embed content from your website in iFrames. Depending on your use case, you may or may not want to allow this (other websites embedding iFrames that load your website in their own website will cause extra server load, as the iFrame content are still loaded by your webservers). Example:

# Do not allow any part of the site to be embedded in an iFrame.
Header always set X-Frame-Options "DENY"

Advanced configuration

For more advanced aspects of configuring Apache (such as the mod_rewrite engine), see this article.