Files
proxmox/docs/04-configuration/NGINX_CONFIGURATIONS_VMIDS_2400-2508.md
defiQUG cb47cce074 Complete markdown files cleanup and organization
- Organized 252 files across project
- Root directory: 187 → 2 files (98.9% reduction)
- Moved configuration guides to docs/04-configuration/
- Moved troubleshooting guides to docs/09-troubleshooting/
- Moved quick start guides to docs/01-getting-started/
- Moved reports to reports/ directory
- Archived temporary files
- Generated comprehensive reports and documentation
- Created maintenance scripts and guides

All files organized according to established standards.
2026-01-06 01:46:25 -08:00

19 KiB

Nginx Configurations for VMIDs 2400-2508

Date: 2026-01-27
Status: Current Active Configurations


Summary

VMID Active Config Status Purpose
2400 rpc-thirdweb Active ThirdWeb RPC endpoint (Cloudflare Tunnel)
2500 rpc-core Active Core RPC node (internal/permissioned)
2500 rpc-public ⚠️ Not active Public RPC endpoints (backup config)
2501 rpc-perm Active Permissioned RPC with JWT auth
2501 rpc-public ⚠️ Not active Public RPC endpoints (backup config)
2502 rpc Active Public RPC endpoints (no auth)
2503-2508 N/A Nginx not installed Besu validator/sentry nodes (no RPC)

VMID 2400 - ThirdWeb RPC (Cloudflare Tunnel)

Active Config: /etc/nginx/sites-enabled/rpc-thirdweb
Domain: rpc.public-0138.defi-oracle.io
IP: 192.168.11.240

Configuration Overview

  • Port 80: Returns 204 (no redirect) for RPC clients
  • Port 443: HTTPS server handling both HTTP RPC and WebSocket RPC
  • Backend:
    • HTTP RPC → 127.0.0.1:8545
    • WebSocket RPC → 127.0.0.1:8546 (detected via $http_upgrade header)
  • SSL: Cloudflare Origin Certificate
  • Cloudflare Integration: Real IP headers configured for Cloudflare IP ranges

Key Features

  • WebSocket detection via $http_upgrade header
  • CORS headers enabled for ThirdWeb web apps
  • Cloudflare real IP support
  • Health check endpoint at /health

Full Configuration

# RPC endpoint for rpc.public-0138.defi-oracle.io

server {
    listen 80;
    listen [::]:80;
    server_name rpc.public-0138.defi-oracle.io;

    # Avoid redirects for RPC clients (prevents loops and broken POST behavior)
    return 204;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name rpc.public-0138.defi-oracle.io;

    ssl_certificate     /etc/nginx/ssl/cloudflare-origin.crt;
    ssl_certificate_key /etc/nginx/ssl/cloudflare-origin.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    access_log /var/log/nginx/rpc-thirdweb-access.log;
    error_log  /var/log/nginx/rpc-thirdweb-error.log;

    client_max_body_size 10M;

    proxy_connect_timeout 300s;
    proxy_send_timeout    300s;
    proxy_read_timeout    300s;
    send_timeout          300s;

    # Optional: if you need real client IPs from Cloudflare
    real_ip_header CF-Connecting-IP;
    set_real_ip_from 173.245.48.0/20;
    set_real_ip_from 103.21.244.0/22;
    set_real_ip_from 103.22.200.0/22;
    set_real_ip_from 103.31.4.0/22;
    set_real_ip_from 141.101.64.0/18;
    set_real_ip_from 108.162.192.0/18;
    set_real_ip_from 190.93.240.0/20;
    set_real_ip_from 188.114.96.0/20;
    set_real_ip_from 197.234.240.0/22;
    set_real_ip_from 198.41.128.0/17;
    set_real_ip_from 162.158.0.0/15;
    set_real_ip_from 104.16.0.0/13;
    set_real_ip_from 104.24.0.0/14;
    set_real_ip_from 172.64.0.0/13;
    set_real_ip_from 131.0.72.0/22;

    location / {
        # Default backend = HTTP RPC
        set $backend "http://127.0.0.1:8545";

        # If websocket upgrade requested, use WS backend
        if ($http_upgrade = "websocket") {
            set $backend "http://127.0.0.1:8546";
        }

        proxy_pass $backend;
        proxy_http_version 1.1;

        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;

        # WebSocket support (safe defaults)
        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_buffering off;
        proxy_request_buffering off;

        # CORS (optional; keep if Thirdweb/browser clients need it)
        add_header Access-Control-Allow-Origin "*" always;
        add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
        add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;

        if ($request_method = OPTIONS) {
            return 204;
        }
    }

    location /health {
        access_log off;
        add_header Content-Type text/plain;
        return 200 "healthy\n";
    }
}

VMID 2500 - Core RPC Node

Active Config: /etc/nginx/sites-enabled/rpc-core
Domains:

  • rpc-core.d-bis.org
  • besu-rpc-1
  • 192.168.11.250
  • rpc-core.besu.local
  • rpc-core.chainid138.local

IP: 192.168.11.250

Configuration Overview

  • Port 80: HTTP to HTTPS redirect
  • Port 443: HTTPS HTTP RPC API (proxies to 127.0.0.1:8545)
  • Port 8443: HTTPS WebSocket RPC API (proxies to 127.0.0.1:8546)
  • SSL: Let's Encrypt certificate (rpc-core.d-bis.org)
  • Rate Limiting: Enabled (zones: rpc_limit, rpc_burst, conn_limit)

Key Features

  • Rate limiting enabled
  • Metrics endpoint at /metrics (proxies to port 9545)
  • Separate ports for HTTP RPC (443) and WebSocket RPC (8443)
  • Health check endpoints

Full Configuration

# HTTP to HTTPS redirect
server {
    listen 80;
    listen [::]:80;
    server_name rpc-core.d-bis.org besu-rpc-1 192.168.11.250 rpc-core.besu.local rpc-core.chainid138.local;
    
    # Redirect all HTTP to HTTPS
    return 301 https://$host$request_uri;
}

# HTTPS server - HTTP RPC API (port 8545)
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name rpc-core.d-bis.org besu-rpc-1 192.168.11.250 rpc-core.besu.local rpc-core.chainid138.local rpc-core.chainid138.local;

    # SSL configuration
    ssl_certificate /etc/letsencrypt/live/rpc-core.d-bis.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/rpc-core.d-bis.org/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # Security headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # Logging
    access_log /var/log/nginx/rpc-core-http-access.log;
    error_log /var/log/nginx/rpc-core-http-error.log;

    # Increase timeouts for RPC calls
    proxy_connect_timeout 300s;
    proxy_send_timeout 300s;
    proxy_read_timeout 300s;
    send_timeout 300s;
    client_max_body_size 10M;

    # HTTP RPC endpoint (port 8545)
    location / {
        proxy_pass http://127.0.0.1:8545;
        limit_req zone=rpc_limit burst=20 nodelay;
        limit_conn conn_limit 10;
        
        # Rate limiting
        proxy_http_version 1.1;
        
        # Headers
        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_set_header Connection "";
        
        # Buffer settings (disable for RPC)
        proxy_buffering off;
        proxy_request_buffering off;
        
        # CORS headers (if needed for web apps)
        add_header Access-Control-Allow-Origin * always;
        add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
        add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
        
        # Handle OPTIONS requests
        if ($request_method = OPTIONS) {
            return 204;
        }
    }

    # Health check endpoint
    location /health {
        access_log off;
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }

    # Metrics endpoint (if exposed)
    location /metrics {
        proxy_pass http://127.0.0.1:9545;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

# HTTPS server - WebSocket RPC API (port 8546)
server {
    listen 8443 ssl http2;
    listen [::]:8443 ssl http2;
    server_name besu-rpc-1 192.168.11.250 rpc-core-ws.besu.local rpc-core-ws.chainid138.local;

    # SSL configuration
    ssl_certificate /etc/letsencrypt/live/rpc-core.d-bis.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/rpc-core.d-bis.org/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # Security headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # Logging
    access_log /var/log/nginx/rpc-core-ws-access.log;
    error_log /var/log/nginx/rpc-core-ws-error.log;

    # WebSocket RPC endpoint (port 8546)
    location / {
        proxy_pass http://127.0.0.1:8546;
        limit_req zone=rpc_burst burst=50 nodelay;
        limit_conn conn_limit 5;
        
        # Rate limiting
        proxy_http_version 1.1;
        
        # WebSocket headers
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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;
        
        # Long timeouts for WebSocket connections
        proxy_read_timeout 86400;
        proxy_send_timeout 86400;
        proxy_connect_timeout 300s;
    }

    # Health check endpoint
    location /health {
        access_log off;
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }
}

Note: There's also a rpc-public config file that's not currently active.


VMID 2501 - Permissioned RPC (JWT Authentication)

Active Config: /etc/nginx/sites-enabled/rpc-perm
Domains:

  • rpc-http-prv.d-bis.org (HTTP RPC with JWT)
  • rpc-ws-prv.d-bis.org (WebSocket RPC with JWT)
  • besu-rpc-2
  • 192.168.11.251

IP: 192.168.11.251

Configuration Overview

  • Port 80: HTTP to HTTPS redirect
  • Port 443: HTTPS servers for both HTTP RPC and WebSocket RPC (same port, different server_name)
  • JWT Authentication: Required for all RPC endpoints (via auth_request to http://127.0.0.1:8888/validate)
  • SSL: Self-signed certificate (/etc/nginx/ssl/rpc.crt)

Key Features

  • JWT authentication using auth_request module
  • JWT validator service running on port 8888
  • Separate error handling for authentication failures
  • Health check endpoint (no JWT required)

Full Configuration

# HTTP to HTTPS redirect
server {
    listen 80;
    listen [::]:80;
    server_name rpc-http-prv.d-bis.org rpc-ws-prv.d-bis.org besu-rpc-2 192.168.11.251;
    return 301 https://$host$request_uri;
}

# Internal server for JWT validation
server {
    server_name _;
    
    location /validate {
        fastcgi_pass unix:/var/run/fcgiwrap.socket;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /usr/local/bin/jwt-validate.py;
        fastcgi_param HTTP_AUTHORIZATION $http_authorization;
    }
}

# HTTPS server - HTTP RPC API (Permissioned with JWT)
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name rpc-http-prv.d-bis.org besu-rpc-2 192.168.11.251;

    ssl_certificate /etc/nginx/ssl/rpc.crt;
    ssl_certificate_key /etc/nginx/ssl/rpc.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    access_log /var/log/nginx/rpc-http-prv-access.log;
    error_log /var/log/nginx/rpc-http-prv-error.log;

    proxy_connect_timeout 300s;
    proxy_send_timeout 300s;
    proxy_read_timeout 300s;
    send_timeout 300s;

    # JWT authentication using auth_request
    location = /auth {
        internal;
        proxy_pass http://127.0.0.1:8888/validate;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Original-URI $request_uri;
        proxy_set_header Authorization $http_authorization;
    }

    # HTTP RPC endpoint
    location / {
        auth_request /auth;
        auth_request_set $auth_status $upstream_status;
        
        # Return 401 if auth failed
        error_page 401 = @auth_failed;
        
        proxy_pass http://127.0.0.1:8545;
        proxy_http_version 1.1;
        proxy_set_header Host localhost;
        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_set_header Connection "";
        proxy_buffering off;
        proxy_request_buffering off;
    }
    
    # Handle auth failures
    location @auth_failed {
        return 401 '{"jsonrpc":"2.0","error":{"code":-32000,"message":"Unauthorized. Missing or invalid JWT token. Use: Authorization: Bearer <token>"},"id":null}';
        add_header Content-Type application/json;
    }

    # Health check endpoint (no JWT required)
    location /health {
        access_log off;
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }
}

# HTTPS server - WebSocket RPC API (Permissioned with JWT)
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name rpc-ws-prv.d-bis.org;

    ssl_certificate /etc/nginx/ssl/rpc.crt;
    ssl_certificate_key /etc/nginx/ssl/rpc.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    access_log /var/log/nginx/rpc-ws-prv-access.log;
    error_log /var/log/nginx/rpc-ws-prv-error.log;

    # JWT authentication for WebSocket connections
    location = /auth {
        internal;
        proxy_pass http://127.0.0.1:8888/validate;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Original-URI $request_uri;
        proxy_set_header Authorization $http_authorization;
    }

    location / {
        auth_request /auth;
        auth_request_set $auth_status $upstream_status;
        
        error_page 401 = @auth_failed;
        
        proxy_pass http://127.0.0.1:8546;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host localhost;
        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_read_timeout 86400;
        proxy_send_timeout 86400;
    }
    
    location @auth_failed {
        return 401 '{"error": "Unauthorized. Missing or invalid JWT token. Use: Authorization: Bearer <token>"}';
        add_header Content-Type application/json;
    }

    # Health check endpoint (no JWT required)
    location /health {
        access_log off;
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }
}

Note: There's also a rpc-public config file that's not currently active.


VMID 2502 - Public RPC (No Authentication)

Active Config: /etc/nginx/sites-enabled/rpc
Domains:

  • rpc-http-prv.d-bis.org (HTTP RPC - Note: domain name suggests private but config has no auth)
  • rpc-ws-prv.d-bis.org (WebSocket RPC - Note: domain name suggests private but config has no auth)
  • rpc-http-pub.d-bis.org (Public HTTP RPC)
  • rpc-ws-pub.d-bis.org (Public WebSocket RPC)
  • besu-rpc-3
  • 192.168.11.252

IP: 192.168.11.252

Configuration Overview

  • Port 80: HTTP to HTTPS redirect
  • Port 443: HTTPS servers for multiple domains (HTTP RPC and WebSocket RPC)
  • Authentication: None (all endpoints are public)
  • SSL: Self-signed certificate (/etc/nginx/ssl/rpc.crt)
  • Cloudflare Integration: Real IP headers configured

Key Features

  • No authentication required (public endpoints)
  • CORS headers enabled
  • Multiple server blocks for different domain names
  • Cloudflare real IP support for public domains

Configuration Notes

⚠️ Important: The configuration includes server blocks for both rpc-http-prv.d-bis.org/rpc-ws-prv.d-bis.org (which suggests private endpoints) and rpc-http-pub.d-bis.org/rpc-ws-pub.d-bis.org (public endpoints), but none of them require authentication. This appears to be a configuration where VMID 2502 handles public RPC endpoints, while VMID 2501 handles the authenticated private endpoints.

Full Configuration

The configuration file contains 4 server blocks:

  1. HTTP to HTTPS redirect (port 80)
  2. HTTPS server for rpc-http-prv.d-bis.org (HTTP RPC, no auth)
  3. HTTPS server for rpc-ws-prv.d-bis.org (WebSocket RPC, no auth)
  4. HTTPS server for rpc-http-pub.d-bis.org (Public HTTP RPC, no auth)
  5. HTTPS server for rpc-ws-pub.d-bis.org (Public WebSocket RPC, no auth)

All server blocks proxy to:

  • HTTP RPC: 127.0.0.1:8545
  • WebSocket RPC: 127.0.0.1:8546

See previous command output for the complete configuration (too long to include here).


VMIDs 2503-2508 - No Nginx

Status: Nginx is not installed on these containers

These VMIDs are Besu validator or sentry nodes that do not expose RPC endpoints, so nginx is not required.


Summary of Port Usage

VMID Port 80 Port 443 Port 8443 Purpose
2400 Returns 204 HTTP/WebSocket RPC - ThirdWeb RPC (Cloudflare Tunnel)
2500 Redirect to 443 HTTP RPC WebSocket RPC Core RPC (internal)
2501 Redirect to 443 HTTP/WebSocket RPC (JWT) - Permissioned RPC
2502 Redirect to 443 HTTP/WebSocket RPC (public) - Public RPC
2503-2508 N/A N/A N/A No nginx installed

SSL Certificates

VMID Certificate Type Location
2400 Cloudflare Origin Certificate /etc/nginx/ssl/cloudflare-origin.crt
2500 Let's Encrypt /etc/letsencrypt/live/rpc-core.d-bis.org/
2501 Self-signed /etc/nginx/ssl/rpc.crt
2502 Self-signed /etc/nginx/ssl/rpc.crt

Access Patterns

Public Endpoints (No Authentication)

  • rpc.public-0138.defi-oracle.io (VMID 2400) - ThirdWeb RPC
  • rpc-http-pub.d-bis.org (VMID 2502) - Public HTTP RPC
  • rpc-ws-pub.d-bis.org (VMID 2502) - Public WebSocket RPC

Permissioned Endpoints (JWT Authentication Required)

  • rpc-http-prv.d-bis.org (VMID 2501) - Permissioned HTTP RPC
  • rpc-ws-prv.d-bis.org (VMID 2501) - Permissioned WebSocket RPC

Internal/Core Endpoints

  • rpc-core.d-bis.org (VMID 2500) - Core RPC node (internal use)

Last Updated: 2026-01-27