feat: publish the Hub through a reverse proxy on another host

GTI terminates TLS in its Nginx Proxy Manager (10.0.10.100), not on the
Hub host, so the Hub must be reachable on the LAN — by the proxy only.

- docker-compose.prod.yml passes FORWARDED_ALLOW_IPS (uvicorn then trusts
  X-Forwarded-For/-Proto from the proxy only: real client IPs in audit and
  session records, https scheme) and WEB_COOKIE_SECURE. Defaults keep the
  previous behaviour.
- restrict_hub_port.sh + gti-fiscal-hub-port.service: Docker-published
  ports bypass UFW, so the source restriction lives in DOCKER-USER,
  matched on the conntrack original destination with --ctdir ORIGINAL,
  and is re-applied whenever docker.service starts (the chain is not
  persisted across reboots).
- *.service forced to LF like *.sh; tests cover both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
gti
2026-09-23 07:46:11 -03:00
co-authored by Claude Opus 5.5
parent d33149f5ee
commit 91a2dda969
7 changed files with 78 additions and 1 deletions
+11
View File
@@ -144,6 +144,17 @@ forwards to `fiscal-hub:8000`. Nothing in the app assumes a particular
proxy; `BASE_URL` in `.env` is informational only (not currently used to
generate absolute links, but keep it accurate for anyone reading the config).
**GTI production (2026-09-23):** TLS terminates in the GTI Nginx Proxy Manager
(10.0.10.100), which forwards `http://<hub-lan-ip>:8000`. On the Hub host:
- `.env`: `HUB_BIND=<hub LAN IP>` (not `0.0.0.0`), `FORWARDED_ALLOW_IPS=<NPM IP>`
(real client IP and `https` scheme from `X-Forwarded-*`), `BASE_URL=https://…`,
and `WEB_COOKIE_SECURE=1` once HTTPS works. Redirects are relative, so the
internal address never leaks.
- Docker-published ports bypass UFW: install `restrict_hub_port.sh` +
`gti-fiscal-hub-port.service` (instructions in the unit file) so only the
NPM reaches the port, re-applied on every Docker start.
## Registering an Agent (per client installation)
Run once per Agent installation, from anywhere with access to Postgres —