-
Notifications
You must be signed in to change notification settings - Fork 0
docs(security): harden remote-hub guidance to avoid Tailscale header spoofing #409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: Dev
Are you sure you want to change the base?
Changes from all commits
d35592b
71c57ea
d560ac6
08ada6f
ec51e42
e25b653
80fff9a
fc4de77
c7d8407
54e2274
2c4dca1
a34e8b7
ebb4d55
682112e
af6113a
847f4f1
ac78647
aaa9eaf
35ff3a4
bae0674
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -77,7 +77,7 @@ ocx config set hostname 100.64.0.10 | |
| ocx config set hub.managementPublicOrigin '"https://hub-name.tailnet-name.ts.net"' | ||
| ocx config set corsAllowOrigins '["http://localhost:10100"]' | ||
| ocx config set hub.managementIngress '{"enabled":true,"port":10101}' | ||
| ocx config set remoteGui.allowedTailscaleUsers '["operator@example.com"]' | ||
| ocx config set remoteGui.allowedTailscaleUsers '[]' | ||
|
|
||
| # Generate/read this in a protected operator shell or secret manager. | ||
| # It is a data-admission token, not a provider credential. | ||
|
|
@@ -115,7 +115,14 @@ tailscale serve status | |
|
|
||
| Set `hub.managementPublicOrigin` to the exact HTTPS origin shown by Serve. Add the operator's exact | ||
| Tailscale login to `remoteGui.allowedTailscaleUsers`; an empty list means no remote identity can mint | ||
| a session. Verify both directions: | ||
| a session. Enable that allowlist only when Tailscale Serve is the process forwarding to the | ||
| management ingress: | ||
|
|
||
| ```bash | ||
| ocx config set remoteGui.allowedTailscaleUsers '["operator@example.com"]' | ||
| ``` | ||
|
|
||
| Verify both directions: | ||
|
|
||
| ```bash | ||
| # Negative: the loopback-only port must not be reachable through the node's tailnet address. | ||
|
|
@@ -138,8 +145,10 @@ tailscale cert hub-name.tailnet-name.ts.net | |
| ``` | ||
|
|
||
| Protect the private key, renew it through Tailscale's supported mechanism, and proxy only to | ||
| `127.0.0.1:10101`. A generic TLS proxy does not supply trustworthy Tailscale identity. Do not | ||
| fabricate `Tailscale-User-*` headers; use the single-use, origin-bound pairing flow instead. | ||
| `127.0.0.1:10101`. A generic TLS proxy does not supply trustworthy Tailscale identity. Keep | ||
| `remoteGui.allowedTailscaleUsers` empty, and configure the proxy to remove or reject every incoming | ||
| `Tailscale-User-*` header before forwarding. Preserving client-supplied identity headers is unsafe; | ||
| do not merely avoid adding new ones. Use the single-use, origin-bound pairing flow instead. | ||
|
Comment on lines
+148
to
+151
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The French, Japanese, Korean, Russian, Turkish, Simplified Chinese, and Traditional Chinese AGENTS.md reference: docs-site/AGENTS.md:L7-L10 Useful? React with 👍 / 👎. |
||
|
|
||
| ## Headless OAuth | ||
|
|
||
|
|
@@ -231,14 +240,16 @@ docker compose run --rm hub bun run src/cli/index.ts config set runtimeRole hub | |
| docker compose run --rm hub bun run src/cli/index.ts config set hostname 0.0.0.0 | ||
| docker compose run --rm hub bun run src/cli/index.ts config set hub.managementPublicOrigin '"https://hub-name.tailnet-name.ts.net"' | ||
| docker compose run --rm hub bun run src/cli/index.ts config set hub.managementIngress '{"enabled":true,"port":10101}' | ||
| docker compose run --rm hub bun run src/cli/index.ts config set remoteGui.allowedTailscaleUsers '["operator@example.com"]' | ||
| docker compose run --rm hub bun run src/cli/index.ts config set remoteGui.allowedTailscaleUsers '[]' | ||
| docker compose up -d | ||
| ``` | ||
|
|
||
| Do not put a token in `ARG`, `ENV`, `COPY`, Compose YAML, image history, or the command line. Do not | ||
| mount the Docker socket, host home, Codex home, SSH agent, or provider-key files. Publish only port | ||
| `10100`. A management ingress bound to `127.0.0.1:10101` inside the container is reachable only by a | ||
| TLS/tailnet frontend in the same network namespace; never publish `10101` as a shortcut. | ||
| TLS/tailnet frontend in the same network namespace; never publish `10101` as a shortcut. Keep the | ||
| allowlist empty and use pairing for a generic frontend. If a Tailscale Serve sidecar is the process | ||
| forwarding to `10101`, set the exact operator allowlist only after that topology is in place. | ||
|
|
||
| After the container is healthy, run a separate readiness promotion check: | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the documented systemd/launchd sequence,
ocx service installstarts the hub while this setting is still empty, and this laterocx config setonly persistsconfig.json;startServercaptures the configuration once at startup insrc/server/index.ts:645, with no live reload forremoteGui. Consequently the allowed Tailscale user still cannot mint a session and the positive dashboard step fails until the service is restarted. Addocx service restartafter this command, or establish Serve and set the allowlist before installing the service.Useful? React with 👍 / 👎.