NGINX - Reverse Proxy
General Configuration Structure
In a reverse proxy setup, Nginx receives client requests and forwards them to an upstream server (e.g., an application server or a web service). This allows Nginx to handle multiple protocols, such as HTTP and TCP, while acting as a gateway for secure and optimized traffic management.
The configuration files for Nginx are typically located in the `/etc/nginx/` directory, with the main configuration file being `/etc/nginx/nginx.conf` and additional server block files in `/etc/nginx/sites-available/` or `/etc/nginx/conf.d/`.
Reverse Proxy for HTTP
The HTTP reverse proxy is the most common use case for Nginx. Below is a sample configuration for forwarding HTTP requests to an upstream server.
Basic HTTP Reverse Proxy
The basic configuration uses the `proxy_pass` directive to forward requests to an upstream server.
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8080; # Forward to the backend HTTP server
proxy_set_header Host $host; # Preserve the original host header
proxy_set_header X-Real-IP $remote_addr; # Pass the real client IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Add to X-Forwarded-For header
proxy_set_header X-Forwarded-Proto $scheme; # Pass the protocol (http/https)
}
}
Load Balancing with HTTP Reverse Proxy
Nginx can distribute incoming HTTP traffic among multiple backend servers for load balancing. Here is an example configuration for load balancing.
http {
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend; # Load balancing to the upstream servers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
Enabling SSL for HTTP Reverse Proxy
To ensure secure communication, you can add SSL support by configuring the `ssl_certificate` and `ssl_certificate_key` directives.
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Reverse Proxy for TCP
Nginx can also be configured as a reverse proxy for TCP traffic. This is particularly useful for protocols like MySQL, PostgreSQL, or custom TCP-based applications.
Basic TCP Reverse Proxy
For TCP proxying, Nginx uses the `stream` context instead of the `http` context. Here's an example of a basic TCP reverse proxy setup:
stream {
upstream mysql_backend {
server 192.168.1.10:3306;
server 192.168.1.11:3306;
}
server {
listen 3306;
proxy_pass mysql_backend; # Forward MySQL requests to the upstream backend servers
}
}
TCP Load Balancing
For TCP-based load balancing, the configuration can distribute traffic to multiple backend servers. This is typically used for databases or other stateful applications.
stream {
upstream mysql_backend {
server 192.168.1.10:3306;
server 192.168.1.11:3306;
server 192.168.1.12:3306;
}
server {
listen 3306;
proxy_pass mysql_backend; # Load balancing for TCP traffic
}
}
Advanced Configuration Settings
Connection Timeout Settings
To improve the performance and reliability of your reverse proxy, it is essential to manage timeouts. These parameters control how long Nginx waits for responses from the upstream servers.
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 60s; # Timeout for establishing a connection to the backend
proxy_send_timeout 60s; # Timeout for sending a request to the upstream server
proxy_read_timeout 60s; # Timeout for receiving a response from the backend
}
}
Buffering and Caching
By default, Nginx buffers responses from upstream servers, which can help prevent overwhelming the client with slow responses. However, buffering may be disabled for specific use cases (e.g., streaming media).
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off; # Disable response buffering (useful for media streaming)
}
}
Rate Limiting for Reverse Proxy
To prevent abuse, you can enable rate limiting on the reverse proxy.
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
limit_req zone=req_limit_per_ip burst=10 nodelay; # Rate limiting per client IP
}
}
# Define rate limit zone
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=1r/s;
Monitoring and Logging
Enabling Access Logs
Nginx logs client requests by default. You can customize the log format and specify the location for logs.
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
}
Enabling Error Logs
Error logs help in diagnosing issues with Nginx itself or the upstream servers.
error_log /var/log/nginx/error.log warn; # Set the error log level to "warn"
Testing and Reloading Configuration
After making changes to the Nginx configuration, it is crucial to test and reload Nginx to apply the changes.
To test the configuration:
sudo nginx -t # Test the configuration for syntax errors
To reload Nginx with the new configuration:
sudo systemctl reload nginx # Reload the Nginx service without downtime
Linux Commands for Nginx Management
- To start Nginx:
sudo systemctl start nginx
- To stop Nginx:
sudo systemctl stop nginx
- To restart Nginx:
sudo systemctl restart nginx
- To enable Nginx to start on boot:
sudo systemctl enable nginx
- To check the status of Nginx:
sudo systemctl status nginx
