Some checks failed
Backend Tests / pytest (Python 3.12) (push) Has been cancelled
Deploy to Production / backend-tests (push) Has been cancelled
Deploy to Production / frontend-build (push) Has been cancelled
Frontend Checks / Build & typecheck (push) Has been cancelled
SonarCloud / SonarCloud Analysis (push) Has been cancelled
Deploy to Production / Trigger production update (push) Has been cancelled
Security - Enforce guest ownership and server assignment across Proxmox endpoints (VM/LXC actions, firewall, backups, tasks, bulk operations, deploy, LXC/ISO creation, golden template) and WebSocket channels - Keep the panel's PVE root ticket server-side for consoles; single-use WebSocket tickets instead of the JWT in URLs; re-check access on open WebSocket bridges - Validate identifiers that reach Proxmox API paths and node shell commands; reject backup archives / foreign volumes in create requests - Close privilege escalation in user management, TOTP replay, reset-link poisoning, X-Forwarded-For spoofing, stored XSS (group icons, SVG logos) - SSH host key pinning (TOFU), encrypted 2FA seeds and notification secrets, password changes end other sessions, redact secrets in logs - Quotas count in-flight creations; 2FA failures count toward lockout Fixes - Consoles on non-default API ports, large App Store/script files, interrupted tasks after restart, impersonation lost on token refresh, HTTPExceptions swallowed into 500s, WebSocket client reconnects Performance and process - Fewer DB writes and queries on hot paths, lazy-loaded locales and heavy pages, off-loop blocking work, indexes (migrations 44-46) - Deploy waits for backend tests and frontend build; frontend checks workflow; API bound to loopback without the SSL profile
151 lines
5.3 KiB
Nginx Configuration File
151 lines
5.3 KiB
Nginx Configuration File
# WebSocket URLs carry the session JWT in ?token= (browsers cannot send
|
|
# headers on WebSocket requests): log those paths without the query string.
|
|
log_format ws_noquery '$remote_addr - $remote_user [$time_local] "$request_method $uri $server_protocol" '
|
|
'$status $body_bytes_sent "$http_referer" "$http_user_agent"';
|
|
|
|
server {
|
|
listen 80;
|
|
server_name _;
|
|
root /usr/share/nginx/html;
|
|
index index.html;
|
|
|
|
# SPA fallback
|
|
location / {
|
|
try_files $uri $uri/ /index.html;
|
|
}
|
|
|
|
# index.html references content-hashed bundles: it must be revalidated on
|
|
# every load, otherwise browsers keep a heuristically cached copy after a
|
|
# deploy and request bundles that no longer exist (blank page until a hard
|
|
# refresh).
|
|
location = /index.html {
|
|
add_header Cache-Control "no-cache";
|
|
# The SPA document is served here in every deployment mode (the outer
|
|
# nginx proxies to this one, and its http-level headers are not
|
|
# inherited by servers that set their own add_header). Without these
|
|
# the panel could be framed by any site (clickjacking).
|
|
add_header Content-Security-Policy "frame-ancestors 'self'" always;
|
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
}
|
|
|
|
# API proxy
|
|
location /api/ {
|
|
proxy_pass http://app:8000/api/;
|
|
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_read_timeout 60s;
|
|
}
|
|
|
|
# Proxmox API proxy
|
|
location /proxmox/ {
|
|
proxy_pass http://app:8000/proxmox/;
|
|
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_read_timeout 60s;
|
|
# Загрузка ISO/образов: файлы многогигабайтные, дефолтный
|
|
# client_max_body_size 1m этого server{} блока и короткие таймауты
|
|
# им не подходят.
|
|
client_max_body_size 20g;
|
|
proxy_send_timeout 300s;
|
|
client_body_timeout 3600s;
|
|
}
|
|
|
|
# Settings API proxy
|
|
location /settings/api/ {
|
|
proxy_pass http://app:8000/settings/api/;
|
|
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_read_timeout 60s;
|
|
}
|
|
|
|
# Templates API proxy
|
|
location /templates/api/ {
|
|
proxy_pass http://app:8000/templates/api/;
|
|
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_read_timeout 60s;
|
|
}
|
|
|
|
# IPAM API proxy
|
|
location /ipam/api/ {
|
|
proxy_pass http://app:8000/ipam/api/;
|
|
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_read_timeout 60s;
|
|
}
|
|
|
|
# Logs API proxy
|
|
location /logs/api/ {
|
|
proxy_pass http://app:8000/logs/api/;
|
|
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_read_timeout 60s;
|
|
}
|
|
|
|
# Admin API proxy
|
|
location /admin/api/ {
|
|
proxy_pass http://app:8000/admin/api/;
|
|
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_read_timeout 60s;
|
|
}
|
|
|
|
# Health check proxy
|
|
location /health {
|
|
proxy_pass http://app:8000/health;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
}
|
|
|
|
# WebSocket proxy
|
|
location /ws/ {
|
|
access_log /var/log/nginx/access.log ws_noquery;
|
|
proxy_pass http://app:8000/ws/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_read_timeout 86400s;
|
|
}
|
|
|
|
# Proxmox WebSocket proxy
|
|
location /proxmox/ws/ {
|
|
access_log /var/log/nginx/access.log ws_noquery;
|
|
proxy_pass http://app:8000/proxmox/ws/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_read_timeout 86400s;
|
|
}
|
|
|
|
# Cache static assets
|
|
location /assets/ {
|
|
expires 1y;
|
|
add_header Cache-Control "public, immutable";
|
|
}
|
|
|
|
# Gzip
|
|
gzip on;
|
|
gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript image/svg+xml;
|
|
gzip_min_length 1000;
|
|
}
|