Expose SSO (3001) + proxy mgmt (3000) UIs on the LAN by default

The SSO web UI and the proxy management UI were bound to 127.0.0.1, so they
were only reachable from the host running the stack — inconvenient during
first-run setup from another machine. Make the bind address configurable
(SSO_BIND / MGMT_BIND, default 0.0.0.0) so both are LAN-reachable by default,
with a one-line flip back to 127.0.0.1 once the proxy fronts them under TLS.

Also: friendlier README with an upfront prerequisites section (domain, >=2 DNS
records to the public IP, port-forward 80/443) and a note that .env values with
spaces should be quoted.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-11 20:38:11 -04:00
parent 5ec951a683
commit ca0ddb1997
3 changed files with 28 additions and 15 deletions
+9 -2
View File
@@ -52,8 +52,7 @@ SMTP_PASS=
SMTP_FROM=
# ── Optional: host port overrides ───────────────────────────────────────────
# SSO web UI (mapped to host for first-run convenience; the proxy fronts it in
# normal use, so you can leave it unmapped by setting SSO_PORT=0).
# SSO web UI + proxy mgmt UI host ports.
SSO_PORT=3001
LDAPS_PORT=636
# Proxy listeners:
@@ -62,6 +61,14 @@ HTTPS_PORT=443
HTTPS_ALT_PORT=4443
MGMT_PORT=3000
# ── Optional: bind address for the SSO UI (3001) + proxy mgmt UI (3000) ───────
# Default 0.0.0.0 = reachable on the LAN (convenient for first-run / admin from
# another machine). These UIs are login-protected, but exposing them widens the
# attack surface; once the proxy fronts both under TLS you can lock them to the
# host only by setting each to 127.0.0.1.
SSO_BIND=0.0.0.0
MGMT_BIND=0.0.0.0
# ── Optional: LDAP TLS cert CN (hostname LDAPS clients verify) ───────────────
# Defaults to LDAP_DOMAIN. Set to the hostname the proxy connects via
# (sso-manager inside the docker net uses the service name, which is in the
+11 -6
View File
@@ -158,10 +158,11 @@ Optional: `BOOTSTRAP_ADMIN_EMAIL`, `LDAP_SERVICE_PASS` (auto-generated if blank)
## After setup
- **SSO Manager UI**: `https://<SSO_HOST>` — log in as your bootstrap admin to
add users, groups, and OAuth clients. (First-run fallback:
`http://127.0.0.1:3001`.)
add users, groups, and OAuth clients. (First-run fallback: `http://<host>:3001`,
reachable on the LAN by default.)
- **Proxy mgmt UI**: `https://<PROXY_HOST>` — add the Host records you want to
protect with OIDC. (First-run fallback: `http://127.0.0.1:3000`.)
protect with OIDC. (First-run fallback: `http://<host>:3000`, reachable on the
LAN by default.)
- **Direct LDAP for legacy apps**: bind to `ldaps://<host>:636` as
`cn=admin,<base>` (admin) or `cn=ldapclient,ou=people,<base>` (read-only
service account the bootstrap created). Use LDAPS, not plain LDAP.
@@ -230,9 +231,13 @@ exactly in the bootstrap) so the SSO can verify them on bind.
## Security notes
1. **Only expose 443 (and optionally 4443) to the internet.** The SSO's web port
(`3001`) is bound to localhost — the proxy fronts it. LDAPS (`636`) is the
only LDAP listener that should cross the network.
1. **Only expose 443 (and optionally 4443) to the internet.** The SSO web port
(`3001`) and the proxy mgmt UI (`3000`) default to `0.0.0.0` for first-run
convenience, so they're reachable on your LAN (they're login-protected, but
it widens the attack surface). The proxy fronts both under TLS in normal
use, so set `SSO_BIND=127.0.0.1` and `MGMT_BIND=127.0.0.1` in `.env` to lock
them to the host once you're up and running. LDAPS (`636`) is the only LDAP
listener that should cross the network.
2. **Persist + protect `.env` and `proxy.env`.** They hold `LDAP_ADMIN_PASS`,
`JWT_SECRET`, the LDAP service password, and the OAuth client secret.
`setup.sh` writes `proxy.env` mode `0600`; both are in `.gitignore`.
+8 -7
View File
@@ -23,10 +23,10 @@ services:
restart: unless-stopped
networks: [theta-net]
ports:
# SSO web UI — bind to localhost only (first-run / admin convenience). In
# normal use the proxy fronts it at https://<SSO_HOST>; don't expose 3001
# to the LAN. Set SSO_PORT=0 in .env to still map (random) or firewall it.
- "127.0.0.1:${SSO_PORT:-3001}:3001"
# SSO web UI. Bind address is configurable via SSO_BIND (default 0.0.0.0 so
# the UI is reachable on the LAN during setup). Set SSO_BIND=127.0.0.1 in
# .env to lock it to localhost once the proxy fronts it at https://<SSO_HOST>.
- "${SSO_BIND:-0.0.0.0}:${SSO_PORT:-3001}:3001"
# LDAPS for EXTERNAL direct-LDAP clients (legacy apps). The proxy itself
# reaches LDAPS over theta-net (sso-manager:636) without this host mapping.
- "${LDAPS_PORT:-636}:636"
@@ -75,9 +75,10 @@ services:
- "${HTTP_PORT:-80}:80"
- "${HTTPS_PORT:-443}:443"
- "${HTTPS_ALT_PORT:-4443}:4443"
# Management UI/API — localhost only (the front proxies it under TLS in
# normal use; exposed on localhost for first-run setup / healthcheck).
- "127.0.0.1:${MGMT_PORT:-3000}:3000"
# Management UI/API. Bind address is configurable via MGMT_BIND (default
# 0.0.0.0 so it's reachable on the LAN during setup). Set MGMT_BIND=127.0.0.1
# in .env to lock it to localhost once the proxy fronts it under TLS.
- "${MGMT_BIND:-0.0.0.0}:${MGMT_PORT:-3000}:3000"
# Written by setup.sh from .env + the bootstrap output (OAuth client creds).
# setup.sh creates it before starting the proxy, so it always exists.
env_file: