NGINX - Reverse Proxy

From IT-Arts.net


Return to Wiki Index


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