How I Built a Secure Reverse Proxy with Nginx
Source: Dev.to
Introduction
A reverse proxy is one of the most powerful building blocks in modern web infrastructure. It sits between users and your backend services, acting as a gatekeeper that can improve performance, enforce security policies, and control traffic.
By the end of this guide you’ll have a practical setup you can deploy in front of your applications.
Reverse Proxy Architecture
At a high level, a reverse proxy sits between clients and your backend servers. Instead of users directly accessing your application server, all requests first go through the proxy.
Client
│
▼
Reverse Proxy (Nginx)
│
▼
Application Server
Benefits
- Hide internal infrastructure
- Centralize security policies
- Terminate TLS in one place
- Add traffic filtering and monitoring
Example Scenario
Internet
│
▼
Nginx Reverse Proxy
├── API Server (Node.js)
├── Web App (React / Next.js)
└── Admin Panel
Simple Reverse Proxy Configuration
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
What this does
- Accepts HTTP requests
- Forwards them to the backend application
- Preserves client IP information
Rate Limiting
Public services often face bot traffic, scanners, and brute‑force attacks. Rate limiting helps protect your application by restricting how many requests a client can make.
Define a Rate Limit Zone
http {
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
}
Apply Rate Limiting in a Server Block
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://backend_api;
}
Configuration details
- Limit: 10 requests per second
- Burst: Allows short spikes
- Protects API endpoints from abuse
Rate limiting is especially effective against automated scanners and brute‑force attacks.
Security Headers
Adding security headers helps protect browsers and users from common web vulnerabilities. You can add them directly in Nginx.
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "no-referrer-when-downgrade";
add_header Content-Security-Policy "default-src 'self'";
These headers help defend against:
- Clickjacking
- Content‑type sniffing
- Cross‑site scripting (XSS)
- Data leakage
They add an additional layer of client‑side protection.
Logging
Logging is essential for visibility and incident response.
Basic Log Configuration
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
Custom Log Format
log_format security_log '$remote_addr - $request - $status - $http_user_agent';
access_log /var/log/nginx/security.log security_log;
Useful data in logs
- Client IP
- Request path
- HTTP status codes
- User agents
- Request timing
Logs often reveal automated scanning and attack attempts hitting your endpoints.
Additional Best Practices
-
Enable HTTPS with TLS
-
Disable unnecessary HTTP methods
-
Hide server version information
server_tokens off; -
Restrict admin endpoints
-
Use upstream health checks
These practices further harden your reverse proxy against attacks.
Conclusion
A reverse proxy is much more than just a traffic router—it can act as a powerful security layer in front of your applications. With a few Nginx configurations you can implement:
- Traffic control
- Security headers
- Request logging
- Basic attack mitigation
These protections significantly reduce your exposure to automated attacks. If you want a ready‑to‑use security layer, projects like SafeLine WAF implement many of these protections out of the box.