Web Server Security Hardening Checklist: Nginx and Apache
Web Server Security Hardening Checklist
Securing your web server is one of the most critical tasks in running a production environment. A misconfigured server exposes your application to data breaches, defacement, malware injection, and denial-of-service attacks. This checklist covers essential hardening steps for both nginx and Apache web servers.
Why Server Hardening Matters
Default server configurations prioritize ease of setup over security. Out-of-the-box installations often expose version information, enable unnecessary modules, and use weak TLS settings. Attackers actively scan for these misconfigurations. Hardening reduces your attack surface and makes exploitation significantly harder.
- Reduced attack surface: Fewer enabled modules and services mean fewer potential vulnerabilities.
- Defense in depth: Security headers and proper TLS add layers of protection beyond application-level security.
- Compliance: Many standards (PCI-DSS, SOC 2, ISO 27001) require documented server hardening procedures.
- Incident prevention: Proper file permissions and access controls prevent privilege escalation after initial compromise.
1. Hide Server Version Information
Never expose your server software version to the public. This information helps attackers identify known vulnerabilities.
Nginx
# nginx.conf
server_tokens off;
# Also remove X-Powered-By if set by upstream
proxy_hide_header X-Powered-By;
Apache
# httpd.conf or apache2.conf
ServerTokens Prod
ServerSignature Off
Header unset X-Powered-By
2. Security Headers
HTTP security headers instruct browsers to enforce security policies. Missing headers leave users vulnerable to XSS, clickjacking, and data injection attacks.
| Header | Value | Purpose |
|---|---|---|
| X-Content-Type-Options | nosniff | Prevents MIME-type sniffing |
| X-Frame-Options | DENY or SAMEORIGIN | Prevents clickjacking |
| X-XSS-Protection | 0 | Disables flawed legacy XSS filter |
| Referrer-Policy | strict-origin-when-cross-origin | Controls referrer information leakage |
| Permissions-Policy | camera=(), microphone=() | Restricts browser feature access |
| Content-Security-Policy | default-src 'self' | Controls resource loading origins |
| Strict-Transport-Security | max-age=63072000 | Forces SSL/TLS проверку connections |
Nginx Implementation
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'" always;
3. TLS Configuration
Modern TLS configuration is essential. Disable outdated protocols and weak ciphers.
# Modern TLS configuration (nginx)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
Test your TLS configuration regularly using SSL Labs (ssllabs.com). Aim for an A+ rating. Ensure OCSP stapling is working correctly and certificates are renewed well before expiry.
4. File Permissions
Incorrect file permissions are one of the most common security failures. Follow the principle of least privilege.
- Web root directories: 755 (rwxr-xr-x)
- Static files (HTML, CSS, JS, images): 644 (rw-r--r--)
- PHP/script files: 644 (rw-r--r--)
- Configuration files: 640 (rw-r-----) or 600 (rw-------)
- Upload directories: 755 with noexec mount option
- Log files: 640 (rw-r-----)
# Set proper ownership and permissions
chown -R www-data:www-data /var/www/html
find /var/www/html -type d -exec chmod 755 {} \;
find /var/www/html -type f -exec chmod 644 {} \;
chmod 600 /var/www/html/.env
chmod 600 /var/www/html/config/*.php
5. Access Control
Restrict access to sensitive paths and administrative interfaces.
Nginx
# Block access to hidden files
location ~ /\. {
deny all;
return 404;
}
# Restrict admin area by IP
location /admin/ {
allow 192.168.1.0/24;
deny all;
}
Apache
# .htaccess for hidden files
<FilesMatch "^\.">
Require all denied
</FilesMatch>
# Restrict admin area
<Directory "/var/www/html/admin">
Require ip 192.168.1.0/24
</Directory>
6. Rate Limiting and DDoS Mitigation
Protect against brute-force and denial-of-service attacks with rate limiting.
# nginx rate limiting
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/m;
location /login {
limit_req zone=login burst=3 nodelay;
}
location /api/ {
limit_req zone=api burst=10 nodelay;
}
7. Logging and Monitoring
Proper logging is essential for detecting and investigating security incidents.
- Enable access and error logs for every virtual host.
- Log to a centralized system (syslog, ELK stack, or a SIEM).
- Monitor for unusual patterns: repeated 403/404 errors, large request bodies, abnormal user agents.
- Set up automated alerts for critical events.
- Retain logs for at least 90 days for forensic analysis.
8. Disable Unnecessary Modules
Every loaded module is a potential attack vector. Disable what you do not use:
# Apache: disable unused modules
a2dismod autoindex status cgi
# Nginx: compile without unnecessary modules or remove them from conf
# Review loaded modules:
nginx -V 2>&1 | tr -- ' -' '\n' | grep module
Summary Checklist
- Hide server version and software information
- Implement all recommended security headers
- Configure modern TLS (1.2+) with strong ciphers
- Set correct file permissions and ownership
- Restrict access to sensitive directories
- Enable rate limiting on authentication and API документацию endpoints
- Configure comprehensive logging and monitoring
- Disable unnecessary server modules
- Keep server software updated
- Test configuration with automated security scanners
Server hardening is not a one-time task. Schedule regular audits, subscribe to security advisories for your server software, and retest after every configuration change.
Check your website right now
Check now →