# AITBC Nginx Reverse Proxy Configuration # Domain: aitbc.keisanki.net # This configuration replaces the need for firehol/iptables port forwarding # HTTP to HTTPS redirect server { listen 80; server_name aitbc.keisanki.net; # Redirect all HTTP traffic to HTTPS return 301 https://$server_name$request_uri; } # Main HTTPS server block server { listen 443 ssl http2; server_name aitbc.keisanki.net; # SSL Configuration (Let's Encrypt certificates) ssl_certificate /etc/letsencrypt/live/aitbc.keisanki.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/aitbc.keisanki.net/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # Security headers 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' http: https: data: blob: 'unsafe-inline' 'unsafe-eval'" always; # Enable gzip compression gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json; # Blockchain Explorer (main route) location / { proxy_pass http://192.168.100.10:3000; 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; # WebSocket support if needed proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } # Coordinator API location /api/ { proxy_pass http://192.168.100.10:8000/v1/; 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; # CORS headers for API add_header Access-Control-Allow-Origin "*" always; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always; add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,X-Api-Key" always; # Handle preflight requests if ($request_method = 'OPTIONS') { add_header Access-Control-Allow-Origin "*"; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"; add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,X-Api-Key"; add_header Access-Control-Max-Age 1728000; add_header Content-Type "text/plain; charset=utf-8"; add_header Content-Length 0; return 204; } } # Blockchain Node 1 RPC location /rpc/ { proxy_pass http://192.168.100.10:8082/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; proxy_buffering off; } # Blockchain Node 2 RPC (alternative endpoint) location /rpc2/ { proxy_pass http://192.168.100.10:8081/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; proxy_buffering off; } # Exchange API location /exchange/ { proxy_pass http://192.168.100.10:9080/; 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; } # Marketplace UI (if separate from explorer) location /marketplace/ { proxy_pass http://192.168.100.10:3001/; 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; # Handle subdirectory rewrite rewrite ^/marketplace/(.*)$ /$1 break; } # Admin dashboard location /admin/ { proxy_pass http://192.168.100.10: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; # Optional: Restrict admin access # allow 192.168.100.0/24; # allow 127.0.0.1; # deny all; } # Health check endpoint location /health { access_log off; return 200 "healthy\n"; add_header Content-Type text/plain; } # API health checks location /api/health { proxy_pass http://192.168.100.10:8000/v1/health; proxy_set_header Host $host; access_log off; } # Static assets caching location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { proxy_pass http://192.168.100.10:3000; expires 1y; add_header Cache-Control "public, immutable"; add_header X-Content-Type-Options nosniff; # Don't log static file access access_log off; } # Deny access to hidden files location ~ /\. { deny all; access_log off; log_not_found off; } # Custom error pages error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } # Optional: Subdomain for API-only access server { listen 443 ssl http2; server_name api.aitbc.keisanki.net; # SSL Configuration (same certificates) ssl_certificate /etc/letsencrypt/live/aitbc.keisanki.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/aitbc.keisanki.net/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # Security headers add_header X-Frame-Options "DENY" 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; # API routes only location / { proxy_pass http://192.168.100.10:8000/v1/; 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; # CORS headers add_header Access-Control-Allow-Origin "*" always; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always; add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,X-Api-Key" always; # Handle preflight requests if ($request_method = 'OPTIONS') { add_header Access-Control-Allow-Origin "*"; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"; add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,X-Api-Key"; add_header Access-Control-Max-Age 1728000; add_header Content-Type "text/plain; charset=utf-8"; add_header Content-Length 0; return 204; } } } # Optional: Subdomain for blockchain RPC server { listen 443 ssl http2; server_name rpc.aitbc.keisanki.net; # SSL Configuration ssl_certificate /etc/letsencrypt/live/aitbc.keisanki.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/aitbc.keisanki.net/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # Security headers add_header X-Frame-Options "DENY" always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; # RPC routes location / { proxy_pass http://192.168.100.10:8082/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; proxy_buffering off; } }