openvibers/openvibe.games Commits

nginx: the repo vhost is production's again (www redirect, security.txt, /tos) plus /internal/ and /metrics closed at the edge and HSTS, nosniff and a referrer policy (#98)

OP OpenVibers committed 27 days ago · 96885a9043 · 1 file, +32 −11

Changes

ddiff --git a/deploy/nginx-openvibe-games.conf b/deploy/nginx-openvibe-games.conf
iindex f59faa4..9fea53f 100644
---- a/deploy/nginx-openvibe-games.conf
++++ b/deploy/nginx-openvibe-games.conf
@@@ -14,27 +14,36 @@ map $http_upgrade $connection_upgrade {
server {
listen 80;
listen [::]:80;
-- server_name openvibe.games play.openvibe.games;
++ server_name openvibe.games www.openvibe.games play.openvibe.games;
++ return 301 https://$host$request_uri;
++}
-- location /.well-known/acme-challenge/ { root /var/www/certbot; }
-- location / { return 301 https://$host$request_uri; }
++# www → apex (the wildcard certificate covers www).
++server {
++ listen 443 ssl http2;
++ listen [::]:443 ssl http2;
++ server_name www.openvibe.games;
++ ssl_certificate /etc/letsencrypt/live/openvibe.games/fullchain.pem;
++ ssl_certificate_key /etc/letsencrypt/live/openvibe.games/privkey.pem;
++ return 301 https://openvibe.games$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name openvibe.games;
++ include snippets/security-txt.conf;
ssl_certificate /etc/letsencrypt/live/openvibe.games/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/openvibe.games/privkey.pem;
client_max_body_size 64m; # map saves + editor asset uploads (48 MB cap in-app)
-- # Readiness is for callers on the host (curl 127.0.0.1:8000/api/ready),
-- # not the internet: everything else under /api/ is proxied as-is below.
-- location = /api/ready {
-- return 404;
-- }
++ # Terms, Privacy and DMCA: static pages built by OpenVibe.Sites (openvibe-shared/legal).
++ location = /tos { return 301 /terms; }
++
++ # Readiness is for callers on the host (curl 127.0.0.1:8000/api/ready), not the internet.
++ location = /api/ready { return 404; }
# ── The Events webhook: OpenVibe.Events delivers over loopback, never through the public vhosts ──
location /internal/ { return 404; }
@@@ -42,6 +51,12 @@ server {
# ── Prometheus metrics: host-local scrapers only (http://127.0.0.1:8000/metrics) ──
location = /metrics { return 404; }
++ # The game server sends no security headers of its own (2026-10-17: none at all on openvibe.games). No CSP or
++ # frame rule here: games and worlds are embedded elsewhere and load from several origins.
++ add_header Strict-Transport-Security "max-age=31536000" always;
++ add_header X-Content-Type-Options "nosniff" always;
++ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
++
location / {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
@@@ -63,15 +78,15 @@ server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name play.openvibe.games;
++ include snippets/security-txt.conf;
ssl_certificate /etc/letsencrypt/live/openvibe.games/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/openvibe.games/privkey.pem;
client_max_body_size 64m;
-- location = /api/ready {
-- return 404;
-- }
++ # Readiness is for callers on the host (curl 127.0.0.1:8000/api/ready), not the internet.
++ location = /api/ready { return 404; }
# ── The Events webhook: OpenVibe.Events delivers over loopback, never through the public vhosts ──
location /internal/ { return 404; }
@@@ -79,6 +94,12 @@ server {
# ── Prometheus metrics: host-local scrapers only (http://127.0.0.1:8000/metrics) ──
location = /metrics { return 404; }
++ # The game server sends no security headers of its own (2026-10-17: none at all on openvibe.games). No CSP or
++ # frame rule here: games and worlds are embedded elsewhere and load from several origins.
++ add_header Strict-Transport-Security "max-age=31536000" always;
++ add_header X-Content-Type-Options "nosniff" always;
++ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
++
location / {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;