Implementing Advanced Security
1. Using ModSecurity WAF Integration
| Directive | Description | Default | Notes |
|---|---|---|---|
| modsecurity | Enables ModSecurity module | off | Must be set to on to enable WAF features |
| modsecurity_rules_file | Path to ModSecurity rules file | none | Required for rule loading |
| modsecurity_rules | Inline ModSecurity rules | none | Alternative to external file |
| modsecurity_config | ModSecurity configuration file path | none | Optional config override |
Example: Basic ModSecurity Configuration
server {
listen 80;
server_name example.com;
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;
location / {
# Your application logic here
}
}
Example: ModSecurity Rules File
# Basic rules for OWASP Core Rule Set
Include /etc/nginx/modsec/owasp-modsecurity-crs/crs-setup.conf
Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BASE.conf
Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf
Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/REQUEST-912-DOS-PROTECTION.conf
Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/REQUEST-913-SCANNER-DETECTION.conf
Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf
Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf
Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf
Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf
Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf
Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf
Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf
Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf
Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/RESPONSE-950-DATA-LEAKAGES.conf
Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/RESPONSE-951-DATA-LEAKAGES-SQLI.conf
Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/RESPONSE-952-DATA-LEAKAGES-XSS.conf
Include /etc/nginx/modsec/owasp-modsecurity-crs/rules/RESPONSE-953-DATA-LEAKAGES-OTHER.conf
Note: ModSecurity requires the
modsecurity module to be installed and loaded in Nginx. Ensure that the modsecurity_rules_file path points to a valid file containing ModSecurity rules.
Warning: ModSecurity can significantly impact performance. It's recommended to test in a staging environment before deploying to production.
ModSecurity Integration Summary
- modsecurity directive enables WAF features
- modsecurity_rules_file specifies rule file location
- OWASP CRS is a popular rule set for common web attacks
- ModSecurity can be configured to block or log threats
- Performance impact should be considered for high-traffic sites
2. Implementing Request Filtering
| Directive | Description | Example |
|---|---|---|
| limit_req | Controls request rate limiting based on a defined zone. | limit_req zone=api burst=5 nodelay; |
| limit_req_zone | Defines a zone for rate limiting with a specified key and rate. | limit_req_zone $binary_remote_addr zone=api:10m rate=1r/s; |
| limit_req_log_level | Sets the log level for rate limiting events. | limit_req_log_level warn; |
| limit_req_status | Defines the HTTP status code returned when a request is limited. | limit_req_status 429; |
Example: Rate Limiting Configuration
limit_req_zone $binary_remote_addr zone=api:10m rate=1r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
server {
listen 80;
server_name example.com;
location /api/ {
limit_req zone=api burst=5 nodelay;
proxy_pass http://backend;
}
location /login/ {
limit_req zone=login burst=10 nodelay;
proxy_pass http://auth_backend;
}
}
| Filtering Method | Description | Use Case |
|---|---|---|
| geo | Maps IP addresses to variables for conditional logic. | Geolocation-based access control |
| map | Maps variables to values for use in conditions. | Custom variable transformations |
| if | Conditional directive for request matching. | Blocking specific user agents or IPs |
Example: IP-Based Access Control
geo $blocked_ip {
default 0;
192.168.1.100 1;
10.0.0.50 1;
}
server {
listen 80;
server_name example.com;
if ($blocked_ip) {
return 403;
}
location / {
proxy_pass http://backend;
}
}
Note: The
if directive can lead to performance issues and should be used sparingly. Prefer using map or geo for better performance.
Warning: Rate limiting can cause legitimate traffic to be blocked if not configured carefully. Always test thresholds with a small subset of users before applying broadly.
3. Blocking SQL Injection
| Directive | Description | Example |
|---|---|---|
| sql_injection | Enables or disables SQL injection detection | sql_injection on; |
| sqli_whitelist | Whitelists specific SQL patterns from being blocked | sqli_whitelist "SELECT.*FROM.*WHERE"; |
| sqli_max_args | Maximum number of arguments to check for SQL injection | sqli_max_args 100; |
Note: The
sql_injection directive is part of the Nginx Plus module and requires a license.
Warning: Misconfiguring SQL injection rules can block legitimate traffic. Always test in a staging environment.
4. Preventing XSS Attacks
| Directive | Description | Values | Notes |
|---|---|---|---|
| add_header | Sets custom headers to response | X-Content-Type-Options: nosniff |
Prevents MIME type sniffing |
| add_header | Sets custom headers to response | X-Frame-Options: DENY |
Prevents clickjacking attacks |
| add_header | Sets custom headers to response | Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; |
Controls resources that can be loaded |
Example: Setting Security Headers
server {
listen 80;
server_name example.com;
add_header X-Content-Type-Options "nosniff";
add_header X-Frame-Options "DENY";
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline';";
location / {
root /var/www;
index index.html;
}
}
Note: Content-Security-Policy (CSP) is a powerful defense mechanism against XSS and other code injection attacks. It allows you to define which sources of content are allowed to be executed or loaded.
XSS Prevention Techniques
- Use
Content-Security-Policyto restrict script sources - Implement
X-Content-Type-Options: nosniffto prevent MIME sniffing - Set
X-Frame-Options: DENYto prevent clickjacking - Escape user input before rendering in HTML context
5. Using Naxsi WAF Module
Naxsi is an open-source Web Application Firewall (WAF) module for Nginx. It provides protection against common web attacks like SQL injection, XSS, and CSRF.
| Directive | Description | Default Value | Notes |
|---|---|---|---|
| naxsi_enable | Enables or disables Naxsi module | off |
Must be set inside http, server, or location |
| main_template | Path to the main template file for error pages | /etc/nginx/naxsi_core.rules |
Can be overridden to customize error messages |
| learning_mode | Enables learning mode to log rules without blocking | off |
Useful for testing and tuning rules |
| disabled | Disables Naxsi for specific locations | off |
Can be used to exclude certain paths from WAF checks |
Example: Basic Naxsi Configuration
http {
include /etc/nginx/naxsi_core.rules;
server {
listen 80;
server_name example.com;
location / {
naxsi_enable on;
learning_mode off;
check_rules;
}
}
}
Note: Naxsi requires the
naxsi_core.rules file to be included in the configuration. This file contains default rules for detecting common attacks.
Warning: In learning mode, Naxsi logs potential threats but does not block them. It's recommended to run in learning mode for a while before enabling blocking mode.
| Rule Type | Description | Example Pattern | Severity Level |
|---|---|---|---|
| SQL Injection | Detects SQL injection attempts | UNION SELECT |
High |
| Cross-Site Scripting (XSS) | Detects XSS payloads | <script> |
High |
| Command Injection | Detects command injection attempts | exec() |
High |
| File Inclusion | Detects attempts to include files via URL parameters | include_once |
Medium |
Key Features of Naxsi
- Rule-based Detection: Uses predefined rules to identify malicious patterns
- Learning Mode: Logs potential threats without blocking, useful for tuning
- Customizable Templates: Allows customization of error pages and messages
- Modular Design: Can be enabled/disabled per location or server block
6. Implementing IP Reputation Blocking
| Directive | Description | Values | Notes |
|---|---|---|---|
| geoip2 | Module to use GeoIP2 database for IP lookups | on |
Requires libmaxminddb library installed |
| geoip2_country | Country code from GeoIP2 database | $geoip2_country_code |
Used in access control rules |
| geoip2_city | City name from GeoIP2 database | $geoip2_city_name |
Can be used for logging or filtering |
Example: Blocking IPs from Known Malicious Countries
map $geoip2_country_code $blocked_country {
default 0;
"CN" 1;
"RU" 1;
}
server {
if ($blocked_country) {
return 403;
}
location / {
# Allow all other traffic
}
}
Note: The
geoip2 module requires a valid MaxMind database file (e.g., GeoLite2-Country.mmdb) to be configured in the nginx.conf.
Warning: IP reputation blocking is not foolproof and can be bypassed by using proxies or VPNs. It should be part of a layered security approach.
7. Using Security Headers Bundle
Example: Basic Security Headers Configuration
server {
listen 443 ssl http2;
server_name example.com;
# Security Headers Bundle
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 "no-referrer-when-downgrade" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
location / {
root /var/www/html;
index index.html;
}
}
| Header | Description | Value | Notes |
|---|---|---|---|
| X-Frame-Options | Prevents clickjacking attacks | SAMEORIGIN |
Prevents framing from other origins |
| X-XSS-Protection | Enables XSS filtering in browsers | 1; mode=block |
Blocks XSS attacks in supported browsers |
| X-Content-Type-Options | Prevents MIME type sniffing | nosniff |
Forces browsers to respect content-type headers |
| Referrer-Policy | Controls referrer information sent with requests | no-referrer-when-downgrade |
Reduces leakage of sensitive data in referrers |
| Permissions-Policy | Controls which browser features can be used | geolocation=(), microphone=(), camera=() |
Disables sensitive APIs by default |
Note: These headers are part of the OWASP Secure Headers Project and are recommended for all modern web applications.
Warning: Some headers like
X-XSS-Protection are deprecated in modern browsers and should not be relied upon for security.
Security Header Best Practices
- Implement all headers in a security headers bundle for comprehensive protection
- Use
SAMEORIGINfor X-Frame-Options to prevent clickjacking - Set
1; mode=blockfor X-XSS-Protection to ensure XSS filtering is active - Configure Referrer-Policy to minimize data leakage
- Use Permissions-Policy to disable sensitive browser APIs by default
8. Configuring Bot Protection
| Directive | Description | Example |
|---|---|---|
| bot_detection | Enables or disables bot detection module | bot_detection on; |
| user_agent_block | Blocks specific user agents | user_agent_block "BadBot"; |
| rate_limit | Rate limit for requests per IP | rate_limit 10r/m; |
Example: Basic Bot Protection Configuration
server {
listen 80;
server_name example.com;
bot_detection on;
user_agent_block "BadBot";
rate_limit 10r/m;
location / {
proxy_pass http://backend;
}
}
Note: Bot protection can be enhanced with additional modules like
ngx_http_cloudflare_module for more advanced detection.
9. Implementing Request Validation
| Directive | Description | Example |
|---|---|---|
| limit_req | Controls request rate limiting based on a defined zone. | limit_req zone=api burst=5 nodelay; |
| limit_req_zone | Defines a zone for rate limiting with specified parameters. | limit_req_zone $binary_remote_addr zone=api:10m rate=1r/s; |
| limit_req_burst | Defines the maximum number of requests allowed in a burst. | limit_req zone=api burst=5; |
| limit_req_nodelay | Disables delay for burst requests. | limit_req zone=api burst=5 nodelay; |
Example: Rate Limiting Configuration
limit_req_zone $binary_remote_addr zone=api:10m rate=1r/s;
server {
listen 80;
location /api/ {
limit_req zone=api burst=5 nodelay;
proxy_pass http://backend;
}
}
| Directive | Description | Values |
|---|---|---|
| geo | Defines variables based on client IP address. | geo $country { 127.0.0.1 US; } |
| map | Maps a variable to another variable using a regular expression. | map $http_user_agent $is_mobile { ~*Mobile true; } |
| if | Conditional directive to execute blocks based on a condition. | if ($is_mobile) { return 403; } |
Example: Geo-based Access Control
geo $blocked_country {
default 0;
192.168.1.0/24 1;
}
server {
listen 80;
if ($blocked_country) {
return 403;
}
}
10. Using Encrypted SNI
| Directive | Description | Values | Notes |
|---|---|---|---|
| ssl_certificate | Specifies the certificate file for the server | /path/to/cert.pem |
Required for TLS |
| ssl_certificate_key | Specifies the private key file for the server | /path/to/key.pem |
Required for TLS |
| ssl_protocols | Enables specific TLS protocols | SSLv3 TLSv1 TLSv1.1 TLSv1.2 TLSv1.3 |
Recommend using TLSv1.2 and TLSv1.3 |
| ssl_ciphers | Specifies the list of ciphers to use for TLS | ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDH-RSA-AES256-GCM-SHA512 |
Use strong ciphers only |
| ssl_prefer_server_ciphers | Enables server cipher preference | on, off |
Recommended to set to on |
Example: Basic SSL Configuration
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDH-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers on;
location / {
root /var/www/html;
index index.html;
}
}
Note: Encrypted SNI (Server Name Indication) is an extension to the TLS protocol that allows a client to indicate the hostname it wishes to connect to during the initial handshake. This is useful for hosting multiple domains on a single IP address.
Warning: Ensure that all certificates used are valid and properly configured to avoid security vulnerabilities.
11. Hardening Worker Process
| Directive | Description | Default | Notes |
|---|---|---|---|
| worker_processes | Sets the number of worker processes | auto | Set to 1 for single-core systems or match CPU cores for multi-core |
| worker_connections | Maximum number of connections per worker process | 512 | Adjust based on system resources and expected load |
| worker_rlimit_nofile | Maximum number of file descriptors available to worker processes | unlimited | Set to a high value (e.g., 65536) to prevent resource exhaustion |
| worker_rlimit_sigpending | Maximum number of pending signals for worker processes | unlimited | Prevents signal queue overflow under high load |
Example: Hardened worker process configuration
worker_processes 1;
worker_connections 1024;
worker_rlimit_nofile 65536;
worker_rlimit_sigpending 8192;
events {
worker_connections 1024;
}
Note: Setting
worker_processes to 1 can reduce memory usage and simplify debugging in single-core environments.
Warning: Setting
worker_rlimit_nofile too low can cause "too many open files" errors under high load.
12. Preventing Path Traversal Attacks
| Directive | Description | Example |
|---|---|---|
| location | Defines how to handle requests to a specific URI or path. | location /files/ { ... } |
| alias | Maps a URI to a filesystem path. | alias /var/www/files/; |
| root | Defines the root directory for resolving file paths. | root /var/www/; |
Example: Secure File Serving with Root
server {
listen 80;
server_name example.com;
location /files/ {
root /var/www/;
autoindex off;
}
}
Example: Preventing Path Traversal with Alias
server {
listen 80;
server_name example.com;
location /secure/ {
alias /var/www/secure/;
autoindex off;
}
}
Note: Using
alias instead of root can prevent path traversal by ensuring that the requested path is always within a specific directory.
Warning: Never allow user input to directly influence the
root or alias directives without strict validation.
| Technique | Description | Effectiveness |
|---|---|---|
| Path Normalization | Ensures that all paths are normalized before processing. | High |
| Allowlist Validation | Only allows known safe paths to be accessed. | Very High |
| File Extension Restrictions | Restricts access to specific file types (e.g., .php, .pl). | Medium |