This commit is contained in:
parent
c20a5e7486
commit
fc0385c8d5
3 changed files with 94 additions and 70 deletions
|
|
@ -98,7 +98,7 @@ void ChatWebSocketController::handleNewConnection(const HttpRequestPtr& req,
|
||||||
// Bots must send { type: "auth", apiKey: "..." } message after connecting
|
// Bots must send { type: "auth", apiKey: "..." } message after connecting
|
||||||
// This prevents API keys from being logged in server access logs
|
// This prevents API keys from being logged in server access logs
|
||||||
{
|
{
|
||||||
// Check for token in query params or headers
|
// Check for token in query params, headers, or httpOnly cookie
|
||||||
auto token = req->getParameter("token");
|
auto token = req->getParameter("token");
|
||||||
LOG_DEBUG << "Token from query param: " << (token.empty() ? "(empty)" : "present");
|
LOG_DEBUG << "Token from query param: " << (token.empty() ? "(empty)" : "present");
|
||||||
|
|
||||||
|
|
@ -110,6 +110,12 @@ void ChatWebSocketController::handleNewConnection(const HttpRequestPtr& req,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check httpOnly auth_token cookie (browser sends this with WebSocket upgrade request)
|
||||||
|
if (token.empty()) {
|
||||||
|
token = req->getCookie("auth_token");
|
||||||
|
LOG_DEBUG << "Token from auth_token cookie: " << (token.empty() ? "(empty)" : "present");
|
||||||
|
}
|
||||||
|
|
||||||
if (!token.empty()) {
|
if (!token.empty()) {
|
||||||
LOG_INFO << "Attempting to verify JWT token";
|
LOG_INFO << "Attempting to verify JWT token";
|
||||||
auto& authService = services::AuthService::getInstance();
|
auto& authService = services::AuthService::getInstance();
|
||||||
|
|
|
||||||
|
|
@ -377,8 +377,58 @@ http {
|
||||||
add_header Cache-Control "no-store, no-cache" always;
|
add_header Cache-Control "no-store, no-cache" always;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Public realm endpoints (with viewer token authentication for stream-key)
|
# Public site settings endpoint
|
||||||
location ~ ^/api/realms/(by-name/[^/]+|live|[0-9]+/stats|[0-9]+/stream-key)$ {
|
location = /api/settings/site {
|
||||||
|
# CORS headers
|
||||||
|
add_header Access-Control-Allow-Origin $cors_origin always;
|
||||||
|
add_header Access-Control-Allow-Methods "GET, OPTIONS" always;
|
||||||
|
add_header Access-Control-Allow-Headers "Content-Type" always;
|
||||||
|
add_header Access-Control-Allow-Credentials "true" always;
|
||||||
|
|
||||||
|
if ($request_method = 'OPTIONS') {
|
||||||
|
add_header Content-Length 0;
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
proxy_pass http://backend;
|
||||||
|
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;
|
||||||
|
|
||||||
|
# Cache site settings
|
||||||
|
expires 30s;
|
||||||
|
add_header Cache-Control "public, max-age=30" always;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Public honk sound endpoint
|
||||||
|
location = /api/honk/active {
|
||||||
|
# CORS headers
|
||||||
|
add_header Access-Control-Allow-Origin $cors_origin always;
|
||||||
|
add_header Access-Control-Allow-Methods "GET, OPTIONS" always;
|
||||||
|
add_header Access-Control-Allow-Headers "Content-Type" always;
|
||||||
|
add_header Access-Control-Allow-Credentials "true" always;
|
||||||
|
|
||||||
|
if ($request_method = 'OPTIONS') {
|
||||||
|
add_header Content-Length 0;
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
proxy_pass http://backend;
|
||||||
|
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;
|
||||||
|
|
||||||
|
# Short cache
|
||||||
|
expires 10s;
|
||||||
|
add_header Cache-Control "public, max-age=10" always;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Public realm endpoints - includes single realm by ID (with viewer token authentication for stream-key)
|
||||||
|
location ~ ^/api/realms/(by-name/[^/]+|live|[0-9]+|[0-9]+/stats|[0-9]+/stream-key)$ {
|
||||||
# CORS headers
|
# CORS headers
|
||||||
add_header Access-Control-Allow-Origin $cors_origin always;
|
add_header Access-Control-Allow-Origin $cors_origin always;
|
||||||
add_header Access-Control-Allow-Methods "GET, OPTIONS" always;
|
add_header Access-Control-Allow-Methods "GET, OPTIONS" always;
|
||||||
|
|
@ -471,6 +521,7 @@ http {
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
|
||||||
# WebSocket timeouts
|
# WebSocket timeouts
|
||||||
proxy_read_timeout 3600s;
|
proxy_read_timeout 3600s;
|
||||||
|
|
@ -493,6 +544,7 @@ http {
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
|
||||||
# WebSocket timeouts
|
# WebSocket timeouts
|
||||||
proxy_read_timeout 3600s;
|
proxy_read_timeout 3600s;
|
||||||
|
|
@ -516,6 +568,7 @@ http {
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
|
||||||
# WebSocket timeouts
|
# WebSocket timeouts
|
||||||
proxy_read_timeout 3600s;
|
proxy_read_timeout 3600s;
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,6 @@ write_files:
|
||||||
# Message of the day
|
# Message of the day
|
||||||
- path: /etc/motd
|
- path: /etc/motd
|
||||||
content: |
|
content: |
|
||||||
|
|
||||||
+---------------------------------------------------------------+
|
+---------------------------------------------------------------+
|
||||||
| REALMS APP SERVER |
|
| REALMS APP SERVER |
|
||||||
| |
|
| |
|
||||||
|
|
@ -176,12 +175,40 @@ write_files:
|
||||||
| |
|
| |
|
||||||
| Commands: |
|
| Commands: |
|
||||||
| cd /opt/realms && docker compose logs -f |
|
| cd /opt/realms && docker compose logs -f |
|
||||||
| cd /opt/realms && docker compose pull && up -d |
|
| cd /opt/realms && docker compose pull && docker compose up -d
|
||||||
| |
|
| |
|
||||||
+---------------------------------------------------------------+
|
+---------------------------------------------------------------+
|
||||||
|
|
||||||
permissions: '0644'
|
permissions: '0644'
|
||||||
|
|
||||||
|
# Environment file generator script (separate file to avoid YAML parsing issues)
|
||||||
|
- path: /usr/local/bin/generate-env.sh
|
||||||
|
content: |
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
ENV_FILE="/opt/realms/.env"
|
||||||
|
if [ -f "$ENV_FILE" ]; then
|
||||||
|
echo ".env already exists, skipping generation"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
echo "Generating .env with secure random secrets..."
|
||||||
|
DB_PASS=$(openssl rand -base64 32 | tr -d '/+=' | head -c 32)
|
||||||
|
JWT_SEC=$(openssl rand -base64 48 | tr -d '/+=' | head -c 48)
|
||||||
|
REDIS_PASS=$(openssl rand -base64 32 | tr -d '/+=' | head -c 32)
|
||||||
|
OME_TOKEN=$(openssl rand -hex 32)
|
||||||
|
NAKAMA_KEY=$(openssl rand -hex 16)
|
||||||
|
NAKAMA_PASS=$(openssl rand -base64 16 | tr -d '/+=' | head -c 16)
|
||||||
|
{
|
||||||
|
echo "DB_PASSWORD=$DB_PASS"
|
||||||
|
echo "JWT_SECRET=$JWT_SEC"
|
||||||
|
echo "REDIS_PASSWORD=$REDIS_PASS"
|
||||||
|
echo "OME_API_TOKEN=$OME_TOKEN"
|
||||||
|
echo "NAKAMA_SERVER_KEY=$NAKAMA_KEY"
|
||||||
|
echo "NAKAMA_CONSOLE_PASSWORD=$NAKAMA_PASS"
|
||||||
|
} > "$ENV_FILE"
|
||||||
|
chmod 600 "$ENV_FILE"
|
||||||
|
echo ".env generated with secure random secrets"
|
||||||
|
permissions: '0755'
|
||||||
|
|
||||||
runcmd:
|
runcmd:
|
||||||
# Ensure .ssh directory exists
|
# Ensure .ssh directory exists
|
||||||
- mkdir -p /root/.ssh && chmod 700 /root/.ssh
|
- mkdir -p /root/.ssh && chmod 700 /root/.ssh
|
||||||
|
|
@ -226,70 +253,8 @@ runcmd:
|
||||||
- mkdir -p /opt/realms
|
- mkdir -p /opt/realms
|
||||||
- mkdir -p /opt/realms/uploads
|
- mkdir -p /opt/realms/uploads
|
||||||
|
|
||||||
# Generate .env with secure random secrets (only if it doesn't exist)
|
# Generate .env with secure random secrets (script defined in write_files)
|
||||||
- |
|
- /usr/local/bin/generate-env.sh
|
||||||
ENV_FILE="/opt/realms/.env"
|
|
||||||
if [ ! -f "$ENV_FILE" ]; then
|
|
||||||
echo "Generating .env with secure random secrets..."
|
|
||||||
cat > "$ENV_FILE" << 'ENVEOF'
|
|
||||||
# =============================================================================
|
|
||||||
# Realms Production Environment - Auto-generated on first deploy
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# Database
|
|
||||||
DB_PASSWORD=$(openssl rand -base64 32 | tr -d '/+=' | head -c 32)
|
|
||||||
|
|
||||||
# JWT Secret for authentication
|
|
||||||
JWT_SECRET=$(openssl rand -base64 48 | tr -d '/+=' | head -c 48)
|
|
||||||
|
|
||||||
# Redis
|
|
||||||
REDIS_PASSWORD=$(openssl rand -base64 32 | tr -d '/+=' | head -c 32)
|
|
||||||
|
|
||||||
# OvenMediaEngine API Token
|
|
||||||
OME_API_TOKEN=$(openssl rand -hex 32)
|
|
||||||
|
|
||||||
# Nakama Game Server
|
|
||||||
NAKAMA_SERVER_KEY=$(openssl rand -hex 16)
|
|
||||||
NAKAMA_CONSOLE_PASSWORD=$(openssl rand -base64 16 | tr -d '/+=' | head -c 16)
|
|
||||||
ENVEOF
|
|
||||||
|
|
||||||
# Generate actual random values by evaluating the file
|
|
||||||
# Read template and generate real values
|
|
||||||
DB_PASS=$(openssl rand -base64 32 | tr -d '/+=' | head -c 32)
|
|
||||||
JWT_SEC=$(openssl rand -base64 48 | tr -d '/+=' | head -c 48)
|
|
||||||
REDIS_PASS=$(openssl rand -base64 32 | tr -d '/+=' | head -c 32)
|
|
||||||
OME_TOKEN=$(openssl rand -hex 32)
|
|
||||||
NAKAMA_KEY=$(openssl rand -hex 16)
|
|
||||||
NAKAMA_PASS=$(openssl rand -base64 16 | tr -d '/+=' | head -c 16)
|
|
||||||
|
|
||||||
cat > "$ENV_FILE" << ENVEOF
|
|
||||||
# =============================================================================
|
|
||||||
# Realms Production Environment - Auto-generated on first deploy
|
|
||||||
# Generated: $(date -Iseconds)
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# Database
|
|
||||||
DB_PASSWORD=$DB_PASS
|
|
||||||
|
|
||||||
# JWT Secret for authentication
|
|
||||||
JWT_SECRET=$JWT_SEC
|
|
||||||
|
|
||||||
# Redis
|
|
||||||
REDIS_PASSWORD=$REDIS_PASS
|
|
||||||
|
|
||||||
# OvenMediaEngine API Token
|
|
||||||
OME_API_TOKEN=$OME_TOKEN
|
|
||||||
|
|
||||||
# Nakama Game Server
|
|
||||||
NAKAMA_SERVER_KEY=$NAKAMA_KEY
|
|
||||||
NAKAMA_CONSOLE_PASSWORD=$NAKAMA_PASS
|
|
||||||
ENVEOF
|
|
||||||
|
|
||||||
chmod 600 "$ENV_FILE"
|
|
||||||
echo ".env generated with secure random secrets"
|
|
||||||
else
|
|
||||||
echo ".env already exists, skipping generation"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Enable unattended upgrades
|
# Enable unattended upgrades
|
||||||
- systemctl enable unattended-upgrades
|
- systemctl enable unattended-upgrades
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue