- 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.
7.0 KiB
JWT Authentication for Permissioned RPC Endpoints
Last Updated: 2025-12-24
Status: Active Configuration
Overview
JWT (JSON Web Token) authentication has been configured for the Permissioned RPC endpoints to provide secure, token-based access control.
Endpoints with JWT Authentication
- HTTP RPC:
https://rpc-http-prv.d-bis.org - WebSocket RPC:
wss://rpc-ws-prv.d-bis.org
Endpoints without Authentication (Public)
- HTTP RPC:
https://rpc-http-pub.d-bis.org - WebSocket RPC:
wss://rpc-ws-pub.d-bis.org
Architecture
VMID Mappings
| VMID | Type | Domain | Authentication | IP |
|---|---|---|---|---|
| 2501 | Permissioned RPC | rpc-http-prv.d-bis.orgrpc-ws-prv.d-bis.org |
✅ JWT Required | 192.168.11.251 |
| 2502 | Public RPC | rpc-http-pub.d-bis.orgrpc-ws-pub.d-bis.org |
❌ No Auth | 192.168.11.252 |
Request Flow with JWT
- Client makes request to
https://rpc-http-prv.d-bis.org - Nginx receives request and extracts JWT token from
Authorization: Bearer <token>header - Lua Script validates JWT token using secret key
- If valid: Request is proxied to Besu RPC (127.0.0.1:8545)
- If invalid: Returns 401 Unauthorized with error message
Setup
1. Configure JWT Authentication
Run the configuration script:
cd /home/intlc/projects/proxmox
./scripts/configure-nginx-jwt-auth.sh
This script will:
- Install required packages (nginx, lua, lua-resty-jwt)
- Generate JWT secret key
- Configure Nginx with JWT validation
- Set up both HTTP and WebSocket endpoints
2. Generate JWT Tokens
Use the token generation script:
# Generate token with default settings (username: rpc-user, expiry: 365 days)
./scripts/generate-jwt-token.sh
# Generate token with custom username and expiry
./scripts/generate-jwt-token.sh my-username 30 # 30 days expiry
The script will output:
- The JWT token
- Usage examples for testing
Usage
HTTP RPC with JWT
# Test with curl
curl -k \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' \
https://rpc-http-prv.d-bis.org
WebSocket RPC with JWT
For WebSocket connections, include the JWT token in the Authorization header during the initial HTTP upgrade request:
// JavaScript example
const ws = new WebSocket('wss://rpc-ws-prv.d-bis.org', {
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN'
}
});
Using with MetaMask or dApps
Most Ethereum clients don't support custom headers. For these cases, you can:
- Use a proxy service that adds the JWT token
- Use the public endpoint (
rpc-http-pub.d-bis.org) for read-only operations - Implement custom authentication in your dApp
Token Management
Token Structure
JWT tokens contain:
- Header: Algorithm (HS256) and type (JWT)
- Payload:
sub: Username/subjectiat: Issued at (timestamp)exp: Expiration (timestamp)
- Signature: HMAC-SHA256 signature using the secret key
Token Expiry
Tokens expire after the specified number of days. To generate a new token:
./scripts/generate-jwt-token.sh username days
Revoking Tokens
JWT tokens cannot be revoked individually without changing the secret key. To revoke all tokens:
-
Generate a new JWT secret on VMID 2501:
ssh root@192.168.11.10 "pct exec 2501 -- openssl rand -base64 32 > /etc/nginx/jwt_secret" -
Restart Nginx:
ssh root@192.168.11.10 "pct exec 2501 -- systemctl restart nginx" -
Generate new tokens for authorized users
Security Considerations
Secret Key Management
- Location:
/etc/nginx/jwt_secreton VMID 2501 - Permissions: 600 (readable only by root)
- Backup: Store securely, do not commit to version control
Best Practices
- Use strong secret keys: The script generates 32-byte random keys
- Set appropriate expiry: Don't create tokens with excessive expiry times
- Rotate secrets periodically: Change the secret key and regenerate tokens
- Monitor access logs: Check
/var/log/nginx/rpc-http-prv-access.logfor unauthorized attempts - Use HTTPS only: All endpoints use HTTPS (port 443)
Rate Limiting
Consider adding rate limiting to prevent abuse:
limit_req_zone $binary_remote_addr zone=jwt_limit:10m rate=10r/s;
location / {
limit_req zone=jwt_limit burst=20 nodelay;
# ... JWT validation ...
}
Troubleshooting
401 Unauthorized
Error: {"error": "Missing Authorization header"}
Solution: Include the Authorization header:
curl -H "Authorization: Bearer YOUR_TOKEN" ...
Error: {"error": "Invalid or expired token"}
Solution:
- Check token is correct (no extra spaces)
- Verify token hasn't expired
- Generate a new token if needed
500 Internal Server Error
Error: {"error": "Internal server error"}
Solution:
- Check JWT secret exists:
pct exec 2501 -- cat /etc/nginx/jwt_secret - Check lua-resty-jwt is installed:
pct exec 2501 -- ls /usr/share/lua/5.1/resty/jwt.lua - Check Nginx error logs:
pct exec 2501 -- tail -f /var/log/nginx/rpc-http-prv-error.log
Token Validation Fails
-
Verify secret key matches:
# On VMID 2501 cat /etc/nginx/jwt_secret -
Regenerate token using the same secret:
./scripts/generate-jwt-token.sh -
Check token format: Should be three parts separated by dots:
header.payload.signature
Testing
Test JWT Authentication
# 1. Generate a token
TOKEN=$(./scripts/generate-jwt-token.sh test-user 365 | grep -A 1 "Token:" | tail -1)
# 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
# 3. Test without token (should fail)
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: {"error": "Missing Authorization header"}
Test Health Endpoint (No Auth Required)
curl -k https://rpc-http-prv.d-bis.org/health
# Expected: healthy
Related Documentation
- RPC_DNS_CONFIGURATION.md - DNS setup
- BESU_RPC_CONFIGURATION_FIXED.md - Besu RPC configuration
- NGINX_ARCHITECTURE_RPC.md - Nginx architecture
Quick Reference
Generate Token:
./scripts/generate-jwt-token.sh [username] [days]
Use Token:
curl -H "Authorization: Bearer <token>" https://rpc-http-prv.d-bis.org
Check Secret:
ssh root@192.168.11.10 "pct exec 2501 -- cat /etc/nginx/jwt_secret"
View Logs:
ssh root@192.168.11.10 "pct exec 2501 -- tail -f /var/log/nginx/rpc-http-prv-access.log"
Last Updated: 2025-12-24