diff --git a/docs/server-client-mode-remote.md b/docs/server-client-mode-remote.md index 58e7a5b..f40bf6c 100644 --- a/docs/server-client-mode-remote.md +++ b/docs/server-client-mode-remote.md @@ -59,8 +59,27 @@ idea --serve \ --trust-reverse-proxy ``` +This example is for a reverse proxy running on the same machine as the server. +If the proxy runs on another machine, bind an address reachable by that proxy, +for example `--listen 192.168.1.75:17373`, and point the proxy upstream to that +address and port. The link from proxy to server is still plain HTTP on the LAN; +only the public access is HTTPS. + +For any non-loopback bind, keep the full remote HTTPS configuration: +`--allow-remote`, `--public-origin https://...`, and `--trust-reverse-proxy`. +`ServerConfig::validate()` rejects a non-loopback bind without it. +That check covers the configuration, not reality: it cannot verify that a proxy +is actually terminating HTTPS in front of the server. Do not expose the backend +on a public non-loopback address without TLS proxying. + The proxy must forward the same origin for the SPA, `/api/*`, and `/api/ws`. -Do not expose the backend on a public non-loopback address without TLS proxying. +`--public-origin` is matched by strict equality against the request `Origin`: +open the UI through the configured domain, not through the server IP, otherwise +API calls are rejected with 403. + +With a LAN bind, also check the host firewall. If the server is reachable from +the local machine but times out from every other host, open the port for the LAN +subnet or, preferably, only for the proxy IP. Avoid opening it broadly: the +server does not provide its own TLS. Secrets must never be placed in URLs; pairing uses `POST /api/pair` and then an `HttpOnly`, `Secure`, `SameSite=Strict` session cookie. -