SSL Certificate Analysis Open Port Detection Web Application Scanning DNS Security Audit HTTP Header Analysis Misconfiguration Detection Software Fingerprinting Subdomain Enumeration
SSL Certificate Analysis Open Port Detection Web Application Scanning DNS Security Audit HTTP Header Analysis Misconfiguration Detection Software Fingerprinting Subdomain Enumeration

This guide is for developers, system administrators, and technical managers responsible for running web servers in production. Whether you use Apache, Nginx, or another server, a default installation leaves many security gaps open. Follow these steps to systematically close them — hardening your server against common attacks, information leakage, and misconfiguration exploits. Sensagraph can automatically verify many of these controls on a continuous basis.

01

Disable Unnecessary Modules and Services

Every enabled module or service that you do not actively use is a potential entry point for attackers. Default installations of Apache and Nginx often include modules for WebDAV, status pages, autoindex, and server-side scripting engines that may not be required. Audit and remove anything that is not essential.

  • List all enabled modules: run apache2ctl -M (Apache) or review your nginx.conf compiled modules.
  • Disable WebDAV modules (mod_dav, mod_dav_fs) unless your application explicitly requires them.
  • Disable server status and info endpoints (mod_status, mod_info) or restrict them to localhost only.
  • Remove autoindex / directory listing modules if not needed (see Step 04 for full directory listing hardening).
  • Disable unused scripting language handlers (e.g., Perl, CGI) at the server level.
  • Stop and disable any OS-level services not required by the web server (FTP, Telnet, unused databases).
  • After disabling, restart the server and verify functionality is not affected.
02

Enforce HTTPS and Configure TLS Properly

Serving content over unencrypted HTTP exposes users to eavesdropping and man-in-the-middle attacks. Enforcing HTTPS and correctly configuring TLS is one of the highest-impact hardening steps you can take. Sensagraph checks your TLS configuration and certificate validity automatically.

  • Obtain a valid TLS certificate from a trusted CA (Let's Encrypt is free and widely supported).
  • Configure a permanent redirect (HTTP 301) from all HTTP traffic to HTTPS at the server level.
  • Disable TLS 1.0 and TLS 1.1 — support only TLS 1.2 and TLS 1.3.
  • Use strong cipher suites; a recommended starting point for Nginx: ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
  • Set ssl_prefer_server_ciphers on; (Nginx) or SSLHonorCipherOrder On (Apache) to enforce your cipher preference.
  • Enable OCSP Stapling to speed up certificate validation: ssl_stapling on; ssl_stapling_verify on; (Nginx).
  • Set a secure Diffie-Hellman parameter: generate with openssl dhparam -out /etc/ssl/dhparam.pem 4096 and reference it in your config.
  • Verify your TLS configuration using an independent scanner after every change.
03

Set Secure HTTP Response Headers

HTTP security headers instruct browsers how to handle your content, protecting users from clickjacking, cross-site scripting, MIME sniffing, and other attacks. Missing or misconfigured headers are one of the most common findings in web security assessments. Sensagraph automatically checks for the presence and correctness of these headers.

  • Strict-Transport-Security (HSTS): Add Strict-Transport-Security: max-age=31536000; includeSubDomains; preload to enforce HTTPS for at least one year.
  • Content-Security-Policy (CSP): Define a policy that restricts script, style, and resource sources. Start restrictive and widen only as needed, e.g. default-src 'self';.
  • X-Frame-Options: Set to DENY or SAMEORIGIN to prevent clickjacking.
  • X-Content-Type-Options: Set to nosniff to prevent MIME-type sniffing.
  • Referrer-Policy: Set to strict-origin-when-cross-origin or stricter to limit referrer leakage.
  • Permissions-Policy: Restrict access to browser features (camera, microphone, geolocation) that your app does not use.
  • Remove the X-Powered-By header entirely (reveals technology stack).
  • Test all headers after deployment using your browser's developer tools or an automated scan.
04

Restrict Directory Listing and Sensitive File Access

Directory listing allows anyone to browse your server's file structure, potentially exposing source code, backups, and configuration files. Sensitive files accidentally placed in the web root compound this risk enormously.

  • Disable directory listing globally in Apache: set Options -Indexes in your main config or .htaccess.
  • Disable autoindex in Nginx: ensure autoindex off; is set (it is the default, but confirm it explicitly).
  • Block direct access to hidden files and directories (dot files): in Nginx, add location ~ /\. { deny all; }; in Apache, use RedirectMatch 404 /\..*$.
  • Block access to common sensitive file extensions: .env, .bak, .sql, .log, .conf, .git directories.
  • Move all configuration and secrets files outside the web root where possible.
  • Verify that /.git/, /.env, /wp-config.php.bak, and similar paths return 403 or 404 — never 200.
  • Audit your web root regularly for files that should not be publicly accessible.
05

Hide Server Version and Technology Information

By default, web servers broadcast their software name and version in response headers and error pages. Attackers use this information to quickly identify vulnerable server versions and target known CVEs. Suppress this information to raise the cost of reconnaissance.

  • Nginx: Set server_tokens off; in the http block of nginx.conf.
  • Apache: Set ServerTokens Prod and ServerSignature Off in httpd.conf or apache2.conf.
  • Remove or rewrite the Server response header using a header manipulation module if you require further obfuscation.
  • Remove the X-Powered-By header (PHP, Express, and others add this by default); in PHP set expose_php = Off in php.ini.
  • Customise default error pages (404, 403, 500) so they do not reveal stack traces, software versions, or file paths.
  • Confirm suppression by inspecting response headers in your browser or via an automated scan — Sensagraph checks for exposed server banners.
06

Limit Allowed HTTP Methods

Web servers often accept HTTP methods — such as TRACE, PUT, DELETE, and OPTIONS — that are not required by most applications. Leaving these enabled provides attackers with additional vectors, including cross-site tracing (XST) attacks via TRACE.

  • Identify the HTTP methods your application actually uses (typically GET, POST, and possibly OPTIONS for CORS pre-flight).
  • Nginx: Restrict methods with a block such as: if ($request_method !~ ^(GET|POST|HEAD)$) { return 405; }
  • Apache: Use a <LimitExcept> directive to deny all methods except those explicitly required.
  • Always disable the TRACE method — it is rarely needed and enables cross-site tracing attacks.
  • Test that disallowed methods return 405 Method Not Allowed or 403 Forbidden and not a 200 OK.
07

Implement Rate Limiting and Request Controls

Without rate limiting, your server is vulnerable to brute-force login attempts, credential stuffing, and volumetric denial-of-service attacks. Controlling request rates and payload sizes significantly reduces your exposure.

  • Nginx rate limiting: Use limit_req_zone and limit_req directives to cap requests per IP, e.g. 10 requests/second with a burst allowance.
  • Apache: Use mod_ratelimit or mod_evasive to limit connection rates and block abusive IPs.
  • Set a maximum request body size appropriate for your application: client_max_body_size 10m; (Nginx) or LimitRequestBody 10485760 (Apache).
  • Set timeouts for slow clients: configure client_body_timeout, client_header_timeout, and keepalive_timeout (Nginx) or their Apache equivalents.
  • Apply stricter rate limits specifically to authentication endpoints (/login, /api/auth) and password reset flows.
  • Consider integrating a Web Application Firewall (WAF) in front of your server for deeper request inspection.
  • Log and alert on repeated 429 (Too Many Requests) or 403 responses to detect active attacks.
08

Harden File and Directory Permissions

Overly permissive file and directory permissions allow attackers — or other users on a shared system — to read configuration files, modify application code, or write malicious files. Apply the principle of least privilege rigorously.

  • Run the web server process as a dedicated, non-privileged user (e.g., www-data on Debian/Ubuntu, nginx on RHEL/CentOS) — never as root.
  • Set web root directory permissions to 755 (owner read/write/execute, group and others read/execute).
  • Set static file permissions to 644 (owner read/write, group and others read-only).
  • Set configuration file permissions to 640 or 600 so only the owner (and optionally the web server group) can read them.
  • Ensure .env and secrets files are 600 and owned by the application user only.
  • Deny write access to the web server process on all directories except designated upload folders.
  • Restrict upload directories from executing scripts: configure php_admin_value engine Off or equivalent for upload paths.
  • Audit permissions recursively: find /var/www -type f -perm /o+w to identify world-writable files.
09

Keep Software Updated and Monitor Continuously

Hardening is not a one-time task. New vulnerabilities in web server software, TLS libraries, and server-side frameworks are discovered regularly. A robust update and monitoring process ensures your hardening remains effective over time. Sensagraph continuously scans your web server configuration and alerts you when new issues are detected.

  • Subscribe to security advisories for your web server software (Apache, Nginx) and OS distribution.
  • Apply security patches within 72 hours of release for critical vulnerabilities; within 30 days for lower severity.
  • Use your OS package manager's automatic security update feature (unattended-upgrades on Debian/Ubuntu, dnf-automatic on RHEL/CentOS) for OS-level patches.
  • Keep TLS libraries (OpenSSL, LibreSSL) up to date — many critical TLS vulnerabilities are in the underlying library.
  • Enable and review server access and error logs; ship them to a centralised log management system.
  • Set up alerting for anomalous patterns: high 4xx/5xx rates, unexpected 200 responses on sensitive paths, traffic spikes.
  • Schedule regular automated security scans of your web server to catch configuration drift and new exposures.
  • After any significant configuration change or software upgrade, re-run your full hardening checklist.

Frequently asked questions

Web server hardening is the process of configuring your server to reduce its attack surface by disabling unnecessary features, enforcing secure protocols, setting proper permissions, and adding protective HTTP headers. It is important because default server installations are configured for convenience, not security, leaving many unnecessary features enabled and sensitive information exposed.

The most impactful headers are Strict-Transport-Security (HSTS), Content-Security-Policy (CSP), X-Frame-Options, X-Content-Type-Options, and Referrer-Policy. Together they protect against protocol downgrade attacks, cross-site scripting, clickjacking, MIME sniffing, and information leakage.

In Nginx, directory listing is disabled by default. Confirm it is off by checking that 'autoindex off;' is set (or not overridden to 'on') in your server block. For Apache, set 'Options -Indexes' in your main configuration or .htaccess file.

You should support only TLS 1.2 and TLS 1.3. TLS 1.0 and 1.1 are deprecated and contain known vulnerabilities (including POODLE and BEAST). Disable them explicitly in your server configuration.

You should re-audit after every significant configuration change, software upgrade, or new application deployment. Additionally, run automated continuous scans to detect configuration drift between manual audits — security issues can be introduced unintentionally through routine changes.

No — hiding the server version (via ServerTokens Prod or server_tokens off) reduces information leakage and raises the cost of reconnaissance, but it is just one layer. You must also enforce HTTPS, set security headers, restrict methods, apply proper permissions, and keep software updated.