A comprehensive guide to configuring security features in Nginx for enhanced protection.
Before configuring security on Nginx, ensure you have:
# /etc/nginx/nginx.conf
http {
# Basic security settings
server_tokens off;
client_max_body_size 10m;
client_body_buffer_size 128k;
# SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
server {
listen 443 ssl http2;
server_name example.com;
# SSL certificate configuration
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
}
}
Key directives explained:
server {
# Security headers
add_header X-Frame-Options "DENY" 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 Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
# Cross-Origin settings
add_header Cross-Origin-Embedder-Policy "require-corp" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Resource-Policy "same-origin" always;
}
http {
# Rate limiting zones
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m;
server {
# API rate limiting
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
limit_req_status 429;
}
# Login rate limiting
location /login {
limit_req zone=login_limit burst=10 nodelay;
limit_req_status 429;
}
}
}
Rate limiting explained:
# Install ModSecurity
sudo apt-get install libnginx-mod-http-modsecurity
# /etc/nginx/nginx.conf
http {
modsecurity on;
modsecurity_rules_file /etc/nginx/modsecurity/main.conf;
server {
location / {
# Basic WAF rules
modsecurity_rules '
SecRule REQUEST_URI "@contains .php" \
"id:1000,\
phase:1,\
deny,\
status:403,\
msg:\'PHP file access attempt\'"
SecRule ARGS "@contains SELECT" \
"id:1001,\
phase:2,\
deny,\
status:403,\
msg:\'SQL Injection attempt\'"
';
}
}
}
# Nginx configuration will appear here