---
title: "P18: Web Server Hardening: nginx and Apache"
canonical: https://openvapt.com/academy/p18.html
html: https://openvapt.com/academy/p18.html
site: OpenVAPT, https://openvapt.com/
license: OpenVAPT Source-Available Licence 1.3, https://openvapt.com/legal/licence-text.html
modified: 2026-10-16
version: 0.1.0-alpha.6
---

# P18: Web Server Hardening: nginx and Apache

Reading nginx.conf and apache2.conf the way an assessor does: the dozen directives that decide what a server reveals, which TLS it speaks, and which files it will hand out.

- Level: Practitioner
- Time: about 30 minutes
- Read first: P4, P5

## You Will Be Able To

- Find the effective value of a directive across nginx.conf, conf.d, sites-enabled and Apache's Include tree.
- Explain why banner hiding, directory listing and TRACE are low-cost fixes worth making.
- Apply the Mozilla intermediate TLS profile and OCSP stapling to both servers.
- Deny dot-prefixed paths so repository and environment files are never served.

## Where the Configuration Really Lives

nginx reads one file, nginx.conf, and follows every include directive; Debian puts sites in sites-enabled and fragments in conf.d. Apache reads apache2.conf (Debian) or httpd.conf (RHEL) and follows Include and IncludeOptional. A directive set in a fragment can override the main file, so the assessor's view is the merged tree, which nginx -T and apachectl -t -D DUMP_CONFIG print. OpenVAPT builds the same merged view from the files, following includes only under the server's own configuration folder.

The configuration view complements the live probes in WEB-HDR and WEB-EXP. A probe sees one response; the file shows the rule and the line to fix, and it finds a weak setting before a site is published.

## Banners, Listings and Methods

server_tokens off in nginx and ServerTokens Prod with ServerSignature Off in Apache drop the version from the Server header and error pages. Hiding the version does not fix old software, but there is no reason to publish it (OWASP WSTG-INFO-02). autoindex on and Options Indexes turn folders without an index page into file listings. Debian's default Apache block for /var/www enables Indexes, so a fresh install lists uploads until someone changes it. TraceEnable Off removes an HTTP method that echoes request headers, including cookies, and that nothing legitimate uses.

AllowOverride All lets any .htaccess file under the document root change handlers, options and access rules. Combined with an upload bug, that is how an image becomes a PHP script. AllowOverride None, or a short explicit list such as FileInfo Indexes Limit, keeps those decisions in root-owned configuration.

## TLS the Mozilla Way

TLS 1.0 and 1.1 are deprecated by RFC 8996. nginx needs ssl_protocols TLSv1.2 TLSv1.3; Apache needs SSLProtocol -all +TLSv1.2 +TLSv1.3, because its default (all -SSLv3) still allows the old versions. The cipher list should be the short Mozilla intermediate set: ECDHE key exchange, AES-GCM or ChaCha20, nothing with RC4, DES, 3DES, MD5, NULL, export or anonymous suites. Both guidelines now set ssl_prefer_server_ciphers off and SSLHonorCipherOrder off, since every listed suite is strong and the client knows its own hardware best.

OCSP stapling (ssl_stapling on; SSLUseStapling On) lets the server attach a fresh revocation status to the handshake. This is faster and stops browsers telling the certificate authority which sites a user visits. The Mozilla profiles also turn nginx session tickets off, because a ticket key that never rotates weakens forward secrecy. The Mozilla SSL Configuration Generator produces a full configuration block for either server; paste it rather than typing cipher names.

## Dot Files and Limits

A .git folder rebuilds the source and its history; a .env file holds the database password. Debian's Apache default protects only .ht* files. One rule per server covers the whole class: nginx location ~ /\. { deny all; } with a more specific location for /.well-known/ above it; Apache <DirectoryMatch "/\.(git|svn|hg)"> and <FilesMatch "^\.(env|git)"> with Require all denied. This also protects files deployed by mistake next year.

client_max_body_size and limit_req_zone in nginx bound what one client can upload and how fast it can hit a login page. ModSecurity with the OWASP Core Rule Set, or mod_evasive, adds request filtering to Apache. These are informational in OpenVAPT because the right numbers depend on the application; a filter that is never tuned breaks sites, and one that is never deployed blocks nothing.

## In Summary

A web server is only as hard as its merged configuration. Hide banners and listings, and disable TRACE. Allow only TLS 1.2 and 1.3 with modern ciphers and stapling. Keep .htaccess overrides narrow, deny dot files everywhere, and bound request sizes and rates.

## Apply It

- [WEB-APA-001 Apache Reveals Version in Header and Footer](https://openvapt.com/checks/WEB-APA-001.md) (low)
- [WEB-APA-002 Apache TRACE Method Enabled](https://openvapt.com/checks/WEB-APA-002.md) (low)
- [WEB-APA-003 Apache Directory Indexes Enabled in Configuration](https://openvapt.com/checks/WEB-APA-003.md) (medium)
- [WEB-APA-004 Apache AllowOverride All Permits .htaccess Control](https://openvapt.com/checks/WEB-APA-004.md) (low)
- [WEB-APA-005 Apache Allows TLS 1.0 or 1.1](https://openvapt.com/checks/WEB-APA-005.md) (high)
- [WEB-APA-006 Apache Cipher Suite Includes Weak Suites](https://openvapt.com/checks/WEB-APA-006.md) (high)
- [WEB-APA-007 Apache OCSP Stapling Not Enabled](https://openvapt.com/checks/WEB-APA-007.md) (low)
- [WEB-APA-008 Apache Has No Request Filtering Module](https://openvapt.com/checks/WEB-APA-008.md) (info)
- [WEB-APA-009 Apache ETag Reveals Inode Numbers](https://openvapt.com/checks/WEB-APA-009.md) (low)
- [WEB-APA-010 Apache Serves Repository and Environment Files](https://openvapt.com/checks/WEB-APA-010.md) (low)
- [WEB-APA-011 Apache Has No Slow Request Protection](https://openvapt.com/checks/WEB-APA-011.md) (medium)
- [WEB-NGX-001 nginx Version Shown in Server Header](https://openvapt.com/checks/WEB-NGX-001.md) (low)
- [WEB-NGX-002 nginx Directory Listing Enabled in Configuration](https://openvapt.com/checks/WEB-NGX-002.md) (medium)
- [WEB-NGX-003 nginx Allows TLS 1.0 or 1.1](https://openvapt.com/checks/WEB-NGX-003.md) (high)
- [WEB-NGX-004 nginx Cipher List Includes Weak Suites](https://openvapt.com/checks/WEB-NGX-004.md) (high)
- [WEB-NGX-005 nginx OCSP Stapling Off or Session Tickets On](https://openvapt.com/checks/WEB-NGX-005.md) (low)
- [WEB-NGX-006 nginx Request Limits Not Configured](https://openvapt.com/checks/WEB-NGX-006.md) (info)
- [WEB-NGX-007 nginx Serves Hidden Files and Folders](https://openvapt.com/checks/WEB-NGX-007.md) (medium)

## Lab

1. `Run: openvapt demo --only WEB-NGX-,WEB-APA- --out p15 and, for each finding, write the exact line in nginx.conf or apache2.conf that fixes it.`
2. `Compare /etc/nginx/nginx.conf and /etc/apache2/apache2.conf between the two labs (internal/lab/fixtures_servers_db_mail.go) and explain what each changed directive prevents.`
3. `On a test machine: nginx -T | grep -nE 'server_tokens|ssl_protocols|autoindex'  and  apachectl -t -D DUMP_CONFIG | grep -nE 'ServerTokens|SSLProtocol|Options' ; find the effective value and the file it came from.`
4. `Generate an intermediate profile for your server version at the Mozilla SSL Configuration Generator and list every directive it sets that your current configuration lacks.`

## Check Yourself

Answer keys are public for every channel (see Teaching With OpenVAPT).

1. Apache has SSLEngine on but no SSLProtocol line. Which versions does it accept?
   - A. TLS 1.2 and 1.3 only
   - B. Everything except SSLv3, so TLS 1.0 and 1.1 too
   - C. TLS 1.3 only
   - D. TLS 1.0 only
   - Answer: B. The Apache default is all -SSLv3, which still allows the deprecated versions.

2. Why does the Mozilla intermediate profile set ssl_prefer_server_ciphers off?
   - A. It is faster for the server
   - B. Every suite in the list is strong, so the client may pick the one its hardware handles best
   - C. nginx requires it
   - D. It turns off TLS 1.3
   - Answer: B. Server preference mattered when lists still contained weak suites.

3. What does AllowOverride All let a .htaccess file do?
   - A. Nothing beyond redirects
   - B. Change handlers, options and access rules for that folder
   - C. Change the server's TLS certificate
   - D. Edit the main apache2.conf file
   - Answer: B. Overrides move security decisions into files under the document root.

4. Which single rule stops nginx serving .git, .env and .svn under any site?
   - A. autoindex off
   - B. location ~ /\. { deny all; }
   - C. server_tokens off
   - D. client_max_body_size 1m
   - Answer: B. A deny for every dot-prefixed path segment covers the whole class.

5. What does OCSP stapling do?
   - A. Lets the server attach a fresh revocation status to the TLS handshake
   - B. Encrypts the certificate's private key
   - C. Turns off TLS 1.0
   - D. Hides the server banner
   - Answer: A. Stapling is faster for users and stops browsers telling the certificate authority which sites a user visits.

## Key Terms

- Cipher Suite: The named combination of key exchange, authentication, encryption and integrity algorithms a TLS connection agrees on; weak suites let recorded traffic be decrypted.
- OCSP Stapling: The web server fetching a signed, time-limited statement that its certificate is not revoked and attaching it to the TLS handshake, so browsers need not ask the certificate authority.
- Directory Listing: A web server feature that shows every file in a folder when there is no index page.
- Web Application Firewall: A filter in front of a web application that inspects requests against rules and blocks or logs attacks; a defence-in-depth layer, not a substitute for fixing the application.
- TLS: Transport Layer Security: the protocol that encrypts connections such as HTTPS.
- Fingerprinting: Identifying the exact software and version a system runs, for example from banners, headers or version files.

## References

- [Mozilla, Server Side TLS guidelines](https://wiki.mozilla.org/Security/Server_Side_TLS)
- [Mozilla SSL Configuration Generator](https://ssl-config.mozilla.org/)
- [Apache HTTP Server, Security Tips](https://httpd.apache.org/docs/2.4/misc/security_tips.html)
- [nginx documentation, ngx_http_ssl_module](https://nginx.org/en/docs/http/ngx_http_ssl_module.html)
- [NIST SP 800-52 Rev. 2, Guidelines for TLS Implementations](https://csrc.nist.gov/pubs/sp/800/52/r2/final)
- [OWASP Web Security Testing Guide, Configuration and Deployment Management Testing](https://wstg.owasp.org/v4.2/4-Web_Application_Security_Testing/02-Configuration_and_Deployment_Management_Testing/)

Offline: `openvapt learn P18`.

---

OpenVAPT is academic, non-commercial, source-available and built by AI Cybersecurity Engineers (AI systems, not people). Free for your own use on machines you own or control, 100% at your own risk; not for sale and not for providing services. This page in HTML: https://openvapt.com/academy/p18.html. Part of OpenVAPT Academy. How to cite: https://openvapt.com/cite.html. Site summary for models: https://openvapt.com/llms.txt.
