1
0
mirror of git://f0xx.org/ac/ac-deploy synced 2026-07-29 05:00:35 +03:00

fix(cluster0): HTTPS redirects behind TLS-terminating FE

BE nginx used $scheme (http) in Location headers, downgrading browsers from
HTTPS to HTTP despite a valid cert on the FE. Honor X-Forwarded-Proto and
force https for public hostnames in all return/rewrite redirects.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Anton Afanasyeu
2026-07-05 19:17:12 +02:00
parent cf2e6ecb4e
commit c23ad5efdc

View File

@@ -7,13 +7,29 @@ map $http_upgrade $connection_upgrade {
'' close; '' close;
} }
# FE terminates TLS; upstream to this vhost is plain HTTP. Prefer X-Forwarded-Proto,
# else force https for known public hostnames so redirects/cookies stay secure.
map $http_x_forwarded_proto $fe_scheme {
default $scheme;
https https;
http http;
}
map $http_host $public_scheme {
default $fe_scheme;
apps.f0xx.org https;
s.f0xx.org https;
notify.f0xx.org https;
acl0.f0xx.org https;
~^c[1-3]\.acl0\.f0xx\.org$ https;
}
server { server {
listen 80 default_server; listen 80 default_server;
listen [::]:80 default_server; listen [::]:80 default_server;
# FE proxies https://apps.f0xx.org/ here as GET / — hub lives under /app/androidcast_project/ # FE proxies https://apps.f0xx.org/ here as GET / — hub lives under /app/androidcast_project/
location = / { location = / {
return 301 https://$http_host/app/androidcast_project/; return 301 $public_scheme://$http_host/app/androidcast_project/;
} }
# OTA v0 static tree — devices fetch https://apps.f0xx.org/v0/ota/channel/stable.json # OTA v0 static tree — devices fetch https://apps.f0xx.org/v0/ota/channel/stable.json
@@ -35,7 +51,7 @@ server {
} }
location = /app/androidcast_project { location = /app/androidcast_project {
return 301 /app/androidcast_project/; return 301 $public_scheme://$http_host/app/androidcast_project/;
} }
location = /app/androidcast_project/index.php { location = /app/androidcast_project/index.php {
@@ -67,12 +83,12 @@ server {
} }
location = /app/androidcast_project/graphs { location = /app/androidcast_project/graphs {
return 301 /app/androidcast_project/graphs/; return 301 $public_scheme://$http_host/app/androidcast_project/graphs/;
} }
# --- /issues/ served from composed ac/* backend --- # --- /issues/ served from composed ac/* backend ---
location = /app/androidcast_project/issues { location = /app/androidcast_project/issues {
return 301 /app/androidcast_project/issues/; return 301 $public_scheme://$http_host/app/androidcast_project/issues/;
} }
location ^~ /app/androidcast_project/issues/assets/ { location ^~ /app/androidcast_project/issues/assets/ {
@@ -99,11 +115,11 @@ server {
# Legacy /crashes/ → 301 to /issues/ (SPEC §7) # Legacy /crashes/ → 301 to /issues/ (SPEC §7)
location = /app/androidcast_project/crashes { location = /app/androidcast_project/crashes {
return 301 /app/androidcast_project/issues/; return 301 $public_scheme://$http_host/app/androidcast_project/issues/;
} }
location ^~ /app/androidcast_project/crashes/ { location ^~ /app/androidcast_project/crashes/ {
rewrite ^/app/androidcast_project/crashes/?(.*)$ /app/androidcast_project/issues/$1 permanent; rewrite ^/app/androidcast_project/crashes/?(.*)$ $public_scheme://$http_host/app/androidcast_project/issues/$1 permanent;
} }
location ^~ /app/androidcast_project/crashes/assets/ { location ^~ /app/androidcast_project/crashes/assets/ {
@@ -111,7 +127,7 @@ server {
} }
location = /app/androidcast_project/crashes/api/upload.php { location = /app/androidcast_project/crashes/api/upload.php {
return 301 /app/androidcast_project/issues/api/upload.php; return 301 $public_scheme://$http_host/app/androidcast_project/issues/api/upload.php;
} }
location ^~ /app/androidcast_project/graphs/assets/ { location ^~ /app/androidcast_project/graphs/assets/ {
@@ -145,7 +161,7 @@ server {
} }
location = /app/androidcast_project/build { location = /app/androidcast_project/build {
return 301 /app/androidcast_project/build/; return 301 $public_scheme://$http_host/app/androidcast_project/build/;
} }
location ^~ /app/androidcast_project/build/assets/ { location ^~ /app/androidcast_project/build/assets/ {
@@ -174,12 +190,12 @@ server {
} }
location @monitor_login_redirect { location @monitor_login_redirect {
return 302 /app/androidcast_project/login?redirect=$request_uri; return 302 $public_scheme://$http_host/app/androidcast_project/login?redirect=$request_uri;
} }
# ── Grafana at cast04:3000 ──────────────────────────────────────────────── # ── Grafana at cast04:3000 ────────────────────────────────────────────────
location = /app/androidcast_project/monitor { location = /app/androidcast_project/monitor {
return 301 /app/androidcast_project/monitor/; return 301 $public_scheme://$http_host/app/androidcast_project/monitor/;
} }
location /app/androidcast_project/monitor/ { location /app/androidcast_project/monitor/ {
auth_request /app/androidcast_project/api/grafana-auth-check.php; auth_request /app/androidcast_project/api/grafana-auth-check.php;
@@ -200,7 +216,7 @@ server {
# ── Alertmanager at cast04:9093 ─────────────────────────────────────────── # ── Alertmanager at cast04:9093 ───────────────────────────────────────────
location = /app/androidcast_project/alertmanager { location = /app/androidcast_project/alertmanager {
return 301 /app/androidcast_project/alertmanager/; return 301 $public_scheme://$http_host/app/androidcast_project/alertmanager/;
} }
location /app/androidcast_project/alertmanager/ { location /app/androidcast_project/alertmanager/ {
auth_request /app/androidcast_project/api/grafana-auth-check.php; auth_request /app/androidcast_project/api/grafana-auth-check.php;
@@ -218,7 +234,7 @@ server {
# ── Broadcast admin dashboard (/app/androidcast_project/broadcast/) ─────── # ── Broadcast admin dashboard (/app/androidcast_project/broadcast/) ───────
location = /app/androidcast_project/broadcast { location = /app/androidcast_project/broadcast {
return 301 /app/androidcast_project/broadcast/; return 301 $public_scheme://$http_host/app/androidcast_project/broadcast/;
} }
location /app/androidcast_project/broadcast/ { location /app/androidcast_project/broadcast/ {
auth_request /app/androidcast_project/api/grafana-auth-check.php; auth_request /app/androidcast_project/api/grafana-auth-check.php;
@@ -235,7 +251,7 @@ server {
# --- Gitea web UI (lab browse; mirrors configured separately) --- # --- Gitea web UI (lab browse; mirrors configured separately) ---
location = /app/androidcast_project/git { location = /app/androidcast_project/git {
return 301 /app/androidcast_project/git/; return 301 $public_scheme://$http_host/app/androidcast_project/git/;
} }
location ^~ /app/androidcast_project/git/ { location ^~ /app/androidcast_project/git/ {
proxy_pass http://127.0.0.1:3000/; proxy_pass http://127.0.0.1:3000/;
@@ -276,7 +292,7 @@ server {
# Catch-all SFU paths → PHP signaling front controller # Catch-all SFU paths → PHP signaling front controller
location = /app/androidcast_project/sfu { location = /app/androidcast_project/sfu {
return 301 /app/androidcast_project/sfu/; return 301 $public_scheme://$http_host/app/androidcast_project/sfu/;
} }
location ^~ /app/androidcast_project/sfu/ { location ^~ /app/androidcast_project/sfu/ {