How to Harden Nginx Web Server Configuration for Security: A Complete Checklist

Harden your Nginx web server by disabling version disclosure and implementing seven critical security headers including CSP, X-Frame-Options, and X-Content-Type-Options in the main http block.

The imthenachoman/How-To-Secure-A-Linux-Server repository provides a battle-tested configuration template for locking down Nginx installations. According to the source code documented in nginx.md (lines 7‑45), hardening Nginx requires modifying global directives to eliminate information leakage while injecting defense‑in‑depth HTTP response headers that mitigate XSS, click‑jacking, and MIME‑type sniffing attacks.

Disable Server Version Disclosure

By default, Nginx exposes its exact version number in the Server response header, enabling attackers to identify known vulnerabilities specific to that release.

Set server_tokens to off in the http block to strip version information from all responses:

server_tokens off;

This directive removes the version string from error pages and the Server header, forcing attackers to perform blind fingerprinting rather than targeting documented CVEs.

Implement Security Headers with add_header

The repository recommends seven essential headers added with the add_header ... always; syntax to ensure coverage on both successful responses and error pages. Place these in the main http block to create global defaults for every server block.

Content-Security-Policy (CSP)

A strict CSP prevents injection attacks by whitelisting content sources. The minimal secure policy restricts content to same‑origin only:

add_header Content-Security-Policy "default-src 'self';" always;

X-Frame-Options

Prevent click‑jacking attacks by restricting how your site can be embedded in frames. The SAMEORIGIN directive allows framing only by your own domain:

add_header X-Frame-Options SAMEORIGIN always;

X-XSS-Protection

While modern browsers rely on CSP for XSS mitigation, legacy browsers still respect this header. The "1; mode=block" value instructs browsers to block pages that appear to contain reflected XSS:

add_header X-Xss-Protection "1; mode=block" always;

Referrer-Policy

Control referrer information leakage by limiting when the Referer header is sent. strict-origin ensures the header is transmitted only for same‑origin requests:

add_header Referrer-Policy "strict-origin" always;

Permissions-Policy

Disable potentially invasive browser APIs that your application does not require. This header explicitly revokes access to geolocation, camera, microphone, and other features:

add_header Permissions-Policy "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()" always;

X-Content-Type-Options

Prevent MIME‑type sniffing attacks by forcing browsers to honor the declared Content-Type rather than inferring it from content:

add_header X-Content-Type-Options nosniff always;

Global Configuration Strategy

Place all directives inside the http block within /etc/nginx/nginx.conf to establish secure defaults across all virtual hosts. Using the always parameter guarantees headers are included on 4xx/5xx error responses, preventing header leakage during error conditions. Server blocks can override these settings when specific applications require relaxed policies, but the global configuration ensures secure defaults according to the repository's defense‑in‑depth philosophy.

Summary

  • Disable version disclosure by setting server_tokens off; in the http block to prevent targeted attacks against known Nginx versions.
  • Add security headers globally using add_header ... always; to ensure protection on both success and error responses.
  • Enforce CSP with default-src 'self' to block cross‑site injection attacks while permitting same‑origin resources.
  • Mitigate click‑jacking via X-Frame-Options SAMEORIGIN to prevent unauthorized framing of your content.
  • Stop MIME‑type sniffing with X-Content-Type-Options nosniff to ensure browsers respect declared content types.
  • Reference repository files nginx.md lines 7‑45 and linux-kernel-sysctl-hardening.md for complete server hardening context.

Frequently Asked Questions

Where should I place the Nginx hardening directives?

Place the server_tokens and add_header directives inside the http block of /etc/nginx/nginx.conf. This location ensures the settings become global defaults for every server block unless explicitly overridden, as documented in imthenachoman/How-To-Secure-A-Linux-Server.

Why use always with add_header?

The always parameter ensures security headers are sent with both successful responses and error responses (4xx/5xx). Without this flag, Nginx omits headers on error pages, potentially leaking information or leaving error responses unprotected against XSS and click‑jacking.

Does X-XSS-Protection still matter for modern browsers?

Modern browsers have deprecated X-XSS-Protection in favor of Content Security Policy, but legacy browsers and corporate environments still respect this header. Including X-Xss-Protection "1; mode=block" provides defense‑in‑depth for older clients at zero cost to modern users.

Which repositories complement the Nginx hardening guide?

The linux-kernel-sysctl-hardening.md file in the same repository provides kernel‑level hardening that should be applied alongside Nginx configuration changes. Together, these files address both the application layer and operating system layer of your web server stack.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →