apiVersion: v1
kind: ConfigMap
metadata:
  name: rpc-gateway-config
  namespace: besu-network
data:
  nginx.conf: |
    upstream besu_rpc {
        least_conn;
        server besu-rpc-0.besu-rpc.besu-network.svc.cluster.local:8545;
        server besu-rpc-1.besu-rpc.besu-network.svc.cluster.local:8545;
        server besu-rpc-2.besu-rpc.besu-network.svc.cluster.local:8545;
    }
    
    upstream besu_ws {
        least_conn;
        server besu-rpc-0.besu-rpc.besu-network.svc.cluster.local:8546;
        server besu-rpc-1.besu-rpc.besu-network.svc.cluster.local:8546;
        server besu-rpc-2.besu-rpc.besu-network.svc.cluster.local:8546;
    }
    
    # Rate limiting zones
    limit_req_zone $binary_remote_addr zone=rpc_limit:10m rate=20r/s;
    limit_req_zone $binary_remote_addr zone=ws_limit:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=call_limit:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=logs_limit:10m rate=5r/s;
    
    # HTTP server
    server {
        listen 80;
        server_name _;
        
        # Redirect to HTTPS
        return 301 https://$host$request_uri;
    }
    
    # HTTPS server
    server {
        listen 443 ssl http2;
        server_name _;
        
        # SSL configuration
        ssl_certificate /etc/nginx/ssl/tls.crt;
        ssl_certificate_key /etc/nginx/ssl/tls.key;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
        
        # Security headers
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
        add_header X-Frame-Options "DENY" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-XSS-Protection "1; mode=block" always;
        
        # CORS headers - Update with your actual domains
        # add_header Access-Control-Allow-Origin "https://yourdomain.com" always;
        # add_header Access-Control-Allow-Origin "https://app.yourdomain.com" always;
        add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
        add_header Access-Control-Allow-Headers "Content-Type, Authorization, X-API-Key" always;
        
        # IP allowlisting for admin operations (example)
        # location /admin {
        #     allow 10.0.0.0/16;  # Internal only
        #     deny all;
        #     proxy_pass http://besu_rpc;
        # }
        
        # Handle preflight requests
        if ($request_method = OPTIONS) {
            return 204;
        }
        
        # JSON-RPC endpoint
        location / {
            limit_req zone=rpc_limit burst=50 nodelay;
            
            # Block write methods for public users
            # This is handled by the method policy, but we can add additional checks here
            if ($request_body ~* "eth_sendTransaction|eth_sendRawTransaction|miner_|admin_") {
                return 403 "Write operations are not allowed";
            }
            
            proxy_pass http://besu_rpc;
            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;
            
            # Timeouts
            proxy_connect_timeout 60s;
            proxy_send_timeout 60s;
            proxy_read_timeout 60s;
            
            # Buffer settings
            proxy_buffering off;
            proxy_request_buffering off;
            
            # Body size limit
            client_max_body_size 1m;
        }
        
        # WebSocket endpoint
        location /ws {
            limit_req zone=ws_limit burst=20 nodelay;
            
            proxy_pass http://besu_ws;
            proxy_http_version 1.1;
            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;
            
            # WebSocket timeouts
            proxy_connect_timeout 7d;
            proxy_send_timeout 7d;
            proxy_read_timeout 7d;
        }
        
        # Health check endpoint
        location /health {
            access_log off;
            return 200 "healthy\n";
            add_header Content-Type text/plain;
        }
        
        # Metrics endpoint (internal only)
        location /metrics {
            allow 10.0.0.0/16;
            deny all;
            
            proxy_pass http://besu_rpc;
            proxy_set_header Host $host;
        }
    }

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: rpc-gateway
  namespace: besu-network
  labels:
    app: rpc-gateway
spec:
  replicas: 2
  selector:
    matchLabels:
      app: rpc-gateway
  template:
    metadata:
      labels:
        app: rpc-gateway
    spec:
      containers:
        - name: nginx
          image: nginx:alpine
          ports:
            - name: http
              containerPort: 80
            - name: https
              containerPort: 443
          volumeMounts:
            - name: config
              mountPath: /etc/nginx/nginx.conf
              subPath: nginx.conf
            - name: ssl
              mountPath: /etc/nginx/ssl
              readOnly: true
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "500m"
              memory: "256Mi"
          livenessProbe:
            httpGet:
              path: /health
              port: 80
            initialDelaySeconds: 10
            periodSeconds: 30
          readinessProbe:
            httpGet:
              path: /health
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 10
      volumes:
        - name: config
          configMap:
            name: rpc-gateway-config
        - name: ssl
          secret:
            secretName: rpc-gateway-ssl
---
apiVersion: v1
kind: Service
metadata:
  name: rpc-gateway
  namespace: besu-network
  labels:
    app: rpc-gateway
spec:
  type: LoadBalancer
  ports:
    - name: http
      port: 80
      targetPort: http
      protocol: TCP
    - name: https
      port: 443
      targetPort: https
      protocol: TCP
  selector:
    app: rpc-gateway

