Securing Nginx Web Server Against Attacks

This tutorial provides step-by-step guidance to harden your Nginx server against common vulnerabilities. Follow these best practices to secure your de
Securing Nginx Web Server Against Attacks
This tutorial provides step-by-step guidance to harden your Nginx server against common vulnerabilities. Follow these best practices to secure your deployment.
Table of Contents
- Introduction
- Keep Nginx Updated
- Configure Firewall
- Disable Directory Listing
- Limit Server Metadata
- Enable HTTPS
- Enable Security Modules
- Restrict Access by IP
- Rate Limiting HTTP Requests
- Content Security Policy (CSP)
- Block Directory Traversal
- Monitor Logs with Fail2Ban
- Disable Unused Modules
- Additional Security Best Practices
- Summary
Introduction
Nginx is a high-performance web server, but security requires proactive configuration. This guide covers critical steps to mitigate risks like directory listing, brute-force attacks, and XSS vulnerabilities.
Update Nginx
Regularly update Nginx to patch vulnerabilities:
sudo apt update && sudo apt upgrade nginx Configure Firewall
Use ufw to restrict access to essential ports:
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable Explanation:
- SSH: Server management.
- HTTP/HTTPS: Web traffic.
Disable Directory Listing
Prevent sensitive files/directories from being listed:
- Edit your Nginx config:
sudo nano /etc/nginx/site-available/your_site - Add:
autoindex off; # Disable directory listing directory_index off; # Disable default index file - Apply changes:
sudo nginx -t && sudo systemctl reload nginx
Limit Server Metadata
Hide Nginx version and headers:
- Edit the main configuration:
sudo nano /etc/nginx/nginx.conf - Add:
server_tokens off; # Hide Nginx version server_name_in_redirect off; # Avoid leaks in redirects proxy_hide_header Server; # Hide headers in proxied requests - Apply changes:
sudo nginx -t && sudo systemctl reload nginx
Enable HTTPS with Let’s Encrypt
Automate SSL certificate setup:
- Install Certbot:
sudo apt install certbot python3-certbot-nginx - Generate a certificate:
sudo certbot --nginx -d yourdomain.com
Note: Certbot automatically configures redirects from http to https.
Enable Security Modules
Use built-in security features in Nginx:
Rate Limiting
Enable the limit_req module to throttle traffic:
sudo apt install nginx-extras # Includes rate limiting Configure in your site config:
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
location / {
limit_req zone=api_limit burst=20 nodelay;
} Custom Headers
Add security headers to all responses:
add_header Content-Security-Policy "default-src 'self'; script-src 'none'";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY; IP Whitelisting
Restrict access to authorized IPs:
location /admin {
allow 192.168.1.100;
allow 10.0.0.0/8;
deny all;
} Rate Limiting for Authentication
Protect login forms from brute-force attacks:
- Configure authentication:
auth_request user_login; - Create
/etc/nginx/locations/user_login:map $http_user_agent $bot_buster { default 0; "nginx" 1; # Block requests with UA containing "nginx" } location /login { allow_always $bot_buster; if ($bot_buster = 1) { return 444; } }
Content Security Policy (CSP)
Block cross-site scripting (XSS) by restricting script sources:
add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted-cdn.com" always; Block Directory Traversal
Prevent malicious URL manipulation:
location / {
if ($request_uri ~* /\.\./) {
return 403;
}
} Log Monitoring with Fail2Ban
Install Fail2Ban to auto-block IPs with repeated failed requests:
- Install Fail2Ban:
sudo apt install fail2ban - Create
/etc/fail2ban/jail.d/nginx.conf:[nginx-badbots] enabled = true port = http,https filter = nginx-badbots logpath = /var/log/nginx/access.log maxretry = 3 findtime = 600 bantime = 86400 - Restart Fail2Ban:
sudo systemctl restart fail2ban
Disable Unused Modules
Minimize server attack surface by disabling unused modules:
sudo systemctl stop nginx
sudo nano /etc/nginx/nginx.conf Remove unnecessary load_module blocks and reload:
sudo systemctl start nginx Additional Security Best Practices
- Enable HSTS:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; - Security Headers:
add_header X-XSS-Protection "1; mode=block" always; - File Permissions: Restrict access to sensitive files (e.g.,
chmod 600 /etc/nginx/conf.d/ssl.conf). - Backup Configs: Regularly back up
/etc/nginx/and SSL certificates.
Summary
By following these steps, you will harden your Nginx server against attacks:
- Keep Nginx updated.
- Use a firewall to limit exposed ports.
- Disable directory listing and traverse vulnerabilities.
- Enforce HTTPS with Let’s Encrypt.
- Enable rate limiting and monitoring (Fail2Ban).
- Hide server metadata and CSP headers.
Remember: Security is an ongoing process. Regularly audit your configurations!

Written by Robin te Hofstee
Technology enthusiast with a deep love for programming. Sharing practical guides on React, Next.js, Linux and self-hosting.
Related Posts
Securing a Next.js Application in Production
Securing a Next.js app in production means protecting the client bundle, the server, and the data flow. This post shows how to lock down Content‑Secur
How Git Works
Git is a distributed version control system that allows multiple people to collaborate on a project while maintaining a complete history of all change
How to Check Disk Usage and Find Large Files on Linux
After setting up a new Linux server, you’ll want to know how to check what’s taking up space. Disk space is often the weakest link in system stability


