The Best Price for IPv4/IPv6 Lease – Any RIR & Any Geo-LocationOrder Now
Hostperl

Configure Apache Security Headers on AlmaLinux VPS

By Raman Kumar

Share:

Updated on Jun 30, 2026

Configure Apache Security Headers on AlmaLinux VPS

Why HTTP Security Headers Matter for Your Hosted Sites

Most VPS hardening guides jump straight to firewalls and SSH keys — and those matter. But a surprising number of live hosting environments skip Apache security headers entirely, leaving browsers with no guidance on how to handle scripts, frames, or mixed content. That gap is exploitable, and it's easy to fix.

HTTP response headers like Content-Security-Policy, X-Frame-Options, and Strict-Transport-Security are instructions Apache sends to the browser alongside every page load. They don't change your application code. They don't require a CDN. You add them once in your Apache config, and every site on that server benefits immediately.

This tutorial walks through configuring the most important security headers on an AlmaLinux VPS running Apache 2.4. It's aimed at hosting customers who manage their own server — whether you're running a stack for client sites, a WooCommerce store, or a multi-site cPanel environment where you have root access to the underlying config.

Before You Start: Check Your Environment

This guide assumes AlmaLinux 8 or 9 with Apache 2.4 installed. If you're on AlmaLinux 9, the config paths are the same. Check your Apache version first:

httpd -v

You'll also need the mod_headers module enabled. On AlmaLinux it's included by default, but worth confirming:

httpd -M | grep headers

If you see headers_module (shared) in the output, you're set. If not, enable it by uncommenting the relevant line in /etc/httpd/conf.modules.d/00-base.conf and restarting Apache.

You'll also want SSL already working on your domains. Security headers like HSTS are only meaningful over HTTPS. If you haven't set that up yet, the tutorial on configuring multi-domain SSL with Certbot covers the process, and the same Certbot workflow applies on AlmaLinux.

Where to Add Security Headers in Apache

You have three sensible places to add headers on AlmaLinux:

  • /etc/httpd/conf/httpd.conf — applies server-wide, affects all virtual hosts
  • /etc/httpd/conf.d/your-site.conf — per-virtual-host configuration
  • .htaccess — per-directory, if AllowOverride All is set

For most VPS setups hosting multiple client sites, per-virtual-host config is the right choice. It gives you control per domain without risking unintended behaviour on other sites. The examples below use a virtual host config file at /etc/httpd/conf.d/example.conf.

Step 1 — Add the Core Security Headers

Open your virtual host config file:

nano /etc/httpd/conf.d/example.conf

Inside the <VirtualHost *:443> block, add the following Header directives. Place them after your DocumentRoot and ServerName lines:

# Prevent clickjacking
Header always set X-Frame-Options "SAMEORIGIN"

# Stop MIME-type sniffing
Header always set X-Content-Type-Options "nosniff"

# Enable XSS filter in older browsers
Header always set X-XSS-Protection "1; mode=block"

# Control referrer data sent to other sites
Header always set Referrer-Policy "strict-origin-when-cross-origin"

# Enforce HTTPS for 1 year (only add once SSL is working)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

# Restrict browser features
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"

Save the file. Test your Apache configuration before reloading:

apachectl configtest

You should see Syntax OK. Then reload:

systemctl reload httpd

Step 2 — Add a Content-Security-Policy Header

CSP is the most powerful header here — and the one most likely to break something if you're not careful. It tells browsers exactly which sources are allowed to load scripts, styles, images, and fonts on your page.

Start with a report-only policy to catch violations before enforcing:

Header always set Content-Security-Policy-Report-Only \
  "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; report-uri /csp-report"

Run this for a few days and check your server logs for CSP violations. If your site loads Google Fonts, embeds YouTube, or uses a CDN for scripts, you'll need to add those origins to the relevant directives before switching to enforcement mode.

Once you're confident, switch to the enforcing header:

Header always set Content-Security-Policy \
  "default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data:; font-src 'self' https://fonts.gstatic.com"

Adjust the origins to match your actual site. There's no universal CSP that fits every WordPress install or custom app — you have to tune it per site.

Step 3 — Remove Information-Leaking Headers

By default, Apache broadcasts its version number in every response. That's useful for attackers looking to match your server against known CVEs. Turn it off:

nano /etc/httpd/conf/httpd.conf

Find or add these two lines:

ServerTokens Prod
ServerSignature Off

ServerTokens Prod reduces the Server header to just Apache with no version. ServerSignature Off removes the version footer from error pages. Reload Apache after saving.

If you're running PHP, also check /etc/php.ini for expose_php = Off — it suppresses the X-Powered-By: PHP/8.x header that otherwise appears in responses.

Step 4 — Apply Headers Across Multiple Virtual Hosts

If you're managing several client domains on the same VPS, repeating these headers in every virtual host config gets messy. A cleaner approach is to create a shared include file.

Create /etc/httpd/conf.d/security-headers.conf:

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 Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"

Apache will load all .conf files in /etc/httpd/conf.d/ automatically. These directives will apply globally, across every virtual host, as long as no individual virtual host config overrides them. For per-site CSP policies, keep those in each site's own config file.

This approach works well for agencies running client sites on a single Hostperl VPS. You get a consistent security baseline across all domains without touching every virtual host manually.

Verify Your Headers Are Working

After reloading Apache, check what your server is actually sending. From the command line:

curl -I https://yourdomain.com

Look for your headers in the output. You should see lines like:

strict-transport-security: max-age=31536000; includeSubDomains
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
content-security-policy: default-src 'self'; ...

If a header is missing, check your Apache error log at /var/log/httpd/error_log for config issues. Also confirm the request hit the correct virtual host — a misconfigured ServerName can cause Apache to serve a different virtual host than expected.

For a quick visual check, use securityheaders.com. It grades your response headers and flags anything missing or misconfigured.

Common Pitfalls on AlmaLinux Apache Setups

A few things trip people up on AlmaLinux specifically:

  • SELinux blocking header writes: AlmaLinux ships with SELinux enforcing by default. If Apache isn't sending your headers despite correct config, check ausearch -m avc -ts recent for denials. The fix is usually a context or boolean adjustment, not disabling SELinux entirely.
  • Headers on HTTP-only virtual hosts: HSTS should only appear on HTTPS virtual hosts. If you add it to a port 80 block, it either has no effect or confuses browsers during certificate renewals.
  • Conflicting headers from PHP or application code: If your application sets its own X-Frame-Options header and Apache sets another, the browser sees duplicates. Use Header always set (which replaces existing headers) rather than Header set (which doesn't override).
  • CSP blocking your CMS assets: WordPress, in particular, loads scripts from wp-includes and sometimes from external CDNs. A strict CSP will break admin areas and front-end plugins. Test in report-only mode first, always.

For broader server hardening context alongside headers, the UFW firewall setup guide and the post on VPS security for hosting customers in 2026 cover the surrounding layers well.

Maintenance: Keep Headers Current

Security header recommendations evolve. The X-XSS-Protection header, for instance, is now deprecated in modern browsers — Chrome and Firefox have removed their built-in XSS auditors. Keeping it doesn't hurt, but it's no longer a meaningful protection layer.

Permissions-Policy is still maturing, with new feature names being added as browser APIs expand. Review your headers every few months, particularly after major Apache or PHP upgrades. A quick re-run through securityheaders.com takes about two minutes and shows you if anything new has become standard practice.

If you're running a multi-tenant setup or managing sites for clients, it's worth documenting your baseline header config in a shared include file and noting which sites have custom CSP overrides. That kind of operational clarity saves time when you're troubleshooting a broken site at short notice.

Running Apache on AlmaLinux for client sites or production workloads? Hostperl VPS plans are provisioned with full root access, clean AlmaLinux images, and no resource contention from oversold shared environments. If you're scaling beyond a single VPS, our dedicated server hosting gives you the full hardware layer for high-traffic sites or agency stacks that need consistent performance.

Frequently Asked Questions

Do these headers work on AlmaLinux 9 as well as AlmaLinux 8?

Yes. The Apache config paths and directives are the same on both. AlmaLinux 9 ships with Apache 2.4.x and mod_headers included. The only difference is that AlmaLinux 9 uses a stricter SELinux policy by default, so watch for AVC denials if headers aren't appearing.

Will adding a CSP header break my WordPress site?

Possibly, if you start with an enforcement policy. WordPress loads scripts and styles from multiple sources, including the admin area. Always start with Content-Security-Policy-Report-Only and monitor logs for violations before switching to enforcement mode.

What's the difference between Header set and Header always set?

Header always set adds the header to all responses, including error pages and redirects. Header set only adds it to successful 2xx responses. For security headers, use Header always set.

Should I add HSTS to HTTP (port 80) virtual hosts?

No. HSTS is only meaningful over HTTPS. Adding it to a port 80 block either has no effect or causes confusion during cert renewals. Keep HSTS exclusively in your <VirtualHost *:443> block.

How do I check if mod_headers is active without restarting Apache?

Run httpd -M | grep headers. If you see headers_module (shared), the module is loaded and active. No restart needed just to check.