Web Servers 3d ago 5 views 4 min read

How to configure Apache mod_headers for security headers

Add HSTS, X-Frame-Options, and Content-Security-Policy headers to your Apache server using mod_headers. Follow these steps to harden your site against common web attacks on Ubuntu 24.04 or AlmaLinux 9.

Roy S
Updated 2h ago
Sponsored

Cloud VPS — scale in minutes

Instantly deploy SSD cloud VPS with guaranteed resources, snapshots and per-hour billing. Pay only for what you use.

You will enable the mod_headers module and configure essential security headers like Strict-Transport-Security and X-Content-Type-Options. These steps apply to Apache 2.4.x running on Ubuntu 24.04, Debian 12, AlmaLinux 9, Rocky 9, or CentOS Stream 9.

Prerequisites

  • Root access or a user with sudo privileges.
  • Apache installed (httpd or apache2 package).
  • mod_headers module available (usually pre-installed).
  • A basic understanding of virtual host configuration.

Step 1: Enable the mod_headers module

Locate the configuration directory for Apache modules. On Debian-based systems, this is /etc/apache2/mods-available, while on RHEL-based systems, it is typically /etc/httpd/modules.d or the modules are loaded directly in the main config. Ensure the headers module is enabled.

sudo a2enmod headers

For AlmaLinux or CentOS, run the following command to enable the module:

sudo a2enmod headers

If you are on a RHEL-based system where a2enmod does not exist, check if the module is already loaded in the main httpd.conf file:

sudo grep -r "LoadModule headers" /etc/httpd/conf.modules.d/

You will see output similar to this if the module is active:

LoadModule headers_module modules/mod_headers.so

If the module is not loaded, add the line to /etc/httpd/conf.modules.d/00-base.conf or /etc/httpd/conf.d/headers.conf:

LoadModule headers_module modules/mod_headers.so

Step 2: Configure global security headers

Create a new configuration file for security headers. This file will apply to all virtual hosts unless overridden. Use a descriptive name like 00-security-headers.conf to ensure it loads early.

sudo nano /etc/apache2/conf.d/00-security-headers.conf

Add the following directives to the file. These headers protect against clickjacking, MIME sniffing, and ensure HTTPS usage:

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https:; connect-src 'self'"
Header always set X-Permitted-Cross-Domain-Policies "none"
Header always set X-Download-Options "noopen"
Header always set X-Download-Options "noexec"

Save and exit the file. On AlmaLinux or CentOS, the path might be /etc/httpd/conf.d/00-security-headers.conf. The directives are identical, but the file path changes based on your distribution.

Step 3: Apply changes to specific virtual hosts

Some headers, like Content-Security-Policy, should be set per virtual host to avoid conflicts with third-party scripts. Open your virtual host configuration file, usually located in /etc/apache2/sites-available/ or /etc/httpd/conf.d/.

sudo nano /etc/apache2/sites-available/000-default.conf

Inside the VirtualHost block, you can override or add specific headers. For example, to allow inline styles for a specific site:


    ServerName example.com
    DocumentRoot /var/www/html

    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"

Ensure the block closes properly. If you have multiple sites, copy this block and adjust the ServerName and CSP directives for each domain.

Step 4: Restart Apache

Apply the new configuration by restarting the web server. This ensures all changes take effect immediately.

sudo systemctl restart apache2

For AlmaLinux or CentOS:

sudo systemctl restart httpd

Verify that Apache restarted without errors by checking the status:

sudo systemctl status apache2

You should see "active (running)" in the output.

Verify the installation

Test the headers by visiting your server from a browser or using curl. Curl is preferred for automation and scripting.

curl -I http://your-domain.com

Replace "your-domain.com" with your actual domain or IP address. The response headers should include:

HTTP/1.1 200 OK
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https:; connect-src 'self'

If you see these headers in the response, the configuration is successful. If any header is missing, check the Apache error logs for syntax errors.

Troubleshooting

If Apache fails to start after adding headers, check the error log for syntax errors. Run the following command to test the configuration:

sudo apache2ctl configtest

For AlmaLinux or CentOS:

sudo httpd -t

If the test returns "Syntax OK", restart Apache. If it reports an error, review the output carefully. Common issues include typos in directive names or missing quotes around values.

Another issue is conflicting headers. If you see duplicate headers, ensure you are not setting the same header in multiple files. Use "Header unset" to remove existing headers before setting new ones:

Header unset Strict-Transport-Security
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

If you use a reverse proxy like nginx in front of Apache, ensure headers are not being stripped or modified by the proxy. Check the proxy configuration to pass headers correctly.

Finally, if you are using a cloud provider like AWS or Google Cloud, ensure the load balancer or CDN is not overriding these headers. Configure the CDN to forward or preserve the security headers set by Apache.

Sponsored

Powerful Dedicated Servers — Linux & Windows

Bare-metal performance with SSD storage, DDoS protection and 24/7 expert support. Ideal for production workloads, databases and high-traffic sites.

Tags: securityUbuntuAlmaLinuxApacheHeaders
0
Was this helpful?

Related tutorials

Comments 0

Login to leave a comment.

No comments yet — be the first to share your thoughts.