DEV Community

Hawkinsdev
Hawkinsdev

Posted on

How I Built a Secure Reverse Proxy with Nginx

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.

In this article, I'll walk through how I built a secure reverse proxy using Nginx, including:

  • Reverse proxy architecture
  • Rate limiting to stop abuse
  • Security headers for safer responses
  • Request logging for visibility

By the end, 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
Enter fullscreen mode Exit fullscreen mode

Benefits of this architecture:

  • 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
Enter fullscreen mode Exit fullscreen mode

This makes Nginx the entry point for all incoming traffic.


Basic Nginx Reverse Proxy Configuration

A simple reverse proxy configuration might look like this:

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;
    }
}
Enter fullscreen mode Exit fullscreen mode

What this does:

  • Accepts HTTP requests
  • Forwards them to the backend application
  • Preserves client IP information

This is the foundation, but by itself it doesn't provide much security.


Adding 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.

First, define a rate limit zone:

http {
    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
}
Enter fullscreen mode Exit fullscreen mode

Then apply it in your server block:

location /api/ {
    limit_req zone=api_limit burst=20 nodelay;
    proxy_pass http://backend_api;
}
Enter fullscreen mode Exit fullscreen mode

This configuration:

Limit: 10 requests per second
Burst: allow short spikes
Protects API endpoints from abuse
Enter fullscreen mode Exit fullscreen mode

Rate limiting is especially effective against automated scanners and brute-force attacks.


Adding Security Headers

Security headers help protect browsers and users from common web vulnerabilities.

You can add them directly in Nginx.

Example configuration:

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'";
Enter fullscreen mode Exit fullscreen mode

These headers help defend against:

clickjacking
content-type sniffing
cross-site scripting
data leakage
Enter fullscreen mode Exit fullscreen mode

They add an additional layer of client-side protection.


Enabling Access Logging

Logging is essential for visibility and incident response.

With Nginx logs you can:

  • detect suspicious traffic
  • identify attack patterns
  • debug application issues
  • analyze performance

Example configuration:

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
Enter fullscreen mode Exit fullscreen mode

You can also customize log formats:

log_format security_log '$remote_addr - $request - $status - $http_user_agent';

access_log /var/log/nginx/security.log security_log;
Enter fullscreen mode Exit fullscreen mode

Useful data in logs:

client IP
request path
HTTP status codes
user agents
request timing
Enter fullscreen mode Exit fullscreen mode

Logs often reveal automated scanning and attack attempts hitting your endpoints.


Extra Hardening Tips

In production environments, you may want to go further.

Additional best practices:

Enable HTTPS with TLS
Disable unnecessary HTTP methods
Hide server version information
Restrict admin endpoints
Use upstream health checks
Enter fullscreen mode Exit fullscreen mode

Example:

server_tokens off;
Enter fullscreen mode Exit fullscreen mode

This prevents Nginx from exposing its version number in responses.


Final Thoughts

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
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)