You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Rewritten. This issue originally proposed SSM Session Manager, on the premise that no CIDR could be allowlisted. Both the premise and the recommendation have since changed; the body below states the current position, including how the premise fell over — worth reading before acting. The identifiers this issue used to carry were replaced with prose ahead of the repository going public, and its comment history was removed in the same pass (#101), so this body is now the authoritative record.
Is your feature request related to a problem?
Inbound 22/tcp is permitted from 0.0.0.0/0 in a security group shared by both deploy hosts. Removing that was the stated payoff of #84 — the build/ship split exists so the ship job can reach the host on its private address over the VPN rather than over the internet.
Two things have since changed the shape of this.
Internet-facing SSH is already closed. Each host has two network interfaces: a public-facing one carrying the HTTPS address and a private one the deploy reaches over the VPN. Security groups attach per-interface, so the public one now carries a group permitting 80/443 only. Verified from outside the VPN — 22 times out where it previously reached sshd, with an HTTPS 200 on the same host as the control that proves the host is up and the difference is the port. The rule itself is untouched and still applies to the private interfaces.
The "no stable CIDR" argument does not hold. It rested on one observed public source address, which turned out to be an artifact: staging's DEPLOY_HOST named the public FQDN, so its deploys left over the internet rather than the VPN and presented a public source. Repointed to the private address, staging presents a private one, as production always did. Both VPN-path deploys observed so far land in the same private /24.
Describe the solution you'd like
Delete the 22-from-0.0.0.0/0 rule and rely on the private range instead, which both hosts already permit.
Not yet, and not blindly:
Accumulate readings first. Only two VPN-path observations exist, both from the same runner group and the same /24. Calico source-NATs each pod to whichever worker node it landed on, node addresses are provisioned dynamically rather than declared, and the two clusters are separate sites with separate ranges — so a reading from the other cluster is the one that matters. This is why the Calico reasoning is retained: not as proof that narrowing is impossible, but as the reason to verify rather than assume. The Report source address as seen by the host step from Report the ship runner's source address, and fix the dual-stack guidance #90 makes this decidable and should stay permanently.
Add our own rule rather than depending on the existing one. The rules currently permitting 22 from the private range belong to another team and can change without reference to this deployment.
The group is shared between both hosts, so editing it affects staging and production simultaneously. That is how the earlier attempt broke staging while a production release was in flight. Change it deliberately, not during a release.
Alternatives considered
SSM Session Manager — declined. Needs no inbound port at all and records each session in CloudTrail, and ssh keeps working over it via a ProxyCommand so deploy.sh would need no changes; only the workflow's SSH setup. It is the stronger end state. Declined as over-engineering for the residual risk once internet-facing SSH was closed: the remaining exposure is to the VPN and on-prem estate, which is accepted. The work it would need — IAM instance profile, GitHub OIDC role, session-manager-plugin, DEPLOY_HOST changing form — is recorded here in case that judgement changes.
A job that opens a short-lived rule for its own address. Circular: the runner cannot discover which address to open, since its public egress is not the address the host sees on the VPN path. It also leaves a rule behind if the job dies, and races concurrent deploys.
A bastion. Inherits the same problem — it needs inbound SSH from the same sources.
Leave the rule as it is. Now much more defensible than when this was filed, since the internet path is gone. Still worth closing: a world-facing rule sitting in a shared group is a trap for whoever next attaches that group to something public.
Additional context
The ::/0 half of the rule was removed early on: the IPsec tunnels and BGP sessions to this VPC are IPv4-only, so the deploy never arrived over IPv6 and that half permitted nothing but internet-sourced attempts. The rules permitting 22 from the private range have no IPv6 entry either, so nothing on the v6 side depended on it. Not empirically retested from outside since — worth confirming rather than assuming.
One loose end: the deploy interface on staging still has an unused public address associated. It is inbound-dead because that subnet's default route goes to a NAT gateway, but repairing that routing or moving the interface would silently restore an internet path to SSH. Worth disassociating.
Rewritten. This issue originally proposed SSM Session Manager, on the premise that no CIDR could be allowlisted. Both the premise and the recommendation have since changed; the body below states the current position, including how the premise fell over — worth reading before acting. The identifiers this issue used to carry were replaced with prose ahead of the repository going public, and its comment history was removed in the same pass (#101), so this body is now the authoritative record.
Is your feature request related to a problem?
Inbound
22/tcpis permitted from0.0.0.0/0in a security group shared by both deploy hosts. Removing that was the stated payoff of #84 — the build/ship split exists so the ship job can reach the host on its private address over the VPN rather than over the internet.Two things have since changed the shape of this.
Internet-facing SSH is already closed. Each host has two network interfaces: a public-facing one carrying the HTTPS address and a private one the deploy reaches over the VPN. Security groups attach per-interface, so the public one now carries a group permitting
80/443only. Verified from outside the VPN —22times out where it previously reachedsshd, with an HTTPS200on the same host as the control that proves the host is up and the difference is the port. The rule itself is untouched and still applies to the private interfaces.The "no stable CIDR" argument does not hold. It rested on one observed public source address, which turned out to be an artifact: staging's
DEPLOY_HOSTnamed the public FQDN, so its deploys left over the internet rather than the VPN and presented a public source. Repointed to the private address, staging presents a private one, as production always did. Both VPN-path deploys observed so far land in the same private/24.Describe the solution you'd like
Delete the
22-from-0.0.0.0/0rule and rely on the private range instead, which both hosts already permit.Not yet, and not blindly:
/24. Calico source-NATs each pod to whichever worker node it landed on, node addresses are provisioned dynamically rather than declared, and the two clusters are separate sites with separate ranges — so a reading from the other cluster is the one that matters. This is why the Calico reasoning is retained: not as proof that narrowing is impossible, but as the reason to verify rather than assume. The Report source address as seen by the host step from Report the ship runner's source address, and fix the dual-stack guidance #90 makes this decidable and should stay permanently.22from the private range belong to another team and can change without reference to this deployment.Alternatives considered
sshkeeps working over it via aProxyCommandsodeploy.shwould need no changes; only the workflow's SSH setup. It is the stronger end state. Declined as over-engineering for the residual risk once internet-facing SSH was closed: the remaining exposure is to the VPN and on-prem estate, which is accepted. The work it would need — IAM instance profile, GitHub OIDC role, session-manager-plugin,DEPLOY_HOSTchanging form — is recorded here in case that judgement changes.Additional context
::/0half of the rule was removed early on: the IPsec tunnels and BGP sessions to this VPC are IPv4-only, so the deploy never arrived over IPv6 and that half permitted nothing but internet-sourced attempts. The rules permitting22from the private range have no IPv6 entry either, so nothing on the v6 side depended on it. Not empirically retested from outside since — worth confirming rather than assuming.deploy/native/README.md's "Narrowing inbound SSH" section is the prose version of this and was brought in line in Rewrite the inbound-SSH section: it described a state that no longer exists #104.