iproxy 0.3.0

Proxy server for IP geolocation. Use external services to get the geolocation of an IP address.
user nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$real_ip_remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    # Hide Nginx version information
    server_tokens off;

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    # Set timeouts to mitigate slow client attacks
    client_body_timeout 12s;
    client_header_timeout 12s;
    keepalive_timeout 15s;
    send_timeout 10s;

    # Limit request sizes to prevent buffer overflow attacks
    client_max_body_size 10M;
    client_body_buffer_size 1k;
    client_header_buffer_size 1k;
    large_client_header_buffers 2 1k;

    # Define a rate limiting zone named 'mylimit' with a size of 10MB
    # Limit each IP to 10 requests per second
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

    # Security headers to mitigate common attacks
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Content-Security-Policy "default-src 'self';" always;

    # Real IP configuration
    set_real_ip_from 0.0.0.0/0;      # Allow from all sources (or use specific IP ranges)
    real_ip_header X-Forwarded-For;  # Specify the header that contains the real IP
    real_ip_recursive on;            # Use the last trusted IP in the chain

    server {
        listen 80;
        server_name api.${VIRTUAL_HOST};

        # Restrict allowed HTTP methods
        if ($request_method !~ ^(GET)$ ) {
            return 405;
        }

        location /iproxy {
            limit_req zone=mylimit burst=20 nodelay;
            limit_except GET { deny all; }

            # Rewrite the URI to include /api/v1 before proxying
            rewrite ^/ifconfig/(.*)$ /api/v1/$1 break;

            proxy_pass http://iproxy:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $real_ip_remote_addr; # Pass real client IP
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }

        # Define a custom error page for rate-limited responses
        error_page 429 /custom_429.html;
        location = /custom_429.html {
            internal;
            root /usr/share/nginx/html;
        }
    }
}