GUIDE / SECURITY / APACHE / LINUX

Apache Web Server Hardening 2026 – HTTPS, TLS 1.3, Security Headers and Secure Cookies

A practical Apache 2.4 hardening guide for Debian: HTTP-to-HTTPS, TLS 1.3, HSTS, secure cookies, CSP, security headers, minimal information disclosure, restrictive directory rules and safe testing.

HTTP→HTTPS→TLS 1.3→HEADERS→MONITORING

1. Hardening is a layered model

Apache hardening is not about copying every directive from a checklist. The goal is a deliberate combination of minimal attack surface, modern TLS, restrictive permissions, browser security headers, useful logs and regular patching.

2. Enable only required modules

The baseline mainly needs `ssl`, `headers` and `rewrite`. On Debian they can be enabled with `a2enmod`. Do not load modules simply because they are commonly installed.

sudo a2enmod ssl headers rewrite
sudo apachectl configtest

3. Redirect HTTP to HTTPS

Port 80 can be dedicated to redirects. `mod_rewrite` preserves the host and requested path. Apache documents HTTPS forcing as a standard rewrite use case.

<VirtualHost *:80>
    RewriteEngine On
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

4. HTTPS VirtualHost

The TLS VirtualHost contains the certificate, key, TLS policy, headers and DocumentRoot. Private keys must never live in the webroot.

5. Enforce TLS 1.3

`SSLProtocol TLSv1.3` accepts TLS 1.3 only. This is intentionally strict and can exclude legacy clients, scanners and embedded devices. For controlled modern environments it is a strong option; for unknown client populations, `TLSv1.2 TLSv1.3` is often more pragmatic.

SSLProtocol TLSv1.3

6. TLS 1.3 ciphers

TLS 1.3 cipher selection differs from TLS 1.2. Modern OpenSSL versions provide the standard TLS-1.3 ciphers. Do not blindly paste old TLS-1.2 cipher lists into a TLS-1.3 configuration.

7. HSTS

`Strict-Transport-Security` tells browsers to use HTTPS for the domain. `includeSubDomains` should only be enabled when every relevant subdomain supports HTTPS. `preload` is a long-term commitment and should not be enabled casually.

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

8. Secure cookies

Session cookies should use `Secure`, `HttpOnly` and an appropriate `SameSite` value. Apache can add missing attributes with `mod_headers`, but this is defense in depth rather than a replacement for correct application code.

Header always edit Set-Cookie ^(.*)$ "$1; Secure; HttpOnly; SameSite=Lax"

9. X-Content-Type-Options

`X-Content-Type-Options: nosniff` is a simple and useful baseline against unwanted MIME sniffing.

10. Referrer-Policy

`strict-origin-when-cross-origin` reduces unnecessary referrer information on cross-origin requests and is a solid baseline for many sites.

11. Content-Security-Policy

CSP can significantly reduce XSS impact but must match the application. Start with `Content-Security-Policy-Report-Only`, analyze violations and tighten the policy gradually.

Header always set Content-Security-Policy-Report-Only "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'"

12. Permissions-Policy

Unused browser features such as camera, microphone and geolocation can be disabled to reduce the capabilities available to unwanted content.

13. Reduce server information

`ServerTokens Prod`, `ServerSignature Off` and `TraceEnable Off` reduce unnecessary disclosure and disable TRACE. They do not replace patching.

ServerTokens Prod
ServerSignature Off
TraceEnable Off

14. Directory rules

`Options -Indexes` prevents directory listings. `AllowOverride None` prevents unexpected `.htaccess` overrides. Keep sensitive directories outside the webroot where possible.

<Directory /var/www/example>
    Options -Indexes
    AllowOverride None
    Require all granted
</Directory>

15. Permissions and uploads

Apache should only read what it needs to serve. Write access inside the DocumentRoot is particularly risky. Upload directories should preferably not be executable web paths.

16. PHP-FPM separation

For PHP applications, PHP-FPM with `mod_proxy_fcgi` often provides a cleaner separation than enabling PHP execution indiscriminately.

17. Certificates and Let’s Encrypt

Certificates are useful only when renewal and reloads work reliably. Monitor expiry and test the renewal path.

18. Test configuration and TLS

Run `apachectl configtest` before every reload. Use `openssl s_client` for local TLS checks and an external TLS scanner for an independent client-side view.

apachectl configtest
systemctl reload apache2
openssl s_client -connect example.com:443 -tls1_3

19. Logging and Fail2ban

Access and error logs are essential for diagnosis. Log rotation prevents disk exhaustion. Fail2ban can mitigate repeated attack patterns but is not a replacement for a firewall or strong authentication.

20. A complete baseline

The configuration below combines the major hardening elements into a practical starting point for a Debian Apache website. Adjust domain names, paths and application-specific requirements.

/var/log/apache2/access.log
/var/log/apache2/error.log

# Beispiel: Status prüfen
systemctl status apache2

21. What not to enable blindly

TLS 1.3-only, HSTS with subdomains and CSP can affect real clients. Test first, then enforce. Browsers cache HSTS, and complex applications should initially use CSP Report-Only.

Complete hardening baselineApache 2.4 / Debian
# Apache 2.4 / Debian – Hardening baseline
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    RewriteEngine On
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

<VirtualHost *:443>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

    # Strict TLS 1.3 policy. Use TLSv1.2 TLSv1.3 if legacy clients are required.
    SSLProtocol TLSv1.3
    SSLCipherSuite TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256

    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    Header always set X-Content-Type-Options "nosniff"
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
    Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"

    ServerTokens Prod
    ServerSignature Off
    TraceEnable Off

    <Directory /var/www/example>
        Options -Indexes
        AllowOverride None
        Require all granted
    </Directory>

    # Defense in depth; applications should ideally set cookie attributes themselves.
    Header always edit Set-Cookie ^(.*)$ "$1; Secure; HttpOnly; SameSite=Lax"

    # Start CSP in Report-Only mode and adapt it to the application:
    # Header always set Content-Security-Policy-Report-Only "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'"

    ErrorLog ${APACHE_LOG_DIR}/example-error.log
    CustomLog ${APACHE_LOG_DIR}/example-access.log combined
</VirtualHost>

22. Conclusion

A strong baseline combines minimal attack surface, HTTPS, modern TLS, secure cookies, security headers, restrictive permissions, limited version disclosure, logs, updates and a tested rollback path.

Practical rule: Never enable TLS, HSTS, CSP or cookie-header policies blindly in production. Validate syntax, reload safely, test the application and keep a rollback path.
Practical check: Before production changes, back up configuration, validate syntax, reload safely, test functionality, inspect logs and keep a documented rollback path.
About Sille-Solutions