feat(proxy): https://<LAN IP>:8443 for the native app (backend-managed cert, LAN only)

- new :8443 server (both copies byte-identical): TLS with the backend's
  data/tls key+cert, LAN-only allow list, proxies the whole waiter
  origin incl. /api/ws/ upgrades
- compose: backend healthcheck; proxy waits for backend healthy (TLS files
  exist) and mounts ${DATA_PATH}/tls read-only; publishes 8443;
  TLS_PORT passed to the backend so it advertises the published port

Verified on an isolated stack: served key == advertised pin, identity and
WebSocket over TLS, proxy starts only after the backend is healthy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-28 17:41:25 +03:00
co-authored by Claude Opus 5.5
parent 8924a16747
commit 2b9f841bbd
3 changed files with 95 additions and 2 deletions
+39
View File
@@ -8,6 +8,7 @@
# :8081 → manager dashboard over plain HTTP, LAN only
# :443 waiter.* / manager.* / bare IP → https (needs certs/cert.pem + key.pem)
# :4443 → manager over https
# :8443 → native app over TLS (backend-managed key, pinned), LAN only
#
# Every proxied location forwards WebSocket upgrades (/api/ws/connect) and
# disables buffering (SSE), otherwise live events never reach phones / KDS.
@@ -179,6 +180,44 @@ server {
}
}
server {
listen 8443 ssl default_server;
server_name _;
# Encrypted LAN entry for the native app (plan step 7). Key + self-signed cert
# are created and renewed by the backend (services/tls_identity.py) under
# ${DATA_PATH}/tls; phones pin the public key, so renewals need no action.
ssl_certificate /etc/nginx/xenia-tls/cert.pem;
ssl_certificate_key /etc/nginx/xenia-tls/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# LAN only: plain HTTP must never be reachable from the internet, even if the
# client forwards ports on their router. Relies on Docker preserving the real
# client IP (default iptables port publishing on Linux).
allow 10.0.0.0/8;
allow 172.16.0.0/12;
allow 192.168.0.0/16;
allow 127.0.0.0/8;
allow fc00::/7;
allow fe80::/10;
allow ::1;
deny all;
location / {
proxy_pass http://waiter_pwa:80;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
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 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
}
}
server {
listen 4443 ssl default_server;
server_name _;