fix(tee)!: restrict the operator-only node ports to the operator's IP - #84
Merged
Conversation
Only :22 was source-restricted; every other rule in the node NSG got source `*`, tdx-init's :8080 config listener included. That listener is unauthenticated and first-POST-wins, so whoever reached it ahead of the operator enrolled the box into *their* network — their manifest, their measurement policy, their bootnode list, so their root_key. Its "close after first deploy" comment was never achievable either: the conf dir is tmpfs, so the listener comes back for a fresh POST on every boot. OPEN_PORTS now carries a per-port source column instead of special-casing the ssh rule by name. :22 and :8080 are operator-only; the peer-facing ports (:80/:443, the enclave's :7878 root_key fetch, summit consensus, reth devp2p) keep source `*` deliberately — admission there is app-layer pubkey authentication, and an IP allowlist would break nodes that join later. :7879 is reserved and restricted ahead of the service that will use it: a summit key holder serving the node's summit pubkeys plus a TDX quote over them to whoever is assembling a founding validator set. Its restriction is permanent rather than founding-window-only, since the holder mints fresh RAM keys and reopens the quote window on every boot until the keystore exists. `source_ip_cidr` becomes `operator_ip_cidr`: the old name described the Azure field the value lands in, while the reader choosing it needs to know whose address it is — and it now gates three ports, not just ssh. The playground project keeps `source_ip_cidr`, where it means SSH access to a dev box and feeds `ssh_source_cidrs` directly. tee/README.md's footgun entry claimed the :8080 restriction already existed; it now points at where the restriction lives and says plainly that the stack setting is the whole guard. The dev stack still ships 0.0.0.0/0, which opts out of it — both comments now say so. BREAKING: the `source_ip_cidr` stack config key is now `operator_ip_cidr`. Existing seismic_node stacks fail on the next `pulumi up` with a missing-required-variable error until `pulumi config set operator_ip_cidr <cidr>` is run.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Only :22 was source-restricted; every other rule in the node NSG got source
*, tdx-init's :8080 config listener included. That listener is unauthenticated and first-POST-wins, so whoever reached it ahead of the operator enrolled the box into their network — their manifest, their measurement policy, their bootnode list, so their root_key. Its "close after first deploy" comment was never achievable either: the conf dir is tmpfs, so the listener comes back for a fresh POST on every boot.OPEN_PORTS now carries a per-port source column instead of special-casing the ssh rule by name. :22 and :8080 are operator-only; the peer-facing ports (:80/:443, the enclave's :7878 root_key fetch, summit consensus, reth devp2p) keep source
*deliberately — admission there is app-layer pubkey authentication, and an IP allowlist would break nodes that join later.:7879 is reserved and restricted ahead of the service that will use it: a summit key holder serving the node's summit pubkeys plus a TDX quote over them to whoever is assembling a founding validator set. Its restriction is permanent rather than founding-window-only, since the holder mints fresh RAM keys and reopens the quote window on every boot until the keystore exists.
source_ip_cidrbecomesoperator_ip_cidr: the old name described the Azure field the value lands in, while the reader choosing it needs to know whose address it is — and it now gates three ports, not just ssh. The playground project keepssource_ip_cidr, where it means SSH access to a dev box and feedsssh_source_cidrsdirectly.tee/README.md's footgun entry claimed the :8080 restriction already existed; it now points at where the restriction lives and says plainly that the stack setting is the whole guard. The dev stack still ships 0.0.0.0/0, which opts out of it — both comments now say so.
BREAKING: the
source_ip_cidrstack config key is nowoperator_ip_cidr. Existing seismic_node stacks fail on the nextpulumi upwith a missing-required-variable error untilpulumi config set operator_ip_cidr <cidr>is run.