Files
proxmox/scripts/fix-jwt-validation.sh
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

151 lines
4.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# Fix JWT validation by using a simple HTTP service instead of FastCGI
set -euo pipefail
PROXMOX_HOST="${PROXMOX_HOST:-192.168.11.10}"
VMID=2501
# Create a simple HTTP validation service
ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} \
"pct exec $VMID -- bash" <<'FIX_EOF'
# Create systemd service for JWT validation
cat > /etc/systemd/system/jwt-validator.service <<'SERVICE_EOF'
[Unit]
Description=JWT Validation Service
After=network.target
[Service]
Type=simple
User=www-data
ExecStart=/usr/bin/python3 /usr/local/bin/jwt-validator-http.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
SERVICE_EOF
# Create HTTP-based JWT validator
cat > /usr/local/bin/jwt-validator-http.py <<'PYTHON_EOF'
#!/usr/bin/env python3
import http.server
import socketserver
import sys
import os
import hmac
import hashlib
import base64
import json
import time
import urllib.parse
def base64url_decode(data):
padding = 4 - len(data) % 4
if padding != 4:
data += '=' * padding
return base64.urlsafe_b64decode(data)
def verify_jwt(token, secret):
try:
parts = token.split('.')
if len(parts) != 3:
return False, "Invalid token format"
header_data = base64url_decode(parts[0])
payload_data = base64url_decode(parts[1])
signature = parts[2]
message = f"{parts[0]}.{parts[1]}"
expected_sig = hmac.new(
secret.encode('utf-8'),
message.encode('utf-8'),
hashlib.sha256
).digest()
expected_sig_b64 = base64.urlsafe_b64encode(expected_sig).decode('utf-8').rstrip('=')
if signature != expected_sig_b64:
return False, "Invalid signature"
payload = json.loads(payload_data)
if 'exp' in payload:
if time.time() > payload['exp']:
return False, "Token expired"
return True, payload
except Exception as e:
return False, str(e)
class JWTValidatorHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
auth_header = self.headers.get('Authorization', '')
if not auth_header.startswith('Bearer '):
self.send_response(401)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(b'{"error": "Missing or invalid Authorization header"}')
return
token = auth_header[7:]
# Read secret
try:
with open('/etc/nginx/jwt_secret', 'r') as f:
secret = f.read().strip()
except Exception as e:
self.send_response(500)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(f'{{"error": "Server error: {str(e)}"}}'.encode())
return
valid, result = verify_jwt(token, secret)
if valid:
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(b'{"valid": true}')
else:
self.send_response(401)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(f'{{"error": "Invalid token", "reason": "{result}"}}'.encode())
def log_message(self, format, *args):
# Suppress default logging
pass
if __name__ == '__main__':
PORT = 8888
with socketserver.TCPServer(("127.0.0.1", PORT), JWTValidatorHandler) as httpd:
httpd.serve_forever()
PYTHON_EOF
chmod +x /usr/local/bin/jwt-validator-http.py
# Update nginx config to use HTTP instead of FastCGI
sed -i 's|proxy_pass http://127.0.0.1:8888/validate;|proxy_pass http://127.0.0.1:8888/;|' /etc/nginx/sites-available/rpc-perm
sed -i 's|fastcgi_pass unix:/var/run/fcgiwrap.socket;|# Removed FastCGI|' /etc/nginx/sites-available/rpc-perm
sed -i 's|include fastcgi_params;|# Removed FastCGI|' /etc/nginx/sites-available/rpc-perm
sed -i 's|fastcgi_param SCRIPT_FILENAME /usr/local/bin/jwt-validate.py;|# Removed FastCGI|' /etc/nginx/sites-available/rpc-perm
sed -i 's|fastcgi_param HTTP_AUTHORIZATION \$http_authorization;|# Removed FastCGI|' /etc/nginx/sites-available/rpc-perm
# Remove the internal FastCGI server block
sed -i '/# Internal server for JWT validation/,/^}$/d' /etc/nginx/sites-available/rpc-perm
# Enable and start the service
systemctl daemon-reload
systemctl enable jwt-validator.service
systemctl restart jwt-validator.service
# Test nginx config
nginx -t
# Reload nginx
systemctl restart nginx
FIX_EOF
echo "JWT validation service updated!"