# JWT Authentication Setup - Complete **Last Updated:** 2026-01-31 **Document Version:** 1.0 **Status:** Active Documentation --- **Date**: 2025-12-26 **Status**: ✅ **FULLY OPERATIONAL** --- ## ✅ Setup Complete JWT authentication has been successfully configured for the Permissioned RPC endpoints on VMID 2501. ### Endpoints Configured | Endpoint | VMID | IP | Authentication | Status | |----------|------|-----|----------------|--------| | `https://rpc-http-prv.d-bis.org` | 2501 | 192.168.11.251 | ✅ JWT Required | ✅ Active | | `wss://rpc-ws-prv.d-bis.org` | 2501 | 192.168.11.251 | ✅ JWT Required | ✅ Active | | `https://rpc-http-pub.d-bis.org` | 2502 | 192.168.11.252 | ❌ No Auth | ✅ Active | | `wss://rpc-ws-pub.d-bis.org` | 2502 | 192.168.11.252 | ❌ No Auth | ✅ Active | --- ## 🔑 JWT Secret **Location**: `/etc/nginx/jwt_secret` on VMID 2501 **Secret**: `UMW58gEniB9Y75yNmw0X9hI+ycg1K+d1TG8VdB6TqX0=` ⚠️ **IMPORTANT**: Keep this secret secure. All JWT tokens are signed with this secret. --- ## 🚀 Quick Start ### 1. Generate a JWT Token ```bash cd /home/intlc/projects/proxmox ./scripts/generate-jwt-token.sh [username] [expiry_days] ``` **Example:** ```bash ./scripts/generate-jwt-token.sh my-app 30 ``` ### 2. Use the Token **HTTP RPC:** ```bash curl -k \ -H "Authorization: Bearer YOUR_TOKEN_HERE" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' \ https://rpc-http-prv.d-bis.org ``` **WebSocket RPC:** ```javascript const ws = new WebSocket('wss://rpc-ws-prv.d-bis.org', { headers: { 'Authorization': 'Bearer YOUR_TOKEN_HERE' } }); ``` ### 3. Test Without Token (Should Fail) ```bash curl -k \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' \ https://rpc-http-prv.d-bis.org ``` **Expected Response:** ```json {"jsonrpc":"2.0","error":{"code":-32000,"message":"Unauthorized. Missing or invalid JWT token. Use: Authorization: Bearer "},"id":null} ``` --- ## 📋 Services Status ### VMID 2501 Services - ✅ **Nginx**: Active and running - ✅ **JWT Validator Service**: Active on port 8888 - ✅ **Besu RPC**: Running on ports 8545 (HTTP) and 8546 (WebSocket) ### Check Status ```bash ssh root@192.168.11.10 "pct exec 2501 -- systemctl status nginx jwt-validator" ``` --- ## 🔧 Configuration Files ### Nginx Configuration - **Location**: `/etc/nginx/sites-available/rpc-perm` - **Enabled**: `/etc/nginx/sites-enabled/rpc-perm` ### JWT Validator Service - **Script**: `/usr/local/bin/jwt-validator-http.py` - **Service**: `/etc/systemd/system/jwt-validator.service` - **Port**: 8888 (internal only, 127.0.0.1) ### JWT Secret - **Location**: `/etc/nginx/jwt_secret` - **Permissions**: 640 (readable by root and www-data group) --- ## 🧪 Testing ### Test Health Endpoint (No Auth Required) ```bash curl -k https://rpc-http-prv.d-bis.org/health # Expected: healthy ``` ### Test with Valid Token ```bash # Generate token TOKEN=$(./scripts/generate-jwt-token.sh test-user 365 | grep "Token:" | tail -1 | awk '{print $2}') # Test HTTP endpoint curl -k \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' \ https://rpc-http-prv.d-bis.org # Expected: {"jsonrpc":"2.0","id":1,"result":"0x8a"} ``` ### Test with Invalid Token ```bash curl -k \ -H "Authorization: Bearer invalid-token" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' \ https://rpc-http-prv.d-bis.org # Expected: 401 Unauthorized ``` --- ## 🔄 Token Management ### Generate New Token ```bash ./scripts/generate-jwt-token.sh [username] [expiry_days] ``` ### Token Structure JWT tokens contain: - **Header**: Algorithm (HS256) and type (JWT) - **Payload**: - `sub`: Username/subject - `iat`: Issued at timestamp - `exp`: Expiration timestamp - **Signature**: HMAC-SHA256 signature ### Token Expiry Tokens expire after the specified number of days. To generate a new token: ```bash ./scripts/generate-jwt-token.sh username days ``` ### Revoke All Tokens To revoke all existing tokens, generate a new JWT secret: ```bash ssh root@192.168.11.10 "pct exec 2501 -- openssl rand -base64 32 > /etc/nginx/jwt_secret" ssh root@192.168.11.10 "pct exec 2501 -- chmod 640 /etc/nginx/jwt_secret && chgrp www-data /etc/nginx/jwt_secret" ssh root@192.168.11.10 "pct exec 2501 -- systemctl restart jwt-validator" ``` Then generate new tokens for authorized users. --- ## 🌐 DNS Configuration ### Required DNS Records Ensure these DNS records are configured in Cloudflare: | Type | Name | Target | Proxy | Notes | |------|------|--------|-------|-------| | A | `rpc-http-prv` | `192.168.11.251` | 🟠 Proxied | Permissioned HTTP RPC | | A | `rpc-ws-prv` | `192.168.11.251` | 🟠 Proxied | Permissioned WebSocket RPC | | A | `rpc-http-pub` | `192.168.11.252` | 🟠 Proxied | Public HTTP RPC | | A | `rpc-ws-pub` | `192.168.11.252` | 🟠 Proxied | Public WebSocket RPC | ### Verify DNS ```bash # Check DNS resolution dig rpc-http-prv.d-bis.org nslookup rpc-http-prv.d-bis.org ``` --- ## 🔍 Troubleshooting ### 401 Unauthorized **Issue**: Token is missing or invalid **Solutions**: 1. Check Authorization header format: `Authorization: Bearer ` 2. Verify token hasn't expired 3. Generate a new token 4. Ensure token matches the current JWT secret ### 500 Internal Server Error **Issue**: JWT validation service not responding **Solutions**: ```bash # Check service status ssh root@192.168.11.10 "pct exec 2501 -- systemctl status jwt-validator" # Check logs ssh root@192.168.11.10 "pct exec 2501 -- journalctl -u jwt-validator -n 20" # Restart service ssh root@192.168.11.10 "pct exec 2501 -- systemctl restart jwt-validator" ``` ### Connection Refused **Issue**: Service not listening on port 8888 **Solutions**: ```bash # Check if service is running ssh root@192.168.11.10 "pct exec 2501 -- ss -tlnp | grep 8888" # Check JWT secret permissions ssh root@192.168.11.10 "pct exec 2501 -- ls -la /etc/nginx/jwt_secret" # Fix permissions if needed ssh root@192.168.11.10 "pct exec 2501 -- chmod 640 /etc/nginx/jwt_secret && chgrp www-data /etc/nginx/jwt_secret" ``` ### Nginx Configuration Errors **Issue**: Nginx fails to start or reload **Solutions**: ```bash # Test configuration ssh root@192.168.11.10 "pct exec 2501 -- nginx -t" # Check error logs ssh root@192.168.11.10 "pct exec 2501 -- tail -20 /var/log/nginx/rpc-http-prv-error.log" # Reload nginx ssh root@192.168.11.10 "pct exec 2501 -- systemctl reload nginx" ``` --- ## 📊 Monitoring ### View Access Logs ```bash # HTTP access logs ssh root@192.168.11.10 "pct exec 2501 -- tail -f /var/log/nginx/rpc-http-prv-access.log" # WebSocket access logs ssh root@192.168.11.10 "pct exec 2501 -- tail -f /var/log/nginx/rpc-ws-prv-access.log" # Error logs ssh root@192.168.11.10 "pct exec 2501 -- tail -f /var/log/nginx/rpc-http-prv-error.log" ``` ### Monitor JWT Validator Service ```bash ssh root@192.168.11.10 "pct exec 2501 -- journalctl -u jwt-validator -f" ``` --- ## 🔐 Security Best Practices 1. **Keep JWT Secret Secure** - Store in secure location - Don't commit to version control - Rotate periodically 2. **Set Appropriate Token Expiry** - Use short expiry for high-security applications - Use longer expiry for trusted services - Regenerate tokens when compromised 3. **Monitor Access** - Review access logs regularly - Watch for unauthorized access attempts - Set up alerts for suspicious activity 4. **Use HTTPS Only** - All endpoints use HTTPS (port 443) - Never send tokens over unencrypted connections 5. **Rate Limiting** (Future Enhancement) - Consider adding rate limiting to prevent abuse - Configure per-user or per-IP limits --- ## 📚 Related Documentation - [RPC_JWT_AUTHENTICATION.md](RPC_JWT_AUTHENTICATION.md) - Detailed JWT authentication guide - [RPC_DNS_CONFIGURATION.md](RPC_DNS_CONFIGURATION.md) - DNS setup and configuration - [BESU_RPC_CONFIGURATION_FIXED.md](../05-network/BESU_RPC_CONFIGURATION_FIXED.md) - Besu RPC node configuration --- ## ✅ Verification Checklist - [x] JWT authentication configured on VMID 2501 - [x] JWT validator service running on port 8888 - [x] Nginx configured with auth_request - [x] JWT secret generated and secured - [x] Token generation script working - [x] Valid tokens allow access - [x] Invalid tokens are rejected - [x] Health endpoint accessible without auth - [x] Documentation complete --- **Last Updated**: 2025-12-26 **Status**: ✅ **PRODUCTION READY**