Lesson 11: Security Hardening and Best Practices
Welcome to the security hardening lesson! After mastering caching strategies in the previous lesson, we'll now focus on protecting your Nginx server from common threats. Security is not an afterthought—it's a fundamental aspect of production deployment that we'll implement step by step.
Learning Goals:
- Implement security headers to protect against common web vulnerabilities
- Configure Nginx to mitigate DDoS and brute force attacks
- Secure server information disclosure and restrict access
- Set up basic authentication and IP whitelisting
- Monitor and audit security configurations
Essential Security Headers
Security headers are your first line of defense against common web attacks. Let's implement the most critical ones:
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
# Content Security Policy - adjust based on your application
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';" always;
Start with a report-only CSP header first: add_header Content-Security-Policy-Report-Only "default-src 'self';" always; This way, you can monitor potential issues without breaking your site.
Rate Limiting and DDoS Protection
Rate limiting is crucial for preventing brute force attacks and DDoS attempts:
# Define rate limit zones
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=auth:10m rate=5r/m;
# Apply to specific locations
server {
listen 443 ssl;
server_name example.com;
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://backend;
}
location /login {
limit_req zone=auth burst=3 nodelay;
proxy_pass http://backend;
}
}
Server Information Hiding
Attackers often use server information to identify vulnerabilities. Let's hide sensitive details:
# Hide Nginx version
server_tokens off;
# Hide PHP version (if using PHP)
fastcgi_hide_header X-Powered-By;
# Custom error pages to avoid information leakage
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
# Security through obscurity - remove unnecessary headers
more_clear_headers 'Server';
more_clear_headers 'X-Powered-By';
Access Control and Authentication
Control who can access your server and what they can see:
# IP-based access control
location /admin {
allow 192.168.1.0/24;
allow 10.0.0.1;
deny all;
# Basic authentication
auth_basic "Administrator Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
# Restrict HTTP methods
location /api {
limit_except GET POST {
deny all;
}
}
# Prevent access to sensitive files
location ~ /\.(ht|git|env) {
deny all;
access_log off;
log_not_found off;
}
SSL/TLS Security Enhancements
Building on our previous SSL lesson, let's harden our TLS configuration:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Enable HSTS for one year
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# OCSP stapling for better performance and privacy
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
File Upload Security
If your application handles file uploads, implement these security measures:
# Limit file upload size
client_max_body_size 10M;
# Prevent execution of uploaded files
location /uploads/ {
location ~ \.php$ {
deny all;
}
# No execution in upload directory
location ~* \.(php|phtml|phar|sh|bash|pl|py)$ {
deny all;
}
}
Monitoring and Logging Security Events
Configure logging to detect and investigate security incidents:
# Custom log format for security monitoring
log_format security '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';
# Log security events separately
server {
access_log /var/log/nginx/security.log security;
# Log failed authentication attempts
location /admin {
access_log /var/log/nginx/admin_access.log;
error_log /var/log/nginx/admin_error.log;
}
}
Complete Security Configuration Example
Here's a comprehensive security configuration you can adapt:
# Global security settings
server_tokens off;
client_body_buffer_size 1k;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
# Rate limiting
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
server {
listen 443 ssl http2;
server_name example.com;
# SSL security (from previous config)
include ssl-security.conf;
# Security headers
include security-headers.conf;
# Rate limiting for login
location /login {
limit_req zone=one burst=5;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
}
# Protect admin area
location /admin {
allow 192.168.1.0/24;
deny all;
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
# Block common attack patterns
location ~* "(eval\()" {
deny all;
}
location ~* "(base64_encode)(.*)(\()" {
deny all;
}
}
Common Pitfalls
- Overly restrictive CSP: Starting with a too-strict Content Security Policy can break legitimate functionality. Use report-only mode first.
- Ignoring log monitoring: Security configurations are useless without monitoring. Regularly check security logs for suspicious activity.
- Forgetting about third-party services: When implementing security headers, remember to allow CDNs, analytics, and other external services your site depends on.
- Testing in production: Always test security configurations in a staging environment first to avoid service disruption.
- Outdated SSL configurations: Regularly review and update your SSL/TLS settings as new vulnerabilities are discovered and best practices evolve.
Summary
In this lesson, you've learned essential Nginx security hardening techniques:
- Implemented security headers to protect against XSS, clickjacking, and MIME sniffing
- Configured rate limiting to prevent DDoS and brute force attacks
- Secured server information disclosure and restricted access to sensitive areas
- Enhanced SSL/TLS configurations and implemented file upload security
- Set up monitoring and logging for security events
Remember that security is an ongoing process—regularly review and update your configurations as new threats emerge.
Quiz
Nginx Security Headers and Best Practices
What is the primary purpose of the `X-Frame-Options` header?